gdb/
[deliverable/binutils-gdb.git] / gdb / stack.c
index 9b7d810d30715b131ef8a45505fc0ac0df409f7e..0f5b42638b584ca8dee8a7a62b59cec9580e982d 100644 (file)
@@ -46,6 +46,7 @@
 #include "gdbthread.h"
 #include "cp-support.h"
 #include "disasm.h"
+#include "inline-frame.h"
 
 #include "gdb_assert.h"
 #include <ctype.h>
@@ -58,7 +59,7 @@ void (*deprecated_selected_frame_level_changed_hook) (int);
 
 static const char *print_frame_arguments_choices[] =
   {"all", "scalars", "none", NULL};
-static const char *print_frame_arguments = "all";
+static const char *print_frame_arguments = "scalars";
 
 /* Prototypes for local functions. */
 
@@ -99,6 +100,30 @@ print_stack_frame_stub (void *args)
   return 0;
 }
 
+/* Return 1 if we should display the address in addition to the location,
+   because we are in the middle of a statement.  */
+
+static int
+frame_show_address (struct frame_info *frame,
+                   struct symtab_and_line sal)
+{
+  /* If there is a line number, but no PC, then there is no location
+     information associated with this sal.  The only way that should
+     happen is for the call sites of inlined functions (SAL comes from
+     find_frame_sal).  Otherwise, we would have some PC range if the
+     SAL came from a line table.  */
+  if (sal.line != 0 && sal.pc == 0 && sal.end == 0)
+    {
+      if (get_next_frame (frame) == NULL)
+       gdb_assert (inline_skipped_frames (inferior_ptid) > 0);
+      else
+       gdb_assert (get_frame_type (get_next_frame (frame)) == INLINE_FRAME);
+      return 0;
+    }
+
+  return get_frame_pc (frame) != sal.pc;
+}
+
 /* Show or print a stack frame FRAME briefly.  The output is format
    according to PRINT_LEVEL and PRINT_WHAT printing the frame's
    relative level, function name, argument list, and file name and
@@ -158,46 +183,6 @@ print_frame_nameless_args (struct frame_info *frame, long start, int num,
     }
 }
 
-/* Return non-zero if the debugger should print the value of the provided
-   symbol parameter (SYM).  */
-
-static int
-print_this_frame_argument_p (struct symbol *sym)
-{
-  struct type *type;
-  
-  /* If the user asked to print no argument at all, then obviously
-     do not print this argument.  */
-
-  if (strcmp (print_frame_arguments, "none") == 0)
-    return 0;
-
-  /* If the user asked to print all arguments, then we should print
-     that one.  */
-
-  if (strcmp (print_frame_arguments, "all") == 0)
-    return 1;
-
-  /* The user asked to print only the scalar arguments, so do not
-     print the non-scalar ones.  */
-
-  type = CHECK_TYPEDEF (SYMBOL_TYPE (sym));
-  while (TYPE_CODE (type) == TYPE_CODE_REF)
-    type = CHECK_TYPEDEF (TYPE_TARGET_TYPE (type));
-  switch (TYPE_CODE (type))
-    {
-      case TYPE_CODE_ARRAY:
-      case TYPE_CODE_STRUCT:
-      case TYPE_CODE_UNION:
-      case TYPE_CODE_SET:
-      case TYPE_CODE_STRING:
-      case TYPE_CODE_BITSTRING:
-        return 0;
-      default:
-        return 1;
-    }
-}
-
 /* Print the arguments of frame FRAME on STREAM, given the function
    FUNC running in that frame (as a symbol), where NUM is the number
    of arguments according to the stack frame (or -1 if the number of
@@ -220,6 +205,10 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
   int args_printed = 0;
   struct cleanup *old_chain, *list_chain;
   struct ui_stream *stb;
+  /* True if we should print arguments, false otherwise.  */
+  int print_args = strcmp (print_frame_arguments, "none");
+  /* True in "summary" mode, false otherwise.  */
+  int summary = !strcmp (print_frame_arguments, "scalars");
 
   stb = ui_out_stream_new (uiout);
   old_chain = make_cleanup_ui_out_stream_delete (stb);
@@ -354,7 +343,7 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
          annotate_arg_name_end ();
          ui_out_text (uiout, "=");
 
-          if (print_this_frame_argument_p (sym))
+          if (print_args)
             {
              /* Avoid value_print because it will deref ref parameters.
                 We just want to print their addresses.  Print ??? for
@@ -381,8 +370,8 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
 
                  get_raw_print_options (&opts);
                  opts.deref_ref = 0;
-                 common_val_print (val, stb->stream, 2,
-                                   &opts, language);
+                 opts.summary = summary;
+                 common_val_print (val, stb->stream, 2, &opts, language);
                  ui_out_field_stream (uiout, "value", stb);
                }
              else
@@ -459,9 +448,9 @@ set_current_sal_from_frame (struct frame_info *frame, int center)
 
 /* If ON, GDB will display disassembly of the next source line when
    execution of the program being debugged stops.
-   If AUTO (which is the default) or the next source line cannot be
-   ascertained, display disassembly of the next instruction
-   instead.  */
+   If AUTO (which is the default), or there's no line info to determine
+   the source line of the next instruction, display disassembly of next
+   instruction instead.  */
 
 static enum auto_boolean disassemble_next_line;
 
@@ -507,6 +496,10 @@ do_gdb_disassembly (int how_many, CORE_ADDR low, CORE_ADDR high)
     {
       gdb_disassembly_stub (&args);
     }
+  /* If an exception was thrown while doing the disassembly, print
+     the error message, to give the user a clue of what happened.  */
+  if (exception.reason == RETURN_ERROR)
+    exception_print (gdb_stderr, exception);
 }
 
 /* Print information about frame FRAME.  The output is format according
@@ -597,7 +590,7 @@ print_frame_info (struct frame_info *frame, int print_level,
     {
       int done = 0;
       int mid_statement = ((print_what == SRC_LINE)
-                          && (get_frame_pc (frame) != sal.pc));
+                          && frame_show_address (frame, sal));
 
       if (annotation_level)
        done = identify_source_line (sal.symtab, sal.line, mid_statement,
@@ -644,22 +637,18 @@ print_frame_info (struct frame_info *frame, int print_level,
   gdb_flush (gdb_stdout);
 }
 
-static void
-print_frame (struct frame_info *frame, int print_level,
-            enum print_what print_what, int print_args,
-            struct symtab_and_line sal)
+/* Attempt to obtain the FUNNAME and FUNLANG of the function corresponding
+   to FRAME.  */
+void
+find_frame_funname (struct frame_info *frame, char **funname,
+                   enum language *funlang)
 {
   struct symbol *func;
-  char *funname = NULL;
-  enum language funlang = language_unknown;
-  struct ui_stream *stb;
-  struct cleanup *old_chain, *list_chain;
-  struct value_print_options opts;
 
-  stb = ui_out_stream_new (uiout);
-  old_chain = make_cleanup_ui_out_stream_delete (stb);
+  *funname = NULL;
+  *funlang = language_unknown;
 
-  func = find_pc_function (get_frame_address_in_block (frame));
+  func = get_frame_function (frame);
   if (func)
     {
       /* In certain pathological cases, the symtabs give the wrong
@@ -680,8 +669,13 @@ print_frame (struct frame_info *frame, int print_level,
          changed (and we'll create a find_pc_minimal_function or some
          such).  */
 
-      struct minimal_symbol *msymbol =
-       lookup_minimal_symbol_by_pc (get_frame_address_in_block (frame));
+      struct minimal_symbol *msymbol = NULL;
+
+      /* Don't attempt to do this for inlined functions, which do not
+        have a corresponding minimal symbol.  */
+      if (!block_inlined_p (SYMBOL_BLOCK_VALUE (func)))
+       msymbol
+         = lookup_minimal_symbol_by_pc (get_frame_address_in_block (frame));
 
       if (msymbol != NULL
          && (SYMBOL_VALUE_ADDRESS (msymbol)
@@ -690,24 +684,24 @@ print_frame (struct frame_info *frame, int print_level,
          /* We also don't know anything about the function besides
             its address and name.  */
          func = 0;
-         funname = SYMBOL_PRINT_NAME (msymbol);
-         funlang = SYMBOL_LANGUAGE (msymbol);
+         *funname = SYMBOL_PRINT_NAME (msymbol);
+         *funlang = SYMBOL_LANGUAGE (msymbol);
        }
       else
        {
-         funname = SYMBOL_PRINT_NAME (func);
-         funlang = SYMBOL_LANGUAGE (func);
-         if (funlang == language_cplus)
+         *funname = SYMBOL_PRINT_NAME (func);
+         *funlang = SYMBOL_LANGUAGE (func);
+         if (*funlang == language_cplus)
            {
              /* It seems appropriate to use SYMBOL_PRINT_NAME() here,
                 to display the demangled name that we already have
                 stored in the symbol table, but we stored a version
                 with DMGL_PARAMS turned on, and here we don't want to
                 display parameters.  So remove the parameters.  */
-             char *func_only = cp_remove_params (funname);
+             char *func_only = cp_remove_params (*funname);
              if (func_only)
                {
-                 funname = func_only;
+                 *funname = func_only;
                  make_cleanup (xfree, func_only);
                }
            }
@@ -720,10 +714,27 @@ print_frame (struct frame_info *frame, int print_level,
 
       if (msymbol != NULL)
        {
-         funname = SYMBOL_PRINT_NAME (msymbol);
-         funlang = SYMBOL_LANGUAGE (msymbol);
+         *funname = SYMBOL_PRINT_NAME (msymbol);
+         *funlang = SYMBOL_LANGUAGE (msymbol);
        }
     }
+}
+
+static void
+print_frame (struct frame_info *frame, int print_level,
+            enum print_what print_what, int print_args,
+            struct symtab_and_line sal)
+{
+  char *funname = NULL;
+  enum language funlang = language_unknown;
+  struct ui_stream *stb;
+  struct cleanup *old_chain, *list_chain;
+  struct value_print_options opts;
+
+  stb = ui_out_stream_new (uiout);
+  old_chain = make_cleanup_ui_out_stream_delete (stb);
+
+  find_frame_funname (frame, &funname, &funlang);
 
   annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
                        get_frame_pc (frame));
@@ -738,7 +749,7 @@ print_frame (struct frame_info *frame, int print_level,
     }
   get_user_print_options (&opts);
   if (opts.addressprint)
-    if (get_frame_pc (frame) != sal.pc || !sal.symtab
+    if (frame_show_address (frame, sal) || !sal.symtab
        || print_what == LOC_AND_ADDRESS)
       {
        annotate_frame_address ();
@@ -759,7 +770,7 @@ print_frame (struct frame_info *frame, int print_level,
       struct print_args_args args;
       struct cleanup *args_list_chain;
       args.frame = frame;
-      args.func = func;
+      args.func = find_pc_function (get_frame_address_in_block (frame));
       args.stream = gdb_stdout;
       args_list_chain = make_cleanup_ui_out_list_begin_end (uiout, "args");
       catch_errors (print_args_stub, &args, "", RETURN_MASK_ERROR);
@@ -918,8 +929,16 @@ parse_frame_specification_1 (const char *frame_exp, const char *message,
        {
          if (frame_id_eq (id, get_frame_id (fid)))
            {
-             while (frame_id_eq (id, frame_unwind_id (fid)))
-               fid = get_prev_frame (fid);
+             struct frame_info *prev_frame;
+
+             while (1)
+               {
+                 prev_frame = get_prev_frame (fid);
+                 if (!prev_frame
+                     || !frame_id_eq (id, get_frame_id (prev_frame)))
+                   break;
+                 fid = prev_frame;
+               }
              return fid;
            }
        }
@@ -1041,7 +1060,7 @@ frame_info (char *addr_exp, int from_tty)
   puts_filtered ("; ");
   wrap_here ("    ");
   printf_filtered ("saved %s ", pc_regname);
-  fputs_filtered (paddress (frame_pc_unwind (fi)), gdb_stdout);
+  fputs_filtered (paddress (frame_unwind_caller_pc (fi)), gdb_stdout);
   printf_filtered ("\n");
 
   if (calling_frame_info == NULL)
@@ -1053,8 +1072,10 @@ frame_info (char *addr_exp, int from_tty)
        printf_filtered (_(" Outermost frame: %s\n"),
                         frame_stop_reason_string (reason));
     }
-
-  if (calling_frame_info)
+  else if (get_frame_type (fi) == INLINE_FRAME)
+    printf_filtered (" inlined into frame %d",
+                    frame_relative_level (get_prev_frame (fi)));
+  else
     {
       printf_filtered (" called by frame at ");
       fputs_filtered (paddress (get_frame_base (calling_frame_info)),
@@ -1514,7 +1535,9 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs,
       if (print_block_frame_locals (block, frame, num_tabs, stream))
        values_printed = 1;
       /* After handling the function's top-level block, stop.  Don't
-         continue to its superblock, the block of per-file symbols.  */
+         continue to its superblock, the block of per-file symbols.
+         Also do not continue to the containing function of an inlined
+         function.  */
       if (BLOCK_FUNCTION (block))
        break;
       block = BLOCK_SUPERBLOCK (block);
@@ -1585,7 +1608,9 @@ print_frame_label_vars (struct frame_info *frame, int this_level_only,
        return;
 
       /* After handling the function's top-level block, stop.  Don't
-         continue to its superblock, the block of per-file symbols.  */
+         continue to its superblock, the block of per-file symbols.
+         Also do not continue to the containing function of an inlined
+         function.  */
       if (BLOCK_FUNCTION (block))
        break;
       block = BLOCK_SUPERBLOCK (block);
@@ -1694,13 +1719,7 @@ select_and_print_frame (struct frame_info *frame)
 struct block *
 get_selected_block (CORE_ADDR *addr_in_block)
 {
-  if (!target_has_stack)
-    return 0;
-
-  if (is_exited (inferior_ptid))
-    return 0;
-
-  if (is_executing (inferior_ptid))
+  if (!has_stack_frames ())
     return 0;
 
   return get_frame_block (get_selected_frame (NULL), addr_in_block);
@@ -1848,12 +1867,17 @@ void
 return_command (char *retval_exp, int from_tty)
 {
   struct frame_info *thisframe;
+  struct gdbarch *gdbarch;
   struct symbol *thisfun;
   struct value *return_value = NULL;
   const char *query_prefix = "";
 
   thisframe = get_selected_frame ("No selected frame.");
   thisfun = get_frame_function (thisframe);
+  gdbarch = get_frame_arch (thisframe);
+
+  if (get_frame_type (get_current_frame ()) == INLINE_FRAME)
+    error (_("Can not force return from an inlined function."));
 
   /* Compute the return value.  If the computation triggers an error,
      let it bail.  If the return type can't be handled, set
@@ -1898,7 +1922,8 @@ return_command (char *retval_exp, int from_tty)
            occur.  */
        return_value = NULL;
       else if (thisfun != NULL
-              && using_struct_return (SYMBOL_TYPE (thisfun), return_type))
+              && using_struct_return (gdbarch,
+                                      SYMBOL_TYPE (thisfun), return_type))
        {
          query_prefix = "\
 The location at which to store the function's return value is unknown.\n\
@@ -2138,17 +2163,21 @@ Usage: func <name>\n"));
 
   add_setshow_auto_boolean_cmd ("disassemble-next-line", class_stack,
                                &disassemble_next_line, _("\
-Set whether to disassemble next source line when execution stops."), _("\
-Show whether to disassemble next source line when execution stops."), _("\
-If ON, GDB will display disassembly of the next source line when\n\
-execution of the program being debugged stops.\n\
-If AUTO (which is the default) or the next source line cannot be\n\
-ascertained, display disassembly of the next instruction\n\
-instead."),
+Set whether to disassemble next source line or insn when execution stops."), _("\
+Show whether to disassemble next source line or insn when execution stops."), _("\
+If ON, GDB will display disassembly of the next source line, in addition\n\
+to displaying the source line itself.  If the next source line cannot\n\
+be displayed (e.g., source is unavailable or there's no line info), GDB\n\
+will display disassembly of next instruction instead of showing the\n\
+source line.\n\
+If AUTO, display disassembly of next instruction only if the source line\n\
+cannot be displayed.\n\
+If OFF (which is the default), never display the disassembly of the next\n\
+source line."),
                                NULL,
                                show_disassemble_next_line,
                                &setlist, &showlist);
-  disassemble_next_line = AUTO_BOOLEAN_AUTO;
+  disassemble_next_line = AUTO_BOOLEAN_FALSE;
 
 #if 0
   add_cmd ("backtrace-limit", class_stack, set_backtrace_limit_command, _(\
This page took 0.036487 seconds and 4 git commands to generate.