Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* Broken prologue skipping with non-returning function
@ 2008-09-19 14:34 Jonathan Larmour
  2008-09-19 15:00 ` Daniel Jacobowitz
  0 siblings, 1 reply; 6+ messages in thread
From: Jonathan Larmour @ 2008-09-19 14:34 UTC (permalink / raw)
  To: gdb

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 <stdio.h>
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  <<<<


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-09-22 15:05 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-19 14:34 Broken prologue skipping with non-returning function Jonathan Larmour
2008-09-19 15:00 ` Daniel Jacobowitz
2008-09-19 19:01   ` Jonathan Larmour
2008-09-19 19:14     ` Daniel Jacobowitz
2008-09-22 14:57     ` Daniel Jacobowitz
2008-09-22 15:05       ` Jonathan Larmour

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox