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]

Re: gdb stack trace problems (Addendum)


   Date: Mon, 25 Apr 2005 09:59:18 +0200
   From: Roland Schwingel <roland.schwingel@onevision.de>

    > Anyway, there is a serious problem here.  The code you show is
    > basically undebuggable.
    > [...]
    > The only thing we can do here is trust the frame pointer, like we used
    > to do in the old days.  The problem with that is that it's very likely
    > to (silently) skip some function calls.  In your particular example it
    > probably would appear as if your code called SleepEx directly and
    > there would be no trace of Sleep at all.  That can be quite puzzling.
    >
    > I'm thinking about adding an option to instruct gdb to "trust" the
    > frame pointer.  I'm not going to make it the default though.  I really
    > prefer seeing an abviously wrong backtrace over gdb silently skipping
    > function calls in its backtraces.
   Well the present situation is quite problematic for us. In past days 
   (gdb 5.3)
   when an application crashed we had a quite accurate backtrace. It wasn't
   wrong (for us). Finding/Fixing bugs was very easy. GDB has been
   very useful here.

You probably didn't notice it was wrong...

   With gdb 6.x we are no longer able to get a backtrace in these
   cases (in about 95% of all cases). This is a serious problem and
   makes gdb 6.x quite unusable for us (and maybe others on
   windows). Having at least an option for enabling that feature would
   be IMHO absolutely necessary. I wonder why other users on windows
   haven't complained earlier about this problem.

Oh they've complained, but never followed through when I asked for
information or tests.

   So will you implement such an option? I am quite unfamiliar with
   the internals of gdb's stack unwinding, so I am not of much help
   here. But whenever I can do something to help to fix this I am
   happily volunteering to do so.

Can you test the attached patch?  It introduces a new option named
"trust-frame-pointer".  Whenever you encounter a problem you can:

(gdb) set trust-frame-pointer 1

and try again.  You probably want to reset it to 0 before continuing
your program since I found out that bad things happen with some of the
tests in the gdb testsuite with this turned on.

Mark


Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.209
diff -u -p -r1.209 i386-tdep.c
--- i386-tdep.c 6 Apr 2005 17:01:25 -0000 1.209
+++ i386-tdep.c 25 Apr 2005 19:24:54 -0000
@@ -858,10 +858,19 @@ i386_unwind_pc (struct gdbarch *gdbarch,
 
 /* Normal frames.  */
 
+static int trust_frame_pointer = 0;
+
+static void set_trust_frame_pointer (char *args, int from_tty,
+				     struct cmd_list_element *c)
+{
+  flush_cached_frames();
+}
+
 static struct i386_frame_cache *
 i386_frame_cache (struct frame_info *next_frame, void **this_cache)
 {
   struct i386_frame_cache *cache;
+  CORE_ADDR pc = 0;
   char buf[4];
   int i;
 
@@ -890,7 +899,8 @@ i386_frame_cache (struct frame_info *nex
 
   cache->pc = frame_func_unwind (next_frame);
   if (cache->pc != 0)
-    i386_analyze_prologue (cache->pc, frame_pc_unwind (next_frame), cache);
+    pc = i386_analyze_prologue (cache->pc, frame_pc_unwind (next_frame),
+				cache);
 
   if (cache->locals < 0)
     {
@@ -902,8 +912,11 @@ i386_frame_cache (struct frame_info *nex
 	 frame by looking at the stack pointer.  For truly "frameless"
 	 functions this might work too.  */
 
-      frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
-      cache->base = extract_unsigned_integer (buf, 4) + cache->sp_offset;
+      if (!trust_frame_pointer || pc == frame_pc_unwind (next_frame))
+	{
+	  frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
+	  cache->base = extract_unsigned_integer (buf, 4) + cache->sp_offset;
+	}
     }
 
   /* Now that we have the base address for the stack frame we can
@@ -2360,6 +2373,16 @@ is \"default\"."),
 			NULL, /* FIXME: i18n: */
 			&setlist, &showlist);
 
+  /* Add the variable that controls whether we trust the frame pointer.  */
+  add_setshow_boolean_cmd ("trust-frame-pointer", no_class,
+			   &trust_frame_pointer, _("\
+Set whether we trust the frame pointer"), _("\
+Show whether we trust the frame pointer"), _("\
+XXXX"),
+			   set_trust_frame_pointer,
+			   NULL, /* FIXME: i18n: */
+			   &setlist, &showlist);
+
   gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
 				  i386_coff_osabi_sniffer);
   gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_nlm_flavour,


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