Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Joel Brobecker <brobecker@adacore.com>
To: gdb-patches@sources.redhat.com
Subject: [RFC] problem fetching inferior memory due to breakpoint
Date: Wed, 26 Apr 2006 19:05:00 -0000	[thread overview]
Message-ID: <20060426190517.GA930@adacore.com> (raw)

Hello,

This happens on Windows XP with the cygwin debugger. Consider the
following code:

        #include <stdio.h>
        
        void
        hello (void)
        {
          printf ("Hello world.\n");
        }
        
        int
        main (void)
        {
          hello ();
        
          return 0;
        }

Break at the first instruction of hello(), and then do a couple of
stepi's:

        (gdb) b *hello
        Breakpoint 1 at 0x401050: file foo.c, line 5.
        (gdb) run
        Starting program: /[...]/foo.exe 
        
        Breakpoint 1, hello () at foo.c:5
        5       {
        (gdb) stepi
        0x00401051      5       {
        (gdb) bt
        #0  0x00401051 in hello () at foo.c:5
        #1  0x00401093 in main () at foo.c:12
        (gdb) stepi
        0x00401053 in hello () at foo.c:5
        5       {

So we're at the third instruction of the function. Here is the backtrace
we get when I request it:

        (gdb) bt
        #0  0x00401053 in hello () at foo.c:5
        #1  0x0022ee88 in ?? ()
        #2  0x00401093 in main () at foo.c:12

We get an extra frame between hello() and main().

The reason for this is that the i386 code tries to scan the prologue
of hello during the step operation. So it tries reading the first few
bytes of the function, and hits a snag, because at the time when we do
the memory read, the breakpoint instruction is still inserted, and hence
we fail to recognize the prologue....

We actually scan the function prologue during the step operation as
opposed to during the "bt", because we need to determine where we are,
and that causes us to create the frame ID for frame 0, which means
scanning the function prologue (not actually verified, all from memory,
may be incorrect - but the fact is correct: we compute the frame ID
during the step).

I'm not exactly sure yet as to why we don't see this problem on x86-linux.
But all works fine there as far as I can tell.

I'm not entirely sure as to how to fix this problem. Since this problem
seems confined to win32, perhaps the fix should be in win32-nat.c, in
the xfer_memory routine, when I would then have to check for breakpoints.
Seems ok, except that I would then end up duplicating the logic of
deprecated_read_memory_nobpt.

I looked at the gdb-patches archives, and Andrew said at the time
that we should use get_frame_memory. The problem is that I don't see
how get_frame_memory() will help, since all it does is calling
read_memory(), which brings us back to our initial problem.

The simplest solution that seems to work is to modify read_memory to
use deprecated_read_memory_nobpt() instead of target_read_memory().
Seems a bit of a shame to check all breakpoints for each and every
memory read, though... But the overhead should be pretty negligible,
assuming that most sessions only have a few breakpoints, not millions of
them. Perhaps add a check for breakpoints inserted before doing the
breakpoints check.

Another solution would be have the win32 native code remove breakpoints
when handling all events, and then re-insert them as we resume execution.
Seems dangerous because we may miss some resume entry points.

We could apply this same later idea to the generic code instead of the
win32 code. Perhaps other targets are affected as well. But I suspect
that this would negatively impact certain targets that wouldn't need
this, especially remote targets with a slow communication link.

Any suggestions?

Thanks,
-- 
Joel


             reply	other threads:[~2006-04-26 19:05 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-04-26 19:05 Joel Brobecker [this message]
2006-04-26 19:19 ` Daniel Jacobowitz
2006-04-26 21:18   ` Joel Brobecker
2006-04-26 21:39     ` Daniel Jacobowitz
2006-04-26 22:18       ` Joel Brobecker
2006-04-26 22:29         ` Daniel Jacobowitz
2006-04-26 23:33           ` Michael Snyder
2006-04-27  0:42             ` Daniel Jacobowitz
2006-04-27  1:37               ` Michael Snyder
2006-04-27  2:10                 ` Daniel Jacobowitz
2006-04-27  0:53   ` Jim Blandy
2006-04-27 20:28 ` Eli Zaretskii
2006-04-27 20:56   ` Joel Brobecker
2006-04-28  5:12     ` Eli Zaretskii
2006-04-28 17:00       ` Joel Brobecker
2006-04-28 17:45         ` Daniel Jacobowitz
2006-04-29 14:14         ` Eli Zaretskii
2006-04-29 14:14         ` Eli Zaretskii
2006-04-29 14:20           ` Daniel Jacobowitz
2006-04-29 14:48             ` Eli Zaretskii
2006-04-29 15:06               ` Daniel Jacobowitz
2006-04-29 15:18                 ` Daniel Jacobowitz
2006-04-29 17:10                 ` Eli Zaretskii

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=20060426190517.GA930@adacore.com \
    --to=brobecker@adacore.com \
    --cc=gdb-patches@sources.redhat.com \
    /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