From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27254 invoked by alias); 19 Sep 2008 14:34:00 -0000 Received: (qmail 27239 invoked by uid 22791); 19 Sep 2008 14:33:58 -0000 X-Spam-Check-By: sourceware.org Received: from snape.ecoscentric.com (HELO snape.ecoscentric.com) (212.13.207.199) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 19 Sep 2008 14:33:04 +0000 Received: from localhost (snape.ecoscentric.com [127.0.0.1]) by snape.ecoscentric.com (Postfix) with ESMTP id 2AF27DCC249 for ; Fri, 19 Sep 2008 15:33:01 +0100 (BST) Received: from snape.ecoscentric.com ([127.0.0.1]) by localhost (snape.ecoscentric.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 0OGa-id-iNue; Fri, 19 Sep 2008 15:33:00 +0100 (BST) Message-ID: <48D3B81B.3000801@eCosCentric.com> Date: Fri, 19 Sep 2008 14:34:00 -0000 From: Jonathan Larmour User-Agent: Thunderbird 1.5.0.12 (X11/20070530) MIME-Version: 1.0 To: gdb@sourceware.org Subject: Broken prologue skipping with non-returning function OpenPGP: id=A5FB74E6 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2008-09/txt/msg00111.txt.bz2 It seems the prologue analysis on ARM, but very probably more generically, has problems if GCC is able to optimise away the prologue. I have an example of this using GCC 4.3.x at -O1 and above. Here's a testcase: #include const char *args; const char *saved1, *saved2; void foo(void) { if (args) { saved1=saved2=args; args=NULL; } for (;;) /* NOTHING */ ; } int main(int argc, char *argv[]) { args = argv[0]; foo(); return 0; } Compile with e.g.: arm-none-eabi-gcc --save-temps -g -O1 -c foo.c (and linked as per my OS runtime) The foo.s contains: foo: .LFB10: .file 1 "foo.c" .loc 1 6 0 @ Function supports interworking. @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. .loc 1 7 0 ldr r3, .L5 ldr r2, [r3, #0] cmp r2, #0 beq .L2 .loc 1 9 0 ldr r3, .L5+4 [snip] We end up with a .loc for both lines 6 and 7 with no intervening instructions. gdb's symtab.c:find_pc_sect_line() looks for when the pc changes to something different and thus ends up returning a symtab_and_line indicating that the line at that pc is at the 'if' and runs from the start of the function to the ldr after the .loc 1 9 0. Thus the outcome as a user if you set a breakpoint at foo, is that it ends up getting set *after* the conditional branch. Which means setting a breakpoint at foo is unreliable as you may never hit it. Bad GDB, no biscuit. But what is the fix? For a start, I envisage this will affect more than just ARM, so a fix in generic code should by rights be best, although OTOH some architectures can have calling conventions that guarantee the prologue is never empty. How about a patch like the following to the generic symtab.c? That way if there are two locs in succession for different lines at the same pc, we stop at the current loc, rather than a later one (after the pc actually changes). Note that a line of 0 seems to need ignoring as that seems do indicate the start of the function. --- symtab.c~ 2008-06-11 23:03:49.000000000 +0100 +++ symtab.c 2008-09-19 15:15:33.000000000 +0100 @@ -2264,7 +2264,7 @@ { /* Leave prev pointing to the linetable entry for the last line that started at or before PC. */ - if (item->pc > pc) + if (item->pc > pc || (prev && item->pc == pc && prev->pc == pc && prev->line > 0 && item->line > prev->line)) break; prev = item; I can't help but feel uneasy about the above change though, simply because this is quite an essential part of GDB and I'm concerned about unintended consequences. What do people think? Jifl -- eCosCentric Limited http://www.eCosCentric.com/ The eCos experts Barnwell House, Barnwell Drive, Cambridge, UK. Tel: +44 1223 245571 Registered in England and Wales: Reg No 4422071. ------["Si fractum non sit, noli id reficere"]------ Opinions==mine >>>> Visit us on stand 905 at the Embedded Systems Show 2008 <<<< >>>> Oct 1-2, NEC, Birmingham, UK http://www.embedded.co.uk <<<<