This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
Re: gdb stack trace problems (Addendum)
- From: Mark Kettenis <mark dot kettenis at xs4all dot nl>
- To: roland dot schwingel at onevision dot de
- Cc: gdb at sourceware dot org
- Date: Mon, 25 Apr 2005 21:26:32 +0200 (CEST)
- Subject: Re: gdb stack trace problems (Addendum)
- References: <426CA356.60901@onevision.de>
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,