From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12104 invoked by alias); 25 Apr 2005 19:28:12 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 8918 invoked from network); 25 Apr 2005 19:26:44 -0000 Received: from unknown (HELO sibelius.xs4all.nl) (82.92.89.47) by sourceware.org with SMTP; 25 Apr 2005 19:26:44 -0000 Received: from elgar.sibelius.xs4all.nl (root@elgar.sibelius.xs4all.nl [192.168.0.2]) by sibelius.xs4all.nl (8.13.0/8.13.0) with ESMTP id j3PJQXxE016481; Mon, 25 Apr 2005 21:26:33 +0200 (CEST) Received: from elgar.sibelius.xs4all.nl (kettenis@localhost.sibelius.xs4all.nl [127.0.0.1]) by elgar.sibelius.xs4all.nl (8.13.4/8.13.3) with ESMTP id j3PJQWRJ020264; Mon, 25 Apr 2005 21:26:32 +0200 (CEST) Received: (from kettenis@localhost) by elgar.sibelius.xs4all.nl (8.13.4/8.13.4/Submit) id j3PJQWUS002190; Mon, 25 Apr 2005 21:26:32 +0200 (CEST) Date: Mon, 25 Apr 2005 19:35:00 -0000 Message-Id: <200504251926.j3PJQWUS002190@elgar.sibelius.xs4all.nl> From: Mark Kettenis To: roland.schwingel@onevision.de CC: gdb@sourceware.org In-reply-to: <426CA356.60901@onevision.de> (message from Roland Schwingel on Mon, 25 Apr 2005 09:59:18 +0200) Subject: Re: gdb stack trace problems (Addendum) References: <426CA356.60901@onevision.de> X-SW-Source: 2005-04/txt/msg00178.txt.bz2 Date: Mon, 25 Apr 2005 09:59:18 +0200 From: Roland Schwingel > 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,