gdb/
[deliverable/binutils-gdb.git] / gdb / stack.c
index 1c37801f2ea44b1014c8f8b36154f18bc3771f57..6e59cd0a055a0ac178f4d23d2dc7f1d130d917dd 100644 (file)
@@ -2,7 +2,7 @@
 
    Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
    1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008,
-   2009 Free Software Foundation, Inc.
+   2009, 2010, 2011 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -52,6 +52,9 @@
 #include <ctype.h>
 #include "gdb_string.h"
 
+#include "psymtab.h"
+#include "symfile.h"
+
 void (*deprecated_selected_frame_level_changed_hook) (int);
 
 /* The possible choices of "set print frame-arguments, and the value
@@ -61,7 +64,7 @@ static const char *print_frame_arguments_choices[] =
   {"all", "scalars", "none", NULL};
 static const char *print_frame_arguments = "scalars";
 
-/* Prototypes for local functions. */
+/* Prototypes for local functions.  */
 
 static void print_frame_local_vars (struct frame_info *, int,
                                    struct ui_file *);
@@ -284,6 +287,7 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
          if (*SYMBOL_LINKAGE_NAME (sym))
            {
              struct symbol *nsym;
+
              nsym = lookup_symbol (SYMBOL_LINKAGE_NAME (sym),
                                    b, VAR_DOMAIN, NULL);
              gdb_assert (nsym != NULL);
@@ -462,8 +466,9 @@ show_disassemble_next_line (struct ui_file *file, int from_tty,
                                 struct cmd_list_element *c,
                                 const char *value)
 {
-  fprintf_filtered (file, _("\
-Debugger's willingness to use disassemble-next-line is %s.\n"),
+  fprintf_filtered (file,
+                   _("Debugger's willingness to use "
+                     "disassemble-next-line is %s.\n"),
                     value);
 }
 
@@ -481,6 +486,7 @@ static void
 gdb_disassembly_stub (void *args)
 {
   struct gdb_disassembly_stub_args *p = args;
+
   gdb_disassembly (p->gdbarch, uiout, 0,
                    DISASSEMBLY_RAW_INSN, p->how_many,
                    p->low, p->high);
@@ -620,14 +626,15 @@ print_frame_info (struct frame_info *frame, int print_level,
          else
            {
              struct value_print_options opts;
+
              get_user_print_options (&opts);
              /* We used to do this earlier, but that is clearly
-                wrong. This function is used by many different
+                wrong.  This function is used by many different
                 parts of gdb, including normal_stop in infrun.c,
                 which uses this to print out the current PC
                 when we stepi/nexti into the middle of a source
-                line. Only the command line really wants this
-                behavior. Other UIs probably would like the
+                line.  Only the command line really wants this
+                behavior.  Other UIs probably would like the
                 ability to decide for themselves if it is desired.  */
              if (opts.addressprint && mid_statement)
                {
@@ -643,28 +650,31 @@ print_frame_info (struct frame_info *frame, int print_level,
       /* If disassemble-next-line is set to on and there is line debug
          messages, output assembly codes for next line.  */
       if (disassemble_next_line == AUTO_BOOLEAN_TRUE)
-       do_gdb_disassembly (get_frame_arch (frame), -1,
-                           get_frame_pc (frame), sal.end);
+       do_gdb_disassembly (get_frame_arch (frame), -1, sal.pc, sal.end);
     }
 
   if (print_what != LOCATION)
-    set_default_breakpoint (1, get_frame_pc (frame), sal.symtab, sal.line);
+    set_default_breakpoint (1, sal.pspace,
+                           get_frame_pc (frame), sal.symtab, sal.line);
 
   annotate_frame_end ();
 
   gdb_flush (gdb_stdout);
 }
 
-/* Attempt to obtain the FUNNAME and FUNLANG of the function corresponding
-   to FRAME.  */
+/* Attempt to obtain the FUNNAME, FUNLANG and optionally FUNCP of the function
+   corresponding to FRAME.  */
+
 void
 find_frame_funname (struct frame_info *frame, char **funname,
-                   enum language *funlang)
+                   enum language *funlang, struct symbol **funcp)
 {
   struct symbol *func;
 
   *funname = NULL;
   *funlang = language_unknown;
+  if (funcp)
+    *funcp = NULL;
 
   func = get_frame_function (frame);
   if (func)
@@ -709,6 +719,8 @@ find_frame_funname (struct frame_info *frame, char **funname,
        {
          *funname = SYMBOL_PRINT_NAME (func);
          *funlang = SYMBOL_LANGUAGE (func);
+         if (funcp)
+           *funcp = func;
          if (*funlang == language_cplus)
            {
              /* It seems appropriate to use SYMBOL_PRINT_NAME() here,
@@ -717,6 +729,7 @@ find_frame_funname (struct frame_info *frame, char **funname,
                 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);
+
              if (func_only)
                {
                  *funname = func_only;
@@ -749,11 +762,12 @@ print_frame (struct frame_info *frame, int print_level,
   struct ui_stream *stb;
   struct cleanup *old_chain, *list_chain;
   struct value_print_options opts;
+  struct symbol *func;
 
   stb = ui_out_stream_new (uiout);
   old_chain = make_cleanup_ui_out_stream_delete (stb);
 
-  find_frame_funname (frame, &funname, &funlang);
+  find_frame_funname (frame, &funname, &funlang, &func);
 
   annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
                        gdbarch, get_frame_pc (frame));
@@ -788,12 +802,13 @@ print_frame (struct frame_info *frame, int print_level,
     {
       struct print_args_args args;
       struct cleanup *args_list_chain;
+
       args.frame = frame;
-      args.func = find_pc_function (get_frame_address_in_block (frame));
+      args.func = func;
       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);
-      /* FIXME: ARGS must be a list. If one argument is a string it
+      /* FIXME: ARGS must be a list.  If one argument is a string it
          will have " that will not be properly escaped.  */
       /* Invoke ui_out_tuple_end.  */
       do_cleanups (args_list_chain);
@@ -810,6 +825,7 @@ print_frame (struct frame_info *frame, int print_level,
       if (ui_out_is_mi_like_p (uiout))
        {
          const char *fullname = symtab_to_fullname (sal.symtab);
+
          if (fullname != NULL)
            ui_out_field_string (uiout, "fullname", fullname);
        }
@@ -825,7 +841,8 @@ print_frame (struct frame_info *frame, int print_level,
 #ifdef PC_SOLIB
       char *lib = PC_SOLIB (get_frame_pc (frame));
 #else
-      char *lib = solib_name_from_address (get_frame_pc (frame));
+      char *lib = solib_name_from_address (get_frame_program_space (frame),
+                                          get_frame_pc (frame));
 #endif
       if (lib)
        {
@@ -861,9 +878,6 @@ parse_frame_specification_1 (const char *frame_exp, const char *message,
     numargs = 0;
   else
     {
-      char *addr_string;
-      struct cleanup *tmp_cleanup;
-
       numargs = 0;
       while (1)
        {
@@ -917,15 +931,17 @@ parse_frame_specification_1 (const char *frame_exp, const char *message,
     {
       struct frame_info *fid;
       int level = value_as_long (args[0]);
+
       fid = find_relative_frame (get_current_frame (), &level);
       if (level == 0)
-       /* find_relative_frame was successful */
+       /* find_relative_frame was successful */
        return fid;
     }
 
   /* Convert each value into a corresponding address.  */
   {
     int i;
+
     for (i = 0; i < numargs; i++)
       addrs[i] = value_as_address (args[i]);
   }
@@ -990,7 +1006,7 @@ frame_info (char *addr_exp, int from_tty)
   struct symbol *func;
   struct symtab *s;
   struct frame_info *calling_frame_info;
-  int i, count, numregs;
+  int numregs;
   char *funname = 0;
   enum language funlang = language_unknown;
   const char *pc_regname;
@@ -1032,6 +1048,7 @@ frame_info (char *addr_exp, int from_tty)
             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);
+
          if (func_only)
            {
              funname = func_only;
@@ -1193,6 +1210,7 @@ frame_info (char *addr_exp, int from_tty)
            int sp_size = register_size (gdbarch, gdbarch_sp_regnum (gdbarch));
            gdb_byte value[MAX_REGISTER_SIZE];
            CORE_ADDR sp;
+
            frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
                                   &optimized, &lval, &addr,
                                   &realnum, value);
@@ -1310,8 +1328,6 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
 
   if (info_verbose)
     {
-      struct partial_symtab *ps;
-
       /* Read in symbols for all of the frames.  Need to do this in a
          separate pass so that "Reading in symbols for xxx" messages
          don't screw up the appearance of the backtrace.  Also if
@@ -1320,10 +1336,11 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
       i = count;
       for (fi = trailing; fi != NULL && i--; fi = get_prev_frame (fi))
        {
+         CORE_ADDR pc;
+
          QUIT;
-         ps = find_pc_psymtab (get_frame_address_in_block (fi));
-         if (ps)
-           PSYMTAB_TO_SYMTAB (ps); /* Force syms to come in.  */
+         pc = get_frame_address_in_block (fi);
+         find_pc_sect_symtab_via_partial (pc, find_pc_mapped_section (pc));
        }
     }
 
@@ -1373,6 +1390,7 @@ static int
 backtrace_command_stub (void *data)
 {
   struct backtrace_command_args *args = data;
+
   backtrace_command_1 (args->count_exp, args->show_locals, args->from_tty);
   return 0;
 }
@@ -1444,6 +1462,7 @@ static void
 backtrace_full_command (char *arg, int from_tty)
 {
   struct backtrace_command_args btargs;
+
   btargs.count_exp = arg;
   btargs.show_locals = 1;
   btargs.from_tty = from_tty;
@@ -1451,17 +1470,16 @@ backtrace_full_command (char *arg, int from_tty)
 }
 \f
 
-/* Print the local variables of a block B active in FRAME on STREAM.
-   Return 1 if any variables were printed; 0 otherwise.  */
+/* Iterate over the local variables of a block B, calling CB with
+   CB_DATA.  */
 
-static int
-print_block_frame_locals (struct block *b, struct frame_info *frame,
-                         int num_tabs, struct ui_file *stream)
+static void
+iterate_over_block_locals (struct block *b,
+                          iterate_over_block_arg_local_vars_cb cb,
+                          void *cb_data)
 {
   struct dict_iterator iter;
   struct symbol *sym;
-  int values_printed = 0;
-  int j;
 
   ALL_BLOCK_SYMBOLS (b, iter, sym)
     {
@@ -1473,8 +1491,7 @@ print_block_frame_locals (struct block *b, struct frame_info *frame,
        case LOC_COMPUTED:
          if (SYMBOL_IS_ARGUMENT (sym))
            break;
-         values_printed = 1;
-         print_variable_and_value (NULL, sym, frame, stream, 4 * num_tabs);
+         (*cb) (SYMBOL_PRINT_NAME (sym), sym, cb_data);
          break;
 
        default:
@@ -1482,12 +1499,18 @@ print_block_frame_locals (struct block *b, struct frame_info *frame,
          break;
        }
     }
-
-  return values_printed;
 }
 
+
 /* Same, but print labels.  */
 
+#if 0
+/* Commented out, as the code using this function has also been
+   commented out.  FIXME:brobecker/2009-01-13: Find out why the code
+   was commented out in the first place.  The discussion introducing
+   this change (2007-12-04: Support lexical blocks and function bodies
+   that occupy non-contiguous address ranges) did not explain why
+   this change was made.  */
 static int
 print_block_frame_labels (struct gdbarch *gdbarch, struct block *b,
                          int *have_default, struct ui_file *stream)
@@ -1508,6 +1531,7 @@ print_block_frame_labels (struct gdbarch *gdbarch, struct block *b,
        {
          struct symtab_and_line sal;
          struct value_print_options opts;
+
          sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym), 0);
          values_printed = 1;
          fputs_filtered (SYMBOL_PRINT_NAME (sym), stream);
@@ -1525,40 +1549,77 @@ print_block_frame_labels (struct gdbarch *gdbarch, struct block *b,
 
   return values_printed;
 }
+#endif
 
-/* Print on STREAM all the local variables in frame FRAME, including
-   all the blocks active in that frame at its current PC.
+/* Iterate over all the local variables in block B, including all its
+   superblocks, stopping when the top-level block is reached.  */
+
+void
+iterate_over_block_local_vars (struct block *block,
+                              iterate_over_block_arg_local_vars_cb cb,
+                              void *cb_data)
+{
+  while (block)
+    {
+      iterate_over_block_locals (block, cb, cb_data);
+      /* After handling the function's top-level block, stop.  Don't
+        continue to its superblock, the block of per-file
+        symbols.  */
+      if (BLOCK_FUNCTION (block))
+       break;
+      block = BLOCK_SUPERBLOCK (block);
+    }
+}
 
-   Returns 1 if the job was done, or 0 if nothing was printed because
-   we have no info on the function running in FRAME.  */
+/* Data to be passed around in the calls to the locals and args
+   iterators.  */
+
+struct print_variable_and_value_data
+{
+  struct frame_info *frame;
+  int num_tabs;
+  struct ui_file *stream;
+  int values_printed;
+};
+
+/* The callback for the locals and args iterators.  */
+
+static void
+do_print_variable_and_value (const char *print_name,
+                            struct symbol *sym,
+                            void *cb_data)
+{
+  struct print_variable_and_value_data *p = cb_data;
+
+  print_variable_and_value (print_name, sym,
+                           p->frame, p->stream, p->num_tabs);
+  p->values_printed = 1;
+}
 
 static void
 print_frame_local_vars (struct frame_info *frame, int num_tabs,
                        struct ui_file *stream)
 {
-  struct block *block = get_frame_block (frame, 0);
-  int values_printed = 0;
+  struct print_variable_and_value_data cb_data;
+  struct block *block;
 
+  block = get_frame_block (frame, 0);
   if (block == 0)
     {
       fprintf_filtered (stream, "No symbol table info available.\n");
       return;
     }
 
-  while (block)
-    {
-      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.
-         Also do not continue to the containing function of an inlined
-         function.  */
-      if (BLOCK_FUNCTION (block))
-       break;
-      block = BLOCK_SUPERBLOCK (block);
-    }
+  cb_data.frame = frame;
+  cb_data.num_tabs = 4 * num_tabs;
+  cb_data.stream = stream;
+  cb_data.values_printed = 0;
+
+  iterate_over_block_local_vars (block,
+                                do_print_variable_and_value,
+                                &cb_data);
 
-  if (!values_printed)
+  if (!cb_data.values_printed)
     fprintf_filtered (stream, _("No locals.\n"));
 }
 
@@ -1648,36 +1709,28 @@ locals_info (char *args, int from_tty)
 static void
 catch_info (char *ignore, int from_tty)
 {
-  struct symtab_and_line *sal;
-
   /* Assume g++ compiled code; old GDB 4.16 behaviour.  */
   print_frame_label_vars (get_selected_frame (_("No frame selected.")),
                           0, gdb_stdout);
 }
 
-static void
-print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
+/* Iterate over all the argument variables in block B.
+
+   Returns 1 if any argument was walked; 0 otherwise.  */
+
+void
+iterate_over_block_arg_vars (struct block *b,
+                            iterate_over_block_arg_local_vars_cb cb,
+                            void *cb_data)
 {
-  struct symbol *func = get_frame_function (frame);
-  struct block *b;
   struct dict_iterator iter;
   struct symbol *sym, *sym2;
-  int values_printed = 0;
 
-  if (func == 0)
-    {
-      fprintf_filtered (stream, _("No symbol table info available.\n"));
-      return;
-    }
-
-  b = SYMBOL_BLOCK_VALUE (func);
   ALL_BLOCK_SYMBOLS (b, iter, sym)
     {
       /* Don't worry about things which aren't arguments.  */
       if (SYMBOL_IS_ARGUMENT (sym))
        {
-         values_printed = 1;
-
          /* We have to look up the symbol because arguments can have
             two entries (one a parameter, one a local) and the one we
             want is the local, which lookup_symbol will find for us.
@@ -1691,12 +1744,33 @@ print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
 
          sym2 = lookup_symbol (SYMBOL_LINKAGE_NAME (sym),
                                b, VAR_DOMAIN, NULL);
-         print_variable_and_value (SYMBOL_PRINT_NAME (sym), sym2,
-                                   frame, stream, 0);
+         (*cb) (SYMBOL_PRINT_NAME (sym), sym2, cb_data);
        }
     }
+}
+
+static void
+print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
+{
+  struct print_variable_and_value_data cb_data;
+  struct symbol *func;
+
+  func = get_frame_function (frame);
+  if (func == NULL)
+    {
+      fprintf_filtered (stream, _("No symbol table info available.\n"));
+      return;
+    }
+
+  cb_data.frame = frame;
+  cb_data.num_tabs = 0;
+  cb_data.stream = gdb_stdout;
+  cb_data.values_printed = 0;
 
-  if (!values_printed)
+  iterate_over_block_arg_vars (SYMBOL_BLOCK_VALUE (func),
+                              do_print_variable_and_value, &cb_data);
+
+  if (!cb_data.values_printed)
     fprintf_filtered (stream, _("No arguments.\n"));
 }
 
@@ -1759,6 +1833,7 @@ find_relative_frame (struct frame_info *frame, int *level_offset_ptr)
   while (*level_offset_ptr > 0)
     {
       struct frame_info *prev = get_prev_frame (frame);
+
       if (!prev)
        break;
       (*level_offset_ptr)--;
@@ -1769,6 +1844,7 @@ find_relative_frame (struct frame_info *frame, int *level_offset_ptr)
   while (*level_offset_ptr < 0)
     {
       struct frame_info *next = get_next_frame (frame);
+
       if (!next)
        break;
       (*level_offset_ptr)++;
@@ -1849,6 +1925,7 @@ down_silently_base (char *count_exp)
 {
   struct frame_info *frame;
   int count = -1;
+
   if (count_exp)
     count = -parse_and_eval_long (count_exp);
 
@@ -1942,9 +2019,10 @@ return_command (char *retval_exp, int from_tty)
               && 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\
-If you continue, the return value that you specified will be ignored.\n";
+         query_prefix = "The location at which to store the "
+           "function's return value is unknown.\n"
+           "If you continue, the return value "
+           "that you specified will be ignored.\n";
          return_value = NULL;
        }
     }
@@ -1955,6 +2033,7 @@ If you continue, the return value that you specified will be ignored.\n";
   if (from_tty)
     {
       int confirmed;
+
       if (thisfun == NULL)
        confirmed = query (_("%sMake selected stack frame return now? "),
                           query_prefix);
@@ -1996,7 +2075,7 @@ If you continue, the return value that you specified will be ignored.\n";
 }
 
 /* Sets the scope to input function name, provided that the function
-   is within the current stack frame */
+   is within the current stack frame */
 
 struct function_bounds
 {
@@ -2087,10 +2166,6 @@ void _initialize_stack (void);
 void
 _initialize_stack (void)
 {
-#if 0
-  backtrace_limit = 30;
-#endif
-
   add_com ("return", class_stack, return_command, _("\
 Make selected stack frame return to its caller.\n\
 Control remains in the debugger, but when you continue\n\
@@ -2114,8 +2189,8 @@ Same as the `down' command, but does not print anything.\n\
 This is useful in command scripts."));
 
   add_com ("frame", class_stack, frame_command, _("\
-Select and print a stack frame.\n\
-With no argument, print the selected stack frame.  (See also \"info frame\").\n\
+Select and print a stack frame.\nWith no argument, \
+print the selected stack frame.  (See also \"info frame\").\n\
 An argument specifies the frame to select.\n\
 It can be a stack frame number or the address of the frame.\n\
 With argument, nothing is printed if input is coming from\n\
@@ -2136,14 +2211,14 @@ It can be a stack frame number or the address of the frame.\n"));
 
   add_com ("backtrace", class_stack, backtrace_command, _("\
 Print backtrace of all stack frames, or innermost COUNT frames.\n\
-With a negative argument, print outermost -COUNT frames.\n\
-Use of the 'full' qualifier also prints the values of the local variables.\n"));
+With a negative argument, print outermost -COUNT frames.\nUse of the \
+'full' qualifier also prints the values of the local variables.\n"));
   add_com_alias ("bt", "backtrace", class_stack, 0);
   if (xdb_commands)
     {
       add_com_alias ("t", "backtrace", class_stack, 0);
       add_com ("T", class_stack, backtrace_full_command, _("\
-Print backtrace of all stack frames, or innermost COUNT frames \n\
+Print backtrace of all stack frames, or innermost COUNT frames\n\
 and the values of the local variables.\n\
 With a negative argument, print outermost -COUNT frames.\n\
 Usage: T <count>\n"));
@@ -2180,8 +2255,10 @@ Usage: func <name>\n"));
 
   add_setshow_auto_boolean_cmd ("disassemble-next-line", class_stack,
                                &disassemble_next_line, _("\
-Set whether to disassemble next source line or insn when execution stops."), _("\
-Show whether to disassemble next source line or insn when execution stops."), _("\
+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\
@@ -2195,12 +2272,4 @@ source line."),
                                show_disassemble_next_line,
                                &setlist, &showlist);
   disassemble_next_line = AUTO_BOOLEAN_FALSE;
-
-#if 0
-  add_cmd ("backtrace-limit", class_stack, set_backtrace_limit_command, _(\
-"Specify maximum number of frames for \"backtrace\" to print by default."),
-          &setlist);
-  add_info ("backtrace-limit", backtrace_limit_info, _("\
-The maximum number of frames for \"backtrace\" to print by default."));
-#endif
 }
This page took 0.032008 seconds and 4 git commands to generate.