From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8486 invoked by alias); 29 May 2003 15:44:18 -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 8450 invoked from network); 29 May 2003 15:44:16 -0000 Received: from unknown (HELO walton.kettenis.dyndns.org) (62.163.169.212) by sources.redhat.com with SMTP; 29 May 2003 15:44:16 -0000 Received: from elgar.kettenis.dyndns.org (elgar.kettenis.dyndns.org [192.168.0.2]) by walton.kettenis.dyndns.org (8.12.6p2/8.12.5) with ESMTP id h4TFi8k9002742; Thu, 29 May 2003 17:44:08 +0200 (CEST) (envelope-from kettenis@elgar.kettenis.dyndns.org) Received: from elgar.kettenis.dyndns.org (localhost [127.0.0.1]) by elgar.kettenis.dyndns.org (8.12.6p2/8.12.6) with ESMTP id h4TFi8Zt031835; Thu, 29 May 2003 17:44:08 +0200 (CEST) (envelope-from kettenis@elgar.kettenis.dyndns.org) Received: (from kettenis@localhost) by elgar.kettenis.dyndns.org (8.12.6p2/8.12.6/Submit) id h4TFi7aL031832; Thu, 29 May 2003 17:44:07 +0200 (CEST) Date: Thu, 29 May 2003 15:44:00 -0000 Message-Id: <200305291544.h4TFi7aL031832@elgar.kettenis.dyndns.org> From: Mark Kettenis To: mludvig@suse.cz, ac131313@redhat.com CC: gdb@sources.redhat.com In-reply-to: <3ED381CB.5050207@suse.cz> (message from Michal Ludvig on Tue, 27 May 2003 17:18:35 +0200) Subject: Re: dwarf-frame.c question References: <3ED381CB.5050207@suse.cz> X-SW-Source: 2003-05/txt/msg00389.txt.bz2 Date: Tue, 27 May 2003 17:18:35 +0200 From: Michal Ludvig Hi Mark, why do you decrement unwound PC in dwarf_frame_cache() before using it? The unwound PC is the return address, i.e. the instruction that will be executed when the function returns. This is the instruction after the call instruction. The problem is that if the call instruction is the last instruction of a function, the return address might point to the next function: foo: ... call abort bar: push %ebp mov %esp, %ebp ... That's why the GCC unwinder does the same thing. Note that the decrementing the PC is wrong for "interrupt frames", which is why the if-statement is there in the code fragment you cite: dwarf-frame.c: 478 /* Unwind the PC. */ 479 fs->pc = frame_pc_unwind (next_frame); 480 if (get_frame_type (next_frame) == NORMAL_FRAME 481 && frame_relative_level (next_frame) >= 0) 482 fs->pc--; This makes a problem for a signal trampoline. If it is sitting on addresses say 0x40000140-0x40000150, the return address from signal handler is 0x40000140, but dwarf_frame_cache() says it is 0x4000013f and couldn't find it's CFI... Do you have signal trampolnes with CFI? If the CFI is hand-generated, you should probably "cheat" by adding a nop before the trampoline and include it in the address range of the FDE (see the arch/i386/kernel/vsyscall-sigreturn.S in the Linux kernel sources). This has a tragic consequence few lines below were you look for FDE but don't check if you find one. If you don't, line 488 segfaults. 484 /* Find the correct FDE. */ 485 fde = dwarf_frame_find_fde (&fs->pc); Hmm, a gdb_assert() is in order here. 487 /* Extract any interesting information from the CIE. */ 488 fs->data_align = fde->cie->data_alignment_factor; 489 fs->code_align = fde->cie->code_alignment_factor; 490 fs->retaddr_column = fde->cie->return_address_register; The problem is, that dwarf_frame_p() looks for the real return address and says that there is a debug info and sets unwinder to use dwarf2 methods for this farme. Hmm, it should do something similar as dwarf_frame_cache(). But the in unwinder itself in dwarf_frame_cache() looks for the decreased one and of course doesn't find it. That defenitely is a bug. It isn't immediately obvious to me how to solve this :-(. Andrew, it seems that we should tweak the frame code to make sure that frame_unwind_by_pc is always passed a PC *within* the function. Mark