From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5238 invoked by alias); 6 Jun 2004 20:45:43 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 5229 invoked from network); 6 Jun 2004 20:45:42 -0000 Received: from unknown (HELO pippin.tausq.org) (64.81.244.94) by sourceware.org with SMTP; 6 Jun 2004 20:45:42 -0000 Received: by pippin.tausq.org (Postfix, from userid 1000) id 60FE5CD28A; Sun, 6 Jun 2004 13:45:44 -0700 (PDT) Date: Sun, 06 Jun 2004 20:45:00 -0000 From: Randolph Chung To: gdb-patches@sources.redhat.com Subject: [patch/rfa] Fix some corner cases in hppa stack unwinding Message-ID: <20040606204544.GY601@tausq.org> Reply-To: Randolph Chung Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-GPG: for GPG key, see http://www.tausq.org/gpg.txt User-Agent: Mutt/1.5.5.1+cvs20040105i X-SW-Source: 2004-06/txt/msg00108.txt.bz2 This fixes a few more corner cases that were not handled properly in the hppa frame unwinder. Fixes the (regression) FAILs in gdb.base/recurse.exp that Michael observed against gdb-6.1. ok to apply? randolph p.s. it's probably possible to come up with a tricky test case where the unwinder will still break: frame 0: sets/saves frame pointer, start unwinding after fp is set but before it is saved frame 1 .. n-1: does not set/save frame pointer frame n: requires frame pointer to unwind properly (e.g. calls alloca()) frame n+1 ... in this case frame n will not unwind properly because we cannot retrieve the correct fp from the stack (the one that has not yet been saved). any suggestions about how to fix this? i'll try to come up with a new test case for this. this is not a very likely scenario normally, but with software watchpoints and a recursive function that calls alloca(), it's probably possible to trigger it. I'm not sure what we can do about it though. 2004-06-06 Randolph Chung * hppa-tdep.c (hppa_frame_cache): Handle the cases when we start unwinding after sp has been saved to the stack but before the end of the prologue, and after the fp has been modified but before it has been saved to the stack. (hppa_frame_base_address, hppa_frame_base, hppa_frame_base_sniffer): Remove superfluous definitions. (hppa_gdbarch_init): Remove superfluous frame base sniffer. Index: hppa-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/hppa-tdep.c,v retrieving revision 1.166 diff -u -p -r1.166 hppa-tdep.c --- hppa-tdep.c 30 May 2004 14:11:00 -0000 1.166 +++ hppa-tdep.c 6 Jun 2004 20:26:02 -0000 @@ -1744,7 +1789,8 @@ hppa_frame_cache (struct frame_info *nex and saved on the stack, the Save_SP flag is set. We use this to decide whether to use the frame pointer for unwinding. - fp should never be zero here; checking just in case. + fp may be zero if it is not available in an inner frame because + it has been modified by not yet saved. TODO: For the HP compiler, maybe we should use the alloca_frame flag instead of Save_SP. */ @@ -1760,10 +1806,9 @@ hppa_frame_cache (struct frame_info *nex fprintf_unfiltered (gdb_stdlog, " (base=0x%s) [frame pointer] }", paddr_nz (cache->base)); } - else if (frame_pc_unwind (next_frame) >= prologue_end) + else if (u->Save_SP + && trad_frame_addr_p (cache->saved_regs, HPPA_SP_REGNUM)) { - if (u->Save_SP && trad_frame_addr_p (cache->saved_regs, HPPA_SP_REGNUM)) - { /* Both we're expecting the SP to be saved and the SP has been saved. The entry SP value is saved at this frame's SP address. */ @@ -1772,29 +1817,17 @@ hppa_frame_cache (struct frame_info *nex if (hppa_debug) fprintf_unfiltered (gdb_stdlog, " (base=0x%s) [saved] }", paddr_nz (cache->base)); - } - else - { - /* The prologue has been slowly allocating stack space. Adjust - the SP back. */ - cache->base = this_sp - frame_size; - if (hppa_debug) - fprintf_unfiltered (gdb_stdlog, " (base=0x%s) [unwind adjust] } ", - paddr_nz (cache->base)); - - } } else { - /* This frame has not yet been created. */ - cache->base = this_sp; - + /* The prologue has been slowly allocating stack space. Adjust + the SP back. */ + cache->base = this_sp - frame_size; if (hppa_debug) - fprintf_unfiltered (gdb_stdlog, " (base=0x%s) [before prologue] } ", + fprintf_unfiltered (gdb_stdlog, " (base=0x%s) [unwind adjust] } ", paddr_nz (cache->base)); } - trad_frame_set_value (cache->saved_regs, HPPA_SP_REGNUM, cache->base); } @@ -1821,6 +1854,14 @@ hppa_frame_cache (struct frame_info *nex } } + /* If the frame pointer was not saved in this frame, but we should be saving + it, set it to an invalid value so that another frame will not pick up the + wrong frame pointer. This can happen if we start unwinding after the + frame pointer has been modified, but before we've saved it to the + stack. */ + if (u->Save_SP && !trad_frame_addr_p (cache->saved_regs, HPPA_FP_REGNUM)) + trad_frame_set_value (cache->saved_regs, HPPA_FP_REGNUM, 0); + { /* Convert all the offsets into addresses. */ int reg; @@ -1978,28 +2020,6 @@ hppa_fallback_unwind_sniffer (struct fra return &hppa_fallback_frame_unwind; } -static CORE_ADDR -hppa_frame_base_address (struct frame_info *next_frame, - void **this_cache) -{ - struct hppa_frame_cache *info = hppa_frame_cache (next_frame, - this_cache); - return info->base; -} - -static const struct frame_base hppa_frame_base = { - &hppa_frame_unwind, - hppa_frame_base_address, - hppa_frame_base_address, - hppa_frame_base_address -}; - -static const struct frame_base * -hppa_frame_base_sniffer (struct frame_info *next_frame) -{ - return &hppa_frame_base; -} - /* Stub frames, used for all kinds of call stubs. */ struct hppa_stub_unwind_cache { @@ -2505,7 +2535,6 @@ hppa_gdbarch_init (struct gdbarch_info i frame_unwind_append_sniffer (gdbarch, hppa_stub_unwind_sniffer); frame_unwind_append_sniffer (gdbarch, hppa_frame_unwind_sniffer); frame_unwind_append_sniffer (gdbarch, hppa_fallback_unwind_sniffer); - frame_base_append_sniffer (gdbarch, hppa_frame_base_sniffer); return gdbarch; } -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/