* Rename remote-es1800.c to remote-es.c
[deliverable/binutils-gdb.git] / gdb / stack.c
index 23bf9cb584e7072b5d2baf30513f4dd3f9e700f2..4849e5d047a5969904013ef839fc7afd2f07cb00 100644 (file)
@@ -1,5 +1,5 @@
 /* Print and select stack frames for GDB, the GNU debugger.
-   Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -17,25 +17,80 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-#include <stdio.h>
-
 #include "defs.h"
-#include "param.h"
-#include "language.h"
+#include "value.h"
 #include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "language.h"
 #include "frame.h"
 #include "gdbcmd.h"
-#include "value.h"
 #include "gdbcore.h"
 #include "target.h"
 #include "breakpoint.h"
+#include "demangle.h"
+#include "inferior.h"
+
+static void
+return_command PARAMS ((char *, int));
+
+static void
+down_command PARAMS ((char *, int));
+
+static void
+down_silently_command PARAMS ((char *, int));
+
+static void
+up_command PARAMS ((char *, int));
+
+static void
+up_silently_command PARAMS ((char *, int));
+
+static void
+frame_command PARAMS ((char *, int));
+
+static void
+select_frame_command PARAMS ((char *, int));
+
+static void
+args_info PARAMS ((char *, int));
+
+static void
+print_frame_arg_vars PARAMS ((FRAME, FILE *));
+
+static void
+catch_info PARAMS ((char *, int));
+
+static void
+locals_info PARAMS ((char *, int));
+
+static void
+print_frame_label_vars PARAMS ((FRAME, int, FILE *));
+
+static void
+print_frame_local_vars PARAMS ((FRAME, FILE *));
+
+static int
+print_block_frame_labels PARAMS ((struct block *, int *, FILE *));
+
+static int
+print_block_frame_locals PARAMS ((struct block *, FRAME, FILE *));
+
+static void
+backtrace_command PARAMS ((char *, int));
+
+static FRAME
+parse_frame_specification PARAMS ((char *));
+
+static void
+frame_info PARAMS ((char *, int));
+
 
 extern int addressprint;       /* Print addresses, or stay symbolic only? */
 extern int info_verbose;       /* Verbosity of symbol reading msgs */
 extern int lines_to_list;      /* # of lines "list" command shows by default */
-extern char *reg_names[];      /* Names of registers */
 
-/* Thie "selected" stack frame is used by default for local and arg access.
+/* The "selected" stack frame is used by default for local and arg access.
    May be zero, for no selected frame.  */
 
 FRAME selected_frame;
@@ -51,7 +106,6 @@ int selected_frame_level;
 
 int frame_file_full_name = 0;
 
-void print_frame_info ();
 \f
 /* Print a stack frame briefly.  FRAME should be the frame id
    and LEVEL should be its level in the stack (or -1 for level not defined).
@@ -86,32 +140,27 @@ print_frame_info (fi, level, source, args)
   struct symtab_and_line sal;
   struct symbol *func;
   register char *funname = 0;
+  enum language funlang = language_unknown;
   int numargs;
 
-#if 0  /* Symbol reading is fast enough now */
-  struct partial_symtab *pst;
-
-  /* Don't give very much information if we haven't readin the
-     symbol table yet.  */
-  pst = find_pc_psymtab (fi->pc);
-  if (pst && !pst->readin)
+  if (PC_IN_CALL_DUMMY (fi->pc, read_register (SP_REGNUM), fi->frame))
     {
-      /* Abbreviated information.  */
-      char *fname;
-
-      if (!find_pc_partial_function (fi->pc, &fname, 0))
-       fname = "??";
-       
-      printf_filtered ("#%-2d ", level);
-      if (addressprint)
-        printf_filtered ("%s in ", local_hex_string(fi->pc));
-
-      fputs_demangled (fname, stdout, -1);
-      fputs_filtered (" (...)\n", stdout);
-      
+      /* Do this regardless of SOURCE because we don't have any source
+        to list for this frame.  */
+      if (level >= 0)
+       printf_filtered ("#%-2d ", level);
+      printf_filtered ("<function called from gdb>\n");
+      return;
+    }
+  if (fi->signal_handler_caller)
+    {
+      /* Do this regardless of SOURCE because we don't have any source
+        to list for this frame.  */
+      if (level >= 0)
+       printf_filtered ("#%-2d ", level);
+      printf_filtered ("<signal handler called>\n");
       return;
     }
-#endif
 
   sal = find_pc_line (fi->pc, fi->next_frame);
   func = find_pc_function (fi->pc);
@@ -125,14 +174,15 @@ print_frame_info (fi, level, source, args)
         ends has been truncated by ar because it is longer than 15
         characters).
 
-        So look in the misc_function_vector as well, and if it comes
+        So look in the minimal symbol tables as well, and if it comes
         up with a larger address for the function use that instead.
-        I don't think this can ever cause any problems;
-        there shouldn't be any
-        misc_function_vector symbols in the middle of a function.  */
-      int misc_index = find_pc_misc_function (fi->pc);
-      if (misc_index >= 0
-         && (misc_function_vector[misc_index].address
+        I don't think this can ever cause any problems; there shouldn't
+        be any minimal symbols in the middle of a function.
+        FIXME:  (Not necessarily true.  What about text labels) */
+
+      struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
+      if (msymbol != NULL
+         && (SYMBOL_VALUE_ADDRESS (msymbol) 
              > BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
        {
          /* In this case we have no way of knowing the source file
@@ -141,16 +191,23 @@ print_frame_info (fi, level, source, args)
          /* We also don't know anything about the function besides
             its address and name.  */
          func = 0;
-         funname = misc_function_vector[misc_index].name;
+         funname = SYMBOL_NAME (msymbol);
+         funlang = SYMBOL_LANGUAGE (msymbol);
        }
       else
-       funname = SYMBOL_NAME (func);
+       {
+         funname = SYMBOL_NAME (func);
+         funlang = SYMBOL_LANGUAGE (func);
+       }
     }
   else
     {
-      register int misc_index = find_pc_misc_function (fi->pc);
-      if (misc_index >= 0)
-       funname = misc_function_vector[misc_index].name;
+      register struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
+      if (msymbol != NULL)
+       {
+         funname = SYMBOL_NAME (msymbol);
+         funlang = SYMBOL_LANGUAGE (msymbol);
+       }
     }
 
   if (source >= 0 || !sal.symtab)
@@ -160,7 +217,8 @@ print_frame_info (fi, level, source, args)
       if (addressprint)
        if (fi->pc != sal.pc || !sal.symtab)
          printf_filtered ("%s in ", local_hex_string(fi->pc));
-      fputs_demangled (funname ? funname : "??", stdout, -1);
+      fprintf_symbol_filtered (stdout, funname ? funname : "??", funlang,
+                              DMGL_NO_OPTS);
       wrap_here ("   ");
       fputs_filtered (" (", stdout);
       if (args)
@@ -174,6 +232,16 @@ print_frame_info (fi, level, source, args)
           wrap_here ("   ");
          printf_filtered (" at %s:%d", sal.symtab->filename, sal.line);
        }
+
+#ifdef PC_LOAD_SEGMENT
+     /* If we couldn't print out function name but if can figure out what
+        load segment this pc value is from, at least print out some info
+       about its load segment. */
+      if (!funname) {
+       wrap_here ("  ");
+       printf_filtered (" from %s", PC_LOAD_SEGMENT (fi->pc));
+      }
+#endif
       printf_filtered ("\n");
     }
 
@@ -197,12 +265,6 @@ print_frame_info (fi, level, source, args)
   fflush (stdout);
 }
 
-void flush_cached_frames ();
-
-#ifdef FRAME_SPECIFICATION_DYADIC
-extern FRAME setup_arbitrary_frame ();
-#endif
-
 /*
  * Read a frame specification in whatever the appropriate format is.
  * Call error() if the specification is in any way invalid (i.e.
@@ -213,7 +275,9 @@ parse_frame_specification (frame_exp)
      char *frame_exp;
 {
   int numargs = 0;
-  int arg1, arg2;
+  int arg1, arg2, arg3;
+#define        MAXARGS 4
+  int args[MAXARGS];
   
   if (frame_exp)
     {
@@ -221,27 +285,25 @@ parse_frame_specification (frame_exp)
       struct cleanup *tmp_cleanup;
 
       while (*frame_exp == ' ') frame_exp++;
-      for (p = frame_exp; *p && *p != ' '; p++)
-       ;
 
-      if (*frame_exp)
+      while (*frame_exp)
        {
-         numargs = 1;
+         if (numargs > MAXARGS)
+           error ("Too many args in frame specification");
+         /* Parse an argument.  */
+          for (p = frame_exp; *p && *p != ' '; p++)
+           ;
          addr_string = savestring(frame_exp, p - frame_exp);
 
          {
            tmp_cleanup = make_cleanup (free, addr_string);
-           arg1 = parse_and_eval_address (addr_string);
+           args[numargs++] = parse_and_eval_address (addr_string);
            do_cleanups (tmp_cleanup);
          }
 
+         /* Skip spaces, move to possible next arg.  */
          while (*p == ' ') p++;
-         
-         if (*p)
-           {
-             numargs = 2;
-             arg2 = parse_and_eval_address (p);
-           }
+         frame_exp = p;
        }
     }
 
@@ -254,7 +316,7 @@ parse_frame_specification (frame_exp)
       /* NOTREACHED */
     case 1:
       {
-       int level = arg1;
+       int level = args[0];
        FRAME fid = find_relative_frame (get_current_frame (), &level);
        FRAME tfid;
 
@@ -266,35 +328,33 @@ parse_frame_specification (frame_exp)
           (s)he gets.  Still, give the highest one that matches.  */
 
        for (fid = get_current_frame ();
-            fid && FRAME_FP (fid) != arg1;
+            fid && FRAME_FP (fid) != args[0];
             fid = get_prev_frame (fid))
          ;
 
        if (fid)
          while ((tfid = get_prev_frame (fid)) &&
-                (FRAME_FP (tfid) == arg1))
+                (FRAME_FP (tfid) == args[0]))
            fid = tfid;
          
-#ifdef FRAME_SPECIFICATION_DYADIC
-       if (!fid)
-         error ("Incorrect number of args in frame specification");
-
-       return fid;
-#else
-       return create_new_frame (arg1, 0);
-#endif
+       /* We couldn't identify the frame as an existing frame, but
+          perhaps we can create one with a single argument.
+          Fall through to default case; it's up to SETUP_ARBITRARY_FRAME
+          to complain if it doesn't like a single arg.  */
       }
-      /* NOTREACHED */
-    case 2:
-      /* Must be addresses */
-#ifndef FRAME_SPECIFICATION_DYADIC
-      error ("Incorrect number of args in frame specification");
+
+     default:
+#ifdef SETUP_ARBITRARY_FRAME
+      return SETUP_ARBITRARY_FRAME (numargs, args);
 #else
-      return setup_arbitrary_frame (arg1, arg2);
+      /* Usual case.  Do it here rather than have everyone supply
+        a SETUP_ARBITRARY_FRAME that does this.  */
+      if (numargs == 1)
+       return create_new_frame (args[0], 0);
+      error ("Too many args in frame specification");
 #endif
       /* NOTREACHED */
     }
-  fatal ("Internal: Error in parsing in parse_frame_specification");
   /* NOTREACHED */
 }
 
@@ -312,8 +372,9 @@ parse_frame_specification (frame_exp)
    This means absolutely all information in the frame is printed.  */
 
 static void
-frame_info (addr_exp)
+frame_info (addr_exp, from_tty)
      char *addr_exp;
+     int from_tty;
 {
   FRAME frame;
   struct frame_info *fi;
@@ -324,9 +385,10 @@ frame_info (addr_exp)
   FRAME calling_frame;
   int i, count;
   char *funname = 0;
+  enum language funlang = language_unknown;
 
   if (!target_has_stack)
-    error ("No inferior or core file.");
+    error ("No stack.");
 
   frame = parse_frame_specification (addr_exp);
   if (!frame)
@@ -337,12 +399,18 @@ frame_info (addr_exp)
   func = get_frame_function (frame);
   s = find_pc_symtab(fi->pc);
   if (func)
-    funname = SYMBOL_NAME (func);
+    {
+      funname = SYMBOL_NAME (func);
+      funlang = SYMBOL_LANGUAGE (func);
+    }
   else
     {
-      register int misc_index = find_pc_misc_function (fi->pc);
-      if (misc_index >= 0)
-       funname = misc_function_vector[misc_index].name;
+      register struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
+      if (msymbol != NULL)
+       {
+         funname = SYMBOL_NAME (msymbol);
+         funlang = SYMBOL_LANGUAGE (msymbol);
+       }
     }
   calling_frame = get_prev_frame (frame);
 
@@ -360,7 +428,11 @@ frame_info (addr_exp)
 
   wrap_here ("   ");
   if (funname)
-    printf_filtered (" in %s", funname);
+    {
+      printf_filtered (" in ");
+      fprintf_symbol_filtered (stdout, funname, funlang,
+                              DMGL_ANSI | DMGL_PARAMS);
+    }
   wrap_here ("   ");
   if (sal.symtab)
     printf_filtered (" (%s:%d)", sal.symtab->filename, sal.line);
@@ -368,6 +440,16 @@ frame_info (addr_exp)
   wrap_here ("    ");
   printf_filtered ("saved %s %s\n", reg_names[PC_REGNUM],
                   local_hex_string(FRAME_SAVED_PC (frame)));
+
+  {
+    int frameless = 0;
+#ifdef FRAMELESS_FUNCTION_INVOCATION
+    FRAMELESS_FUNCTION_INVOCATION (fi, frameless);
+#endif
+    if (frameless)
+      printf_filtered (" (FRAMELESS),");
+  }
+
   if (calling_frame)
     printf_filtered (" called by frame at %s", 
                     local_hex_string(FRAME_FP (calling_frame)));
@@ -381,6 +463,10 @@ frame_info (addr_exp)
   if (s)
      printf_filtered(" source language %s.\n", language_str(s->language));
 
+#ifdef PRINT_EXTRA_FRAME_INFO
+  PRINT_EXTRA_FRAME_INFO (fi);
+#endif
+
   {
     /* Address of the argument list for this frame, or 0.  */
     CORE_ADDR arg_list = FRAME_ARGS_ADDRESS_CORRECT (fi);
@@ -406,6 +492,15 @@ frame_info (addr_exp)
        puts_filtered ("\n");
       }
   }
+  {
+    /* Address of the local variables for this frame, or 0.  */
+    CORE_ADDR arg_list = FRAME_LOCALS_ADDRESS (fi);
+
+    if (arg_list == 0)
+       printf_filtered (" Locals at unknown address,");
+    else
+       printf_filtered (" Locals at %s,", local_hex_string(arg_list));
+  }
 
 #if defined (FRAME_FIND_SAVED_REGS)  
   get_frame_saved_regs (fi, &fsr);
@@ -535,7 +630,7 @@ backtrace_command (count_exp, from_tty)
          fi = get_frame_info (frame);
          ps = find_pc_psymtab (fi->pc);
          if (ps)
-           (void) PSYMTAB_TO_SYMTAB (ps);      /* Force syms to come in */
+           PSYMTAB_TO_SYMTAB (ps);     /* Force syms to come in */
        }
     }
 
@@ -577,11 +672,10 @@ print_block_frame_locals (b, frame, stream)
          || SYMBOL_CLASS (sym) == LOC_STATIC)
        {
          values_printed = 1;
-         fprint_symbol (stream, SYMBOL_NAME (sym));
+         fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream);
          fputs_filtered (" = ", stream);
          print_variable_value (sym, frame, stream);
          fprintf_filtered (stream, "\n");
-         fflush (stream);
        }
     }
   return values_printed;
@@ -605,7 +699,7 @@ print_block_frame_labels (b, have_default, stream)
   for (i = 0; i < nsyms; i++)
     {
       sym = BLOCK_SYM (b, i);
-      if (! strcmp (SYMBOL_NAME (sym), "default"))
+      if (STREQ (SYMBOL_NAME (sym), "default"))
        {
          if (*have_default)
            continue;
@@ -616,13 +710,12 @@ print_block_frame_labels (b, have_default, stream)
          struct symtab_and_line sal;
          sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym), 0);
          values_printed = 1;
-         fputs_demangled (SYMBOL_NAME (sym), stream, 1);
+         fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream);
          if (addressprint)
            fprintf_filtered (stream, " %s", 
                              local_hex_string(SYMBOL_VALUE_ADDRESS (sym)));
          fprintf_filtered (stream, " in file %s, line %d\n",
                            sal.symtab->filename, sal.line);
-         fflush (stream);
        }
     }
   return values_printed;
@@ -636,7 +729,7 @@ print_block_frame_labels (b, have_default, stream)
    or 0 if nothing was printed because we have no info
    on the function running in FRAME.  */
 
-static int
+static void
 print_frame_local_vars (frame, stream)
      register FRAME frame;
      register FILE *stream;
@@ -647,8 +740,7 @@ print_frame_local_vars (frame, stream)
   if (block == 0)
     {
       fprintf_filtered (stream, "No symbol table info available.\n");
-      fflush (stream);
-      return 0;
+      return;
     }
   
   while (block != 0)
@@ -666,21 +758,17 @@ print_frame_local_vars (frame, stream)
   if (!values_printed)
     {
       fprintf_filtered (stream, "No locals.\n");
-      fflush (stream);
     }
-  
-  return 1;
 }
 
 /* Same, but print labels.  */
 
-static int
+static void
 print_frame_label_vars (frame, this_level_only, stream)
      register FRAME frame;
      int this_level_only;
      register FILE *stream;
 {
-  extern struct blockvector *blockvector_for_pc ();
   register struct blockvector *bl;
   register struct block *block = get_frame_block (frame);
   register int values_printed = 0;
@@ -692,13 +780,12 @@ print_frame_label_vars (frame, this_level_only, stream)
   if (block == 0)
     {
       fprintf_filtered (stream, "No symbol table info available.\n");
-      fflush (stream);
-      return 0;
+      return;
     }
 
   bl = blockvector_for_pc (BLOCK_END (block) - 4, &index);
   blocks_printed = (char *) alloca (BLOCKVECTOR_NBLOCKS (bl) * sizeof (char));
-  bzero (blocks_printed, BLOCKVECTOR_NBLOCKS (bl) * sizeof (char));
+  memset (blocks_printed, 0, BLOCKVECTOR_NBLOCKS (bl) * sizeof (char));
 
   while (block != 0)
     {
@@ -729,9 +816,9 @@ print_frame_label_vars (frame, this_level_only, stream)
          index++;
        }
       if (have_default)
-       return 1;
+       return;
       if (values_printed && this_level_only)
-       return 1;
+       return;
 
       /* After handling the function's top-level block, stop.
         Don't continue to its superblock, the block of
@@ -744,10 +831,7 @@ print_frame_label_vars (frame, this_level_only, stream)
   if (!values_printed && !this_level_only)
     {
       fprintf_filtered (stream, "No catches.\n");
-      fflush (stream);
     }
-  
-  return values_printed;
 }
 
 /* ARGSUSED */
@@ -762,14 +846,16 @@ locals_info (args, from_tty)
 }
 
 static void
-catch_info ()
+catch_info (ignore, from_tty)
+     char *ignore;
+     int from_tty;
 {
   if (!selected_frame)
     error ("No frame selected.");
   print_frame_label_vars (selected_frame, 0, stdout);
 }
 
-static int
+static void
 print_frame_arg_vars (frame, stream)
      register FRAME frame;
      register FILE *stream;
@@ -784,8 +870,7 @@ print_frame_arg_vars (frame, stream)
   if (func == 0)
     {
       fprintf_filtered (stream, "No symbol table info available.\n");
-      fflush (stream);
-      return 0;
+      return;
     }
 
   b = SYMBOL_BLOCK_VALUE (func);
@@ -797,34 +882,41 @@ print_frame_arg_vars (frame, stream)
       if (SYMBOL_CLASS (sym) == LOC_ARG
          || SYMBOL_CLASS (sym) == LOC_LOCAL_ARG
          || SYMBOL_CLASS (sym) == LOC_REF_ARG
-         || SYMBOL_CLASS (sym) == LOC_REGPARM)
+         || SYMBOL_CLASS (sym) == LOC_REGPARM
+         || SYMBOL_CLASS (sym) == LOC_REGPARM_ADDR)
        {
          values_printed = 1;
-         fprint_symbol (stream, SYMBOL_NAME (sym));
+         fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream);
          fputs_filtered (" = ", stream);
-         /* We have to look up the symbol because arguments often have
-            two entries (one a parameter, one a register) and the one
-            we want is the register, which lookup_symbol will find for
-            us.  */
+
+         /* 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.
+            This includes gcc1 (not gcc2) on the sparc when passing a
+            small structure and gcc2 when the argument type is float
+            and it is passed as a double and converted to float by
+            the prologue (in the latter case the type of the LOC_ARG
+            symbol is double and the type of the LOC_LOCAL symbol is
+            float).  There are also LOC_ARG/LOC_REGISTER pairs which
+            are not combined in symbol-reading.  */
+
          sym2 = lookup_symbol (SYMBOL_NAME (sym),
                        b, VAR_NAMESPACE, (int *)NULL, (struct symtab **)NULL);
          print_variable_value (sym2, frame, stream);
          fprintf_filtered (stream, "\n");
-         fflush (stream);
        }
     }
 
   if (!values_printed)
     {
       fprintf_filtered (stream, "No arguments.\n");
-      fflush (stream);
     }
-
-  return 1;
 }
 
 static void
-args_info ()
+args_info (ignore, from_tty)
+     char *ignore;
+     int from_tty;
 {
   if (!selected_frame)
     error ("No frame selected.");
@@ -866,7 +958,7 @@ record_selected_frame (frameaddrp, levelp)
      FRAME_ADDR *frameaddrp;
      int *levelp;
 {
-  *frameaddrp = selected_frame ? FRAME_FP (selected_frame) : NULL;
+  *frameaddrp = selected_frame ? FRAME_FP (selected_frame) : 0;
   *levelp = selected_frame_level;
 }
 
@@ -925,14 +1017,15 @@ find_relative_frame (frame, level_offset_ptr)
   return frame;
 }
 
-/* The "frame" command.  With no arg, print selected frame briefly.
+/* The "select_frame" command.  With no arg, NOP.
    With arg LEVEL_EXP, select the frame at level LEVEL if it is a
    valid level.  Otherwise, treat level_exp as an address expression
-   and print it.  See parse_frame_specification for more info on proper
+   and select it.  See parse_frame_specification for more info on proper
    frame expressions. */
 
+/* ARGSUSED */
 static void
-frame_command (level_exp, from_tty)
+select_frame_command (level_exp, from_tty)
      char *level_exp;
      int from_tty;
 {
@@ -958,10 +1051,18 @@ frame_command (level_exp, from_tty)
     level = 0;
 
   select_frame (frame, level);
+}
 
-  if (!from_tty)
-    return;
+/* The "frame" command.  With no arg, print selected frame briefly.
+   With arg, behaves like select_frame and then prints the selected
+   frame.  */
 
+static void
+frame_command (level_exp, from_tty)
+     char *level_exp;
+     int from_tty;
+{
+  select_frame_command (level_exp, from_tty);
   print_stack_frame (selected_frame, selected_frame_level, 1);
 }
 
@@ -980,7 +1081,7 @@ up_silently_command (count_exp, from_tty)
     count = parse_and_eval_address (count_exp);
   count1 = count;
   
-  if (!target_has_stack)
+  if (target_has_stack == 0 || selected_frame == 0)
     error ("No stack.");
 
   frame = find_relative_frame (selected_frame, &count1);
@@ -1013,7 +1114,7 @@ down_silently_command (count_exp, from_tty)
     count = - parse_and_eval_address (count_exp);
   count1 = count;
   
-  if (!target_has_stack)
+  if (target_has_stack == 0 || selected_frame == 0)
     error ("No stack.");
 
   frame = find_relative_frame (selected_frame, &count1);
@@ -1041,6 +1142,7 @@ return_command (retval_exp, from_tty)
   FRAME_ADDR selected_frame_addr;
   CORE_ADDR selected_frame_pc;
   FRAME frame;
+  value return_value;
 
   if (selected_frame == NULL)
     error ("No selected frame.");
@@ -1048,14 +1150,27 @@ return_command (retval_exp, from_tty)
   selected_frame_addr = FRAME_FP (selected_frame);
   selected_frame_pc = (get_frame_info (selected_frame))->pc;
 
+  /* Compute the return value (if any -- possibly getting errors here).
+     Call VALUE_CONTENTS to make sure we have fully evaluated it, since
+     it might live in the stack frame we're about to pop.  */
+
+  if (retval_exp)
+    {
+      return_value = parse_and_eval (retval_exp);
+      VALUE_CONTENTS (return_value);
+    }
+
   /* If interactive, require confirmation.  */
 
   if (from_tty)
     {
       if (thisfun != 0)
        {
-         if (!query ("Make %s return now? ", SYMBOL_NAME (thisfun)))
-           error ("Not confirmed.");
+         if (!query ("Make %s return now? ", SYMBOL_SOURCE_NAME (thisfun)))
+           {
+             error ("Not confirmed.");
+             /* NOTREACHED */
+           }
        }
       else
        if (!query ("Make selected stack frame return now? "))
@@ -1079,7 +1194,7 @@ return_command (retval_exp, from_tty)
      for return values.  */
 
   if (retval_exp)
-    set_return_value (parse_and_eval (retval_exp));
+    set_return_value (return_value);
 
   /* If interactive, print the frame that is now current.  */
 
@@ -1134,6 +1249,7 @@ This is useful in command scripts.");
           "Select and print stack frame called by this one.\n\
 An argument says how many frames down to go.");
   add_com_alias ("do", "down", class_stack, 1);
+  add_com_alias ("dow", "down", class_stack, 1);
   add_com ("down-silently", class_support, down_silently_command,
           "Same as the `down' command, but does not print anything.\n\
 This is useful in command scripts.");
@@ -1148,6 +1264,11 @@ a command file or a user-defined command.");
 
   add_com_alias ("f", "frame", class_stack, 1);
 
+  add_com ("select-frame", class_stack, select_frame_command,
+          "Select a stack frame without printing anything.\n\
+An argument specifies the frame to select.\n\
+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.");
This page took 0.033779 seconds and 4 git commands to generate.