From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12233 invoked by alias); 26 Apr 2006 19:05:31 -0000 Received: (qmail 12224 invoked by uid 22791); 26 Apr 2006 19:05:31 -0000 X-Spam-Check-By: sourceware.org Received: from nile.gnat.com (HELO nile.gnat.com) (205.232.38.5) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 26 Apr 2006 19:05:28 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-nile.gnat.com (Postfix) with ESMTP id 35D9748CFF9 for ; Wed, 26 Apr 2006 15:05:26 -0400 (EDT) Received: from nile.gnat.com ([127.0.0.1]) by localhost (nile.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 25948-01-5 for ; Wed, 26 Apr 2006 15:05:26 -0400 (EDT) Received: from takamaka.act-europe.fr (s142-179-108-108.bc.hsia.telus.net [142.179.108.108]) by nile.gnat.com (Postfix) with ESMTP id CD5B548CFF7 for ; Wed, 26 Apr 2006 15:05:23 -0400 (EDT) Received: by takamaka.act-europe.fr (Postfix, from userid 507) id F3A8747E7F; Wed, 26 Apr 2006 12:05:17 -0700 (PDT) Date: Wed, 26 Apr 2006 19:05:00 -0000 From: Joel Brobecker To: gdb-patches@sources.redhat.com Subject: [RFC] problem fetching inferior memory due to breakpoint Message-ID: <20060426190517.GA930@adacore.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4i Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-04/txt/msg00345.txt.bz2 Hello, This happens on Windows XP with the cygwin debugger. Consider the following code: #include 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