This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Changing "info frame" output?


Hello,

GDB's current info frame output looks like:

Stack level 1, frame at 0x7ffff290:
pc = 0x1005e5f8 in fprintf_filtered (/home/scratch/GDB/src/gdb/utils.c:2231);
saved pc 0x1005a6b8
called by frame at 0x7ffff2b0, caller of frame at 0x7ffff210
source language c.
Arglist at 0x7ffff210, args: stream=0x10465888,
format=0x1036fe4c "GNU gdb %s\n"
Locals at 0x7ffff210, Previous frame's sp is 0x7ffff290
Saved registers:
pc at 0x7ffff294, lr at 0x7ffff294


I see several problems (some apparent, some not so):

- PC and SP as registers really no longer apply.
Phrases such as ``pc = ...'' and ``saved pc'', and ``Previous frame's SP'' should be worded in a more ISA netural way.


- Often there isn't an "Arglist at ..."
Modern architectures often don't push any arguments on the stack so the argument address isn't meaningful.


- More register info.
Modern ISAs also save registers in other registers, that should be displayed. That its talking about registers saved by this frame should be clarified.


and with that in mind have come up with the following as a draft:

Stack level 1, frame at 0x7ffff240:
 Code at 0x1005e5f8 in fprintf_filtered (stream=0x10467888,
    format=0x10371b74 "GNU gdb %s\n")
    at /home/scratch/PENDING/2004-10-29-full-location/src/gdb/utils.c:2231
 called by frame at 0x7ffff260, caller of frame at 0x7ffff1c0
 Source language c.
 Frame base at 0x7ffff1c0.
 Registers saved by this frame:
    pc at 0x7ffff244, lr at 0x7ffff244

Notice how:

-- source location (second line) uses a more "standard" format
The one printed when switching frames using up/down. The format includes the argment list. I've also modified it to print "Code at" instead of "pc =".


-- the separate ``Arglist at ...'' line is dropped
The actual list is moved to "source location"; while the args address is moved to ...


-- a new "Frame base" line
Where applicable frame locals and args addresses are also printed.

-- /Saved registers:/Registered saved by this frame/
And the list can include registers saved in another register (but the example doesn't show this).


I'm still wondering:

-- Frame's ID?
Should this be printed - the frame address is the frame ID's address already.


-- "saved pc" dropped
Perhaphs it should print "Return address ..."?

thoughts,
Andrew
2004-11-03  Andrew Cagney  <cagney@gnu.org>

	* stack.c (frame_info): List registers saved in another register.
	Use the standard format when printing the source and frame
	information.  Only print the frame's args or locals address when
	different to the frame's base address.

Index: stack.c
===================================================================
RCS file: /cvs/src/src/gdb/stack.c,v
retrieving revision 1.115
diff -p -u -r1.115 stack.c
--- stack.c	30 Oct 2004 21:16:10 -0000	1.115
+++ stack.c	3 Nov 2004 15:55:50 -0000
@@ -851,106 +851,30 @@ frame_info (char *addr_exp, int from_tty
   struct frame_info *fi;
   struct symtab_and_line sal;
   struct symbol *func;
-  struct symtab *s;
   struct frame_info *calling_frame_info;
-  int i, count, numregs;
+  int i;
   char *funname = 0;
   enum language funlang = language_unknown;
   const char *pc_regname;
   int selected_frame_p;
+  struct gdbarch *gdbarch;
 
   fi = parse_frame_specification_1 (addr_exp, "No stack.", &selected_frame_p);
-
-  /* Name of the value returned by get_frame_pc().  Per comments, "pc"
-     is not a good name.  */
-  if (PC_REGNUM >= 0)
-    /* OK, this is weird.  The PC_REGNUM hardware register's value can
-       easily not match that of the internal value returned by
-       get_frame_pc().  */
-    pc_regname = REGISTER_NAME (PC_REGNUM);
-  else
-    /* But then, this is weird to.  Even without PC_REGNUM, an
-       architectures will often have a hardware register called "pc",
-       and that register's value, again, can easily not match
-       get_frame_pc().  */
-    pc_regname = "pc";
-
-  find_frame_sal (fi, &sal);
-  func = get_frame_function (fi);
-  /* FIXME: cagney/2002-11-28: Why bother?  Won't sal.symtab contain
-     the same value.  */
-  s = find_pc_symtab (get_frame_pc (fi));
-  if (func)
-    {
-      /* I'd like 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 call the demangler again,
-       * with DMGL_ANSI only. RT
-       * (Yes, I know that printf_symbol_filtered() will
-       * again try to demangle the name on the fly, but
-       * the issue is that if cplus_demangle() fails here,
-       * it'll fail there too. So we want to catch the failure
-       * ("demangled==NULL" case below) here, while we still
-       * have our hands on the function symbol.)
-       */
-      char *demangled;
-      funname = DEPRECATED_SYMBOL_NAME (func);
-      funlang = SYMBOL_LANGUAGE (func);
-      if (funlang == language_cplus)
-	{
-	  demangled = cplus_demangle (funname, DMGL_ANSI);
-	  /* If the demangler fails, try the demangled name
-	   * from the symbol table. This'll have parameters,
-	   * but that's preferable to diplaying a mangled name.
-	   */
-	  if (demangled == NULL)
-	    funname = SYMBOL_PRINT_NAME (func);
-	}
-    }
-  else
-    {
-      struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (get_frame_pc (fi));
-      if (msymbol != NULL)
-	{
-	  funname = DEPRECATED_SYMBOL_NAME (msymbol);
-	  funlang = SYMBOL_LANGUAGE (msymbol);
-	}
-    }
+  gdbarch = get_frame_arch (fi);
   calling_frame_info = get_prev_frame (fi);
 
-  if (selected_frame_p && frame_relative_level (fi) >= 0)
-    {
-      printf_filtered ("Stack level %d, frame at ",
-		       frame_relative_level (fi));
-      print_address_numeric (get_frame_base (fi), 1, gdb_stdout);
-      printf_filtered (":\n");
-    }
+  /* Opening line, dump out the frame's stack address ...  */
+  if (selected_frame_p)
+    fprintf_filtered (gdb_stdout, "Stack level %d, frame at ",
+		      frame_relative_level (fi));
   else
-    {
-      printf_filtered ("Stack frame at ");
-      print_address_numeric (get_frame_base (fi), 1, gdb_stdout);
-      printf_filtered (":\n");
-    }
-  printf_filtered (" %s = ", pc_regname);
-  print_address_numeric (get_frame_pc (fi), 1, gdb_stdout);
-
-  wrap_here ("   ");
-  if (funname)
-    {
-      printf_filtered (" in ");
-      fprintf_symbol_filtered (gdb_stdout, funname, funlang,
-			       DMGL_ANSI | DMGL_PARAMS);
-    }
-  wrap_here ("   ");
-  if (sal.symtab)
-    printf_filtered (" (%s:%d)", sal.symtab->filename, sal.line);
-  puts_filtered ("; ");
-  wrap_here ("    ");
-  printf_filtered ("saved %s ", pc_regname);
-  print_address_numeric (frame_pc_unwind (fi), 1, gdb_stdout);
-  printf_filtered ("\n");
+    fprintf_filtered (gdb_stdout, "Stack frame at ");
+  print_address_numeric (get_frame_base (fi), 1, gdb_stdout);
+  fprintf_filtered (gdb_stdout, ":\n");
+
+  /* Report where this frame is.  */
+  fprintf_filtered (gdb_stdout, " Code at ");
+  print_frame_info (fi, 0/*level*/, LOC_AND_ADDRESS, 1/*print_args*/);
 
   if (calling_frame_info)
     {
@@ -969,56 +893,49 @@ frame_info (char *addr_exp, int from_tty
     }
   if (get_next_frame (fi) || calling_frame_info)
     puts_filtered ("\n");
-  if (s)
-    printf_filtered (" source language %s.\n",
-		     language_str (s->language));
 
+  /* The source language, if known.  */
   {
-    /* Address of the argument list for this frame, or 0.  */
-    CORE_ADDR arg_list = get_frame_args_address (fi);
-    /* Number of args for this frame, or -1 if unknown.  */
-    int numargs;
-
-    if (arg_list == 0)
-      printf_filtered (" Arglist at unknown address.\n");
-    else
-      {
-	printf_filtered (" Arglist at ");
-	print_address_numeric (arg_list, 1, gdb_stdout);
-	printf_filtered (",");
-
-	if (!FRAME_NUM_ARGS_P ())
-	  {
-	    numargs = -1;
-	    puts_filtered (" args: ");
-	  }
-	else
-	  {
-	    numargs = FRAME_NUM_ARGS (fi);
-	    gdb_assert (numargs >= 0);
-	    if (numargs == 0)
-	      puts_filtered (" no args.");
-	    else if (numargs == 1)
-	      puts_filtered (" 1 arg: ");
-	    else
-	      printf_filtered (" %d args: ", numargs);
-	  }
-	print_frame_args (func, fi, numargs, gdb_stdout);
-	puts_filtered ("\n");
-      }
+    struct symtab *s;
+    s = find_pc_symtab (get_frame_pc (fi));
+    if (s)
+      printf_filtered (" Source language %s.\n",
+		       language_str (s->language));
   }
+
+  /* Print the frame's base, args, and locals addresses (if any are
+     different).  */
   {
-    /* Address of the local variables for this frame, or 0.  */
-    CORE_ADDR arg_list = get_frame_locals_address (fi);
+    CORE_ADDR base_addr;
+    CORE_ADDR args_addr;
+    CORE_ADDR locals_addr;
 
-    if (arg_list == 0)
-      printf_filtered (" Locals at unknown address,");
+    base_addr = get_frame_base_address (fi);
+    if (base_addr)
+      {
+	fprintf_filtered (gdb_stdout, " Frame base at ");
+	print_address_numeric (base_addr, 1, gdb_stdout);
+      }
     else
+      printf_filtered (" Frame base at unknown address");
+    args_addr = get_frame_args_address (fi);
+    if (args_addr && args_addr != base_addr)
+      {
+	fprintf_filtered (gdb_stdout, ",");
+	wrap_here ("   ");
+	fprintf_filtered (gdb_stdout, " arglist at ");
+	print_address_numeric (args_addr, 1, gdb_stdout);
+      }
+    locals_addr = get_frame_locals_address (fi);
+    if (locals_addr && locals_addr != base_addr)
       {
-	printf_filtered (" Locals at ");
-	print_address_numeric (arg_list, 1, gdb_stdout);
-	printf_filtered (",");
+	fprintf_filtered (gdb_stdout, ",");
+	wrap_here ("   ");
+	fprintf_filtered (gdb_stdout, " locals at ");
+	print_address_numeric (locals_addr, 1, gdb_stdout);
       }
+    if (base_addr || args_addr || locals_addr)
+      fprintf_filtered (gdb_stdout, ".\n");
   }
 
   /* Print as much information as possible on the location of all the
@@ -1028,77 +945,50 @@ frame_info (char *addr_exp, int from_tty
     int optimized;
     CORE_ADDR addr;
     int realnum;
-    int count;
-    int i;
-    int need_nl = 1;
-
-    /* The sp is special; what's displayed isn't the save address, but
-       the value of the previous frame's sp.  This is a legacy thing,
-       at one stage the frame cached the previous frame's SP instead
-       of its address, hence it was easiest to just display the cached
-       value.  */
-    if (SP_REGNUM >= 0)
+    int regnum;
+    int count = 0;
+    const int numregs = NUM_REGS + NUM_PSEUDO_REGS;
+
+    for (regnum = 0; regnum < numregs; regnum++)
       {
-	/* Find out the location of the saved stack pointer with out
-           actually evaluating it.  */
-	frame_register_unwind (fi, SP_REGNUM, &optimized, &lval, &addr,
+	/* Filter out system registers and the like.  */
+	if (!gdbarch_register_reggroup_p (current_gdbarch, regnum,
+					  all_reggroup))
+	  continue;
+	/* Find out the location of the saved register without
+	   fetching the corresponding value.  */
+	frame_register_unwind (fi, regnum, &optimized, &lval, &addr,
 			       &realnum, NULL);
-	if (!optimized && lval == not_lval)
+	/* Filter out registers that haven't been saved in another
+	   register or memory.  */
+	if (optimized)
+	  continue;
+	if (lval != lval_memory
+	    && (lval != lval_register || realnum == regnum))
+	  continue;
+	/* Print the value.  */
+	if (count == 0)
+	  puts_filtered (" Registers saved by this frame:\n   ");
+	else
 	  {
-	    char value[MAX_REGISTER_SIZE];
-	    CORE_ADDR sp;
-	    frame_register_unwind (fi, SP_REGNUM, &optimized, &lval, &addr,
-				   &realnum, value);
-	    /* 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 (current_gdbarch, SP_REGNUM));
-	    printf_filtered (" Previous frame's sp is ");
-	    print_address_numeric (sp, 1, gdb_stdout);
-	    printf_filtered ("\n");
-	    need_nl = 0;
+	    puts_filtered (",");
+	    wrap_here ("   ");
 	  }
-	else if (!optimized && lval == lval_memory)
+	count++;
+	printf_filtered (" %s", gdbarch_register_name (gdbarch, regnum));
+	switch (lval)
 	  {
-	    printf_filtered (" Previous frame's sp at ");
+	  case lval_memory:
+	    printf_filtered (" at ");
 	    print_address_numeric (addr, 1, gdb_stdout);
-	    printf_filtered ("\n");
-	    need_nl = 0;
-	  }
-	else if (!optimized && lval == lval_register)
-	  {
-	    printf_filtered (" Previous frame's sp in %s\n",
-			     REGISTER_NAME (realnum));
-	    need_nl = 0;
+	    break;
+	  case lval_register:
+	    printf_filtered (" in %s",
+			     gdbarch_register_name (gdbarch, realnum));
+	    break;
 	  }
-	/* else keep quiet.  */
       }
-
-    count = 0;
-    numregs = NUM_REGS + NUM_PSEUDO_REGS;
-    for (i = 0; i < numregs; i++)
-      if (i != SP_REGNUM
-	  && gdbarch_register_reggroup_p (current_gdbarch, i, all_reggroup))
-	{
-	  /* Find out the location of the saved register without
-             fetching the corresponding value.  */
-	  frame_register_unwind (fi, i, &optimized, &lval, &addr, &realnum,
-				 NULL);
-	  /* For moment, only display registers that were saved on the
-	     stack.  */
-	  if (!optimized && lval == lval_memory)
-	    {
-	      if (count == 0)
-		puts_filtered (" Saved registers:\n ");
-	      else
-		puts_filtered (",");
-	      wrap_here (" ");
-	      printf_filtered (" %s at ", REGISTER_NAME (i));
-	      print_address_numeric (addr, 1, gdb_stdout);
-	      count++;
-	    }
-	}
-    if (count || need_nl)
+    if (count)
       puts_filtered ("\n");
   }
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]