gdb/
[platform/upstream/binutils.git] / gdb / stack.c
index 3a4cc7f..53d4aeb 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 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "gdbthread.h"
 #include "cp-support.h"
 #include "disasm.h"
+#include "inline-frame.h"
 
 #include "gdb_assert.h"
 #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
@@ -99,6 +103,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
@@ -139,6 +167,8 @@ static void
 print_frame_nameless_args (struct frame_info *frame, long start, int num,
                           int first, struct ui_file *stream)
 {
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int i;
   CORE_ADDR argsaddr;
   long arg_value;
@@ -149,7 +179,8 @@ print_frame_nameless_args (struct frame_info *frame, long start, int num,
       argsaddr = get_frame_args_address (frame);
       if (!argsaddr)
        return;
-      arg_value = read_memory_integer (argsaddr + start, sizeof (int));
+      arg_value = read_memory_integer (argsaddr + start,
+                                      sizeof (int), byte_order);
       if (!first)
        fprintf_filtered (stream, ", ");
       fprintf_filtered (stream, "%ld", arg_value);
@@ -443,6 +474,7 @@ Debugger's willingness to use disassemble-next-line is %s.\n"),
 
 struct gdb_disassembly_stub_args
 {
+  struct gdbarch *gdbarch;
   int how_many;
   CORE_ADDR low;
   CORE_ADDR high;
@@ -452,18 +484,22 @@ static void
 gdb_disassembly_stub (void *args)
 {
   struct gdb_disassembly_stub_args *p = args;
-  gdb_disassembly (uiout, 0, 0, p->how_many, p->low, p->high);
+  gdb_disassembly (p->gdbarch, uiout, 0,
+                   DISASSEMBLY_RAW_INSN, p->how_many,
+                   p->low, p->high);
 }
 
 /* Use TRY_CATCH to catch the exception from the gdb_disassembly
    because it will be broken by filter sometime.  */
 
 static void
-do_gdb_disassembly (int how_many, CORE_ADDR low, CORE_ADDR high)
+do_gdb_disassembly (struct gdbarch *gdbarch,
+                   int how_many, CORE_ADDR low, CORE_ADDR high)
 {
   volatile struct gdb_exception exception;
   struct gdb_disassembly_stub_args args;
 
+  args.gdbarch = gdbarch;
   args.how_many = how_many;
   args.low = low;
   args.high = high;
@@ -492,18 +528,20 @@ void
 print_frame_info (struct frame_info *frame, int print_level,
                  enum print_what print_what, int print_args)
 {
+  struct gdbarch *gdbarch = get_frame_arch (frame);
   struct symtab_and_line sal;
   int source_print;
   int location_print;
 
   if (get_frame_type (frame) == DUMMY_FRAME
-      || get_frame_type (frame) == SIGTRAMP_FRAME)
+      || get_frame_type (frame) == SIGTRAMP_FRAME
+      || get_frame_type (frame) == ARCH_FRAME)
     {
       struct cleanup *uiout_cleanup
        = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
 
       annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
-                           get_frame_pc (frame));
+                           gdbarch, get_frame_pc (frame));
 
       /* Do this regardless of SOURCE because we don't have any source
          to list for this frame.  */
@@ -516,7 +554,8 @@ print_frame_info (struct frame_info *frame, int print_level,
       if (ui_out_is_mi_like_p (uiout))
         {
           annotate_frame_address ();
-          ui_out_field_core_addr (uiout, "addr", get_frame_pc (frame));
+          ui_out_field_core_addr (uiout, "addr",
+                                 gdbarch, get_frame_pc (frame));
           annotate_frame_address_end ();
         }
 
@@ -530,6 +569,10 @@ print_frame_info (struct frame_info *frame, int print_level,
          annotate_signal_handler_caller ();
           ui_out_field_string (uiout, "func", "<signal handler called>");
         }
+      else if (get_frame_type (frame) == ARCH_FRAME)
+        {
+          ui_out_field_string (uiout, "func", "<cross-architecture call>");
+       }
       ui_out_text (uiout, "\n");
       annotate_frame_end ();
 
@@ -559,13 +602,14 @@ print_frame_info (struct frame_info *frame, int print_level,
   if ((disassemble_next_line == AUTO_BOOLEAN_AUTO
        || disassemble_next_line == AUTO_BOOLEAN_TRUE)
       && source_print && !sal.symtab)
-    do_gdb_disassembly (1, get_frame_pc (frame), get_frame_pc (frame) + 1);
+    do_gdb_disassembly (get_frame_arch (frame), 1,
+                       get_frame_pc (frame), get_frame_pc (frame) + 1);
 
   if (source_print && sal.symtab)
     {
       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,
@@ -590,7 +634,8 @@ print_frame_info (struct frame_info *frame, int print_level,
                 ability to decide for themselves if it is desired.  */
              if (opts.addressprint && mid_statement)
                {
-                 ui_out_field_core_addr (uiout, "addr", get_frame_pc (frame));
+                 ui_out_field_core_addr (uiout, "addr",
+                                         gdbarch, get_frame_pc (frame));
                  ui_out_text (uiout, "\t");
                }
 
@@ -601,11 +646,12 @@ 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 (-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 ();
 
@@ -623,7 +669,7 @@ find_frame_funname (struct frame_info *frame, char **funname,
   *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
@@ -644,8 +690,13 @@ find_frame_funname (struct frame_info *frame, char **funname,
          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)
@@ -695,6 +746,7 @@ print_frame (struct frame_info *frame, int print_level,
             enum print_what print_what, int print_args,
             struct symtab_and_line sal)
 {
+  struct gdbarch *gdbarch = get_frame_arch (frame);
   char *funname = NULL;
   enum language funlang = language_unknown;
   struct ui_stream *stb;
@@ -707,7 +759,7 @@ print_frame (struct frame_info *frame, int print_level,
   find_frame_funname (frame, &funname, &funlang);
 
   annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
-                       get_frame_pc (frame));
+                       gdbarch, get_frame_pc (frame));
 
   list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
 
@@ -719,11 +771,11 @@ 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 ();
-       ui_out_field_core_addr (uiout, "addr", get_frame_pc (frame));
+       ui_out_field_core_addr (uiout, "addr", gdbarch, get_frame_pc (frame));
        annotate_frame_address_end ();
        ui_out_text (uiout, " in ");
       }
@@ -776,7 +828,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)
        {
@@ -899,8 +952,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;
            }
        }
@@ -1004,10 +1065,10 @@ frame_info (char *addr_exp, int from_tty)
     {
       printf_filtered (_("Stack frame at "));
     }
-  fputs_filtered (paddress (get_frame_base (fi)), gdb_stdout);
+  fputs_filtered (paddress (gdbarch, get_frame_base (fi)), gdb_stdout);
   printf_filtered (":\n");
   printf_filtered (" %s = ", pc_regname);
-  fputs_filtered (paddress (get_frame_pc (fi)), gdb_stdout);
+  fputs_filtered (paddress (gdbarch, get_frame_pc (fi)), gdb_stdout);
 
   wrap_here ("   ");
   if (funname)
@@ -1022,7 +1083,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 (gdbarch, frame_unwind_caller_pc (fi)), gdb_stdout);
   printf_filtered ("\n");
 
   if (calling_frame_info == NULL)
@@ -1034,11 +1095,13 @@ 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)),
+      fputs_filtered (paddress (gdbarch, get_frame_base (calling_frame_info)),
                      gdb_stdout);
     }
   if (get_next_frame (fi) && calling_frame_info)
@@ -1047,7 +1110,7 @@ frame_info (char *addr_exp, int from_tty)
   if (get_next_frame (fi))
     {
       printf_filtered (" caller of frame at ");
-      fputs_filtered (paddress (get_frame_base (get_next_frame (fi))),
+      fputs_filtered (paddress (gdbarch, get_frame_base (get_next_frame (fi))),
                      gdb_stdout);
     }
   if (get_next_frame (fi) || calling_frame_info)
@@ -1068,7 +1131,7 @@ frame_info (char *addr_exp, int from_tty)
     else
       {
        printf_filtered (" Arglist at ");
-       fputs_filtered (paddress (arg_list), gdb_stdout);
+       fputs_filtered (paddress (gdbarch, arg_list), gdb_stdout);
        printf_filtered (",");
 
        if (!gdbarch_frame_num_args_p (gdbarch))
@@ -1100,7 +1163,7 @@ frame_info (char *addr_exp, int from_tty)
     else
       {
        printf_filtered (" Locals at ");
-       fputs_filtered (paddress (arg_list), gdb_stdout);
+       fputs_filtered (paddress (gdbarch, arg_list), gdb_stdout);
        printf_filtered (",");
       }
   }
@@ -1130,6 +1193,8 @@ frame_info (char *addr_exp, int from_tty)
                               &realnum, NULL);
        if (!optimized && lval == not_lval)
          {
+           enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+           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),
@@ -1138,18 +1203,16 @@ frame_info (char *addr_exp, int from_tty)
            /* NOTE: cagney/2003-05-22: This is assuming that the
                stack pointer was packed as an unsigned integer.  That
                may or may not be valid.  */
-           sp = extract_unsigned_integer (value,
-                                          register_size (gdbarch,
-                                          gdbarch_sp_regnum (gdbarch)));
+           sp = extract_unsigned_integer (value, sp_size, byte_order);
            printf_filtered (" Previous frame's sp is ");
-           fputs_filtered (paddress (sp), gdb_stdout);
+           fputs_filtered (paddress (gdbarch, sp), gdb_stdout);
            printf_filtered ("\n");
            need_nl = 0;
          }
        else if (!optimized && lval == lval_memory)
          {
            printf_filtered (" Previous frame's sp at ");
-           fputs_filtered (paddress (addr), gdb_stdout);
+           fputs_filtered (paddress (gdbarch, addr), gdb_stdout);
            printf_filtered ("\n");
            need_nl = 0;
          }
@@ -1184,7 +1247,7 @@ frame_info (char *addr_exp, int from_tty)
              wrap_here (" ");
              printf_filtered (" %s at ",
                               gdbarch_register_name (gdbarch, i));
-             fputs_filtered (paddress (addr), gdb_stdout);
+             fputs_filtered (paddress (gdbarch, addr), gdb_stdout);
              count++;
            }
        }
@@ -1216,11 +1279,6 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
      of frames which we should print, or -1 if all of them.  */
   trailing = get_current_frame ();
 
-  /* The target can be in a state where there is no valid frames
-     (e.g., just connected). */
-  if (trailing == NULL)
-    error (_("No stack."));
-
   trailing_level = 0;
   if (count_exp)
     {
@@ -1266,10 +1324,10 @@ 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));
        }
     }
 
@@ -1397,17 +1455,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)
     {
@@ -1419,8 +1476,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:
@@ -1428,15 +1484,21 @@ 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 block *b, int *have_default,
-                         struct ui_file *stream)
+print_block_frame_labels (struct gdbarch *gdbarch, struct block *b,
+                         int *have_default, struct ui_file *stream)
 {
   struct dict_iterator iter;
   struct symbol *sym;
@@ -1461,7 +1523,8 @@ print_block_frame_labels (struct block *b, int *have_default,
          if (opts.addressprint)
            {
              fprintf_filtered (stream, " ");
-             fputs_filtered (paddress (SYMBOL_VALUE_ADDRESS (sym)), stream);
+             fputs_filtered (paddress (gdbarch, SYMBOL_VALUE_ADDRESS (sym)),
+                             stream);
            }
          fprintf_filtered (stream, " in file %s, line %d\n",
                            sal.symtab->filename, sal.line);
@@ -1470,38 +1533,77 @@ print_block_frame_labels (struct block *b, int *have_default,
 
   return values_printed;
 }
+#endif
+
+/* 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);
+    }
+}
+
+/* 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  */
 
-/* Print on STREAM all the local variables in frame FRAME, including
-   all the blocks active in that frame at its current PC.
+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;
 
-   Returns 1 if the job was done, or 0 if nothing was printed because
-   we have no info on the function running in FRAME.  */
+  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.  */
-      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"));
 }
 
@@ -1516,6 +1618,7 @@ print_frame_label_vars (struct frame_info *frame, int this_level_only,
 #else
   struct blockvector *bl;
   struct block *block = get_frame_block (frame, 0);
+  struct gdbarch *gdbarch = get_frame_arch (frame);
   int values_printed = 0;
   int index, have_default = 0;
   char *blocks_printed;
@@ -1553,7 +1656,8 @@ print_frame_label_vars (struct frame_info *frame, int this_level_only,
        {
          if (blocks_printed[index] == 0)
            {
-             if (print_block_frame_labels (BLOCKVECTOR_BLOCK (bl, index),
+             if (print_block_frame_labels (gdbarch,
+                                           BLOCKVECTOR_BLOCK (bl, index),
                                            &have_default, stream))
                values_printed = 1;
              blocks_printed[index] = 1;
@@ -1566,7 +1670,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);
@@ -1594,29 +1700,23 @@ catch_info (char *ignore, int from_tty)
                           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.
@@ -1630,12 +1730,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"));
 }
 
@@ -1832,6 +1953,9 @@ return_command (char *retval_exp, int from_tty)
   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
      RETURN_VALUE to NULL, and QUERY_PREFIX to an informational