From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22940 invoked by alias); 1 Apr 2004 00:34:53 -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 22921 invoked from network); 1 Apr 2004 00:34:51 -0000 Received: from unknown (HELO takamaka.act-europe.fr) (142.179.108.108) by sources.redhat.com with SMTP; 1 Apr 2004 00:34:51 -0000 Received: by takamaka.act-europe.fr (Postfix, from userid 507) id 000FE47D62; Wed, 31 Mar 2004 16:34:49 -0800 (PST) Date: Thu, 01 Apr 2004 00:34:00 -0000 From: Joel Brobecker To: gdb-patches@sources.redhat.com Subject: [RFA] Fix an unwinding problem on alpha-tru64 Message-ID: <20040401003449.GY888@gnat.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="AYsPlKobQGgtCvjI" Content-Disposition: inline User-Agent: Mutt/1.4i X-SW-Source: 2004-04/txt/msg00001.txt.bz2 --AYsPlKobQGgtCvjI Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 2430 Hello, One of our users reported that GDB is unable to compute the backtrace from __hstTransferRegistersPC on Tru64 5.1b. We never noticed this before because our machines run 4.0f and 5.1a. Anyway, what happened is that the user switched to an inactive thread, and then asked for the backtrace, and got: (gdb) bt #0 0x000003ff805c174c in __hstTransferRegistersPC () from /usr/shlib/libpthread.so #1 0x000003ff805b0fe8 in __osTransferContext () from /usr/shlib/libpthread.so warning: Hit heuristic-fence-post without finding warning: enclosing function for address 0x20000a1d440 And inspection of the assembly code for __osTransferContext reveals the source of the problem: Dump of assembler code for function __osTransferContext: <__osTransferContext>: ldah gp,16321(t12) <__osTransferContext+4>: unop <__osTransferContext+8>: lda gp,-3056(gp) <__osTransferContext+12>: unop <__osTransferContext+16>: lda sp,-64(sp) <__osTransferContext+20>: stq ra,0(sp) <__osTransferContext+24>: stq s0,8(sp) <__osTransferContext+28>: stq s1,16(sp) <__osTransferContext+32>: stq s2,24(sp) <__osTransferContext+36>: stq s3,32(sp) <__osTransferContext+40>: stq s4,40(sp) <__osTransferContext+44>: stq fp,48(sp) <__osTransferContext+48>: mov sp,fp [...] <__osTransferContext+160>: ldq ra,0(s2) <__osTransferContext+164>: stq ra,8(sp) So we can see that the return address is saved at $fp+0 (insn @ +20 and +48). The function scanner in alpha_heuristic_frame_unwind_cache() first interpreted the code correctly and stored the fact that $ra was at $fp+0. However, upon reading the insn @ +164, it doesn't realizes that it's the second time we see this register being saved, and therefore changes our record of the register save location to $fp+8. This causes us to fetch the wrong value for the return address, and then leads to the heuristic-fence-post warning. 2004-03-31 Joel Brobecker * alpha-tdep.c (alpha_heuristic_frame_unwind_cache): Do not take into account an instruction saving a register if we have already seen an earlier instruction saving that same register. Tested on alpha-tru64 5.1a, no regression. OK to apply? Thanks, -- Joel --AYsPlKobQGgtCvjI Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="alpha-tdep.c.diff" Content-length: 991 Index: alpha-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/alpha-tdep.c,v retrieving revision 1.128 diff -u -p -r1.128 alpha-tdep.c --- alpha-tdep.c 23 Mar 2004 14:47:54 -0000 1.128 +++ alpha-tdep.c 31 Mar 2004 23:58:36 -0000 @@ -1029,6 +1029,16 @@ alpha_heuristic_frame_unwind_cache (stru { reg = (word & 0x03e00000) >> 21; + /* Ignore this instruction if we have already encountered + an instruction saving the same register earlier in the + function code. The current instruction does not tell + us where the original value upon function entry is saved. + All it says is that the function we are scanning reused + that register for some computation of its own, and is now + saving its result. */ + if (info->saved_regs[reg]) + continue; + if (reg == 31) continue; --AYsPlKobQGgtCvjI--