Mirror of the gdb mailing list
 help / color / mirror / Atom feed
From: Jonathan Larmour <jifl@eCosCentric.com>
To: gdb@sourceware.org
Subject: Broken prologue skipping with non-returning function
Date: Fri, 19 Sep 2008 14:34:00 -0000	[thread overview]
Message-ID: <48D3B81B.3000801@eCosCentric.com> (raw)

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  <<<<


             reply	other threads:[~2008-09-19 14:34 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-19 14:34 Jonathan Larmour [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48D3B81B.3000801@eCosCentric.com \
    --to=jifl@ecoscentric.com \
    --cc=gdb@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox