From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25455 invoked by alias); 16 Mar 2009 17:41:21 -0000 Received: (qmail 25445 invoked by uid 22791); 16 Mar 2009 17:41:19 -0000 X-SWARE-Spam-Status: No, hits=-3.1 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from main.gmane.org (HELO ciao.gmane.org) (80.91.229.2) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 16 Mar 2009 17:41:10 +0000 Received: from list by ciao.gmane.org with local (Exim 4.43) id 1LjGoD-0007E1-HN for gdb@sources.redhat.com; Mon, 16 Mar 2009 17:41:05 +0000 Received: from enigma.qnx.com ([209.226.137.106]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Mon, 16 Mar 2009 17:41:05 +0000 Received: from aristovski by enigma.qnx.com with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Mon, 16 Mar 2009 17:41:05 +0000 To: gdb@sources.redhat.com From: Aleksandar Ristovski Subject: [RFC] stepping over permanent breakpoint Date: Mon, 16 Mar 2009 17:41:00 -0000 Message-ID: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------050709000105040609010703" User-Agent: Thunderbird 2.0.0.19 (Windows/20081209) X-IsSubscribed: yes 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: 2009-03/txt/msg00087.txt.bz2 This is a multi-part message in MIME format. --------------050709000105040609010703 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1348 Hello, When there is a hard-coded breakpoint in code, like in this example (for x86): #include int main() { __asm(" int $0x03\n"); printf("Hello World\n"); return 0; } gdb on linux will appear to work correctly. However, on systems that do not need pc adjustment after break (like QNX) gdb will not be able to step over that breakpoint unless user explicitly sets a breakpoint on top of it. I think that in case of linux it is actually working by accident - because kernel does not back-up instruction pointer after hard-coded breakpoint instruction was executed. Gdb will receive SIGTRAP but will not really know why. Attached patch fixes this for systems where gdbarch_decr_pc_after_break (gdbarch) == 0 I am still not sure this is the final fix. Wouldn't it be better if we recognized a hard-coded breakpoint as a breakpoint? There would be an issue since it is not in the breakpoint list, but maybe we should either automatically add it when we encounter it, or perhaps print with some "special" number (to make it clear to the user it is not one of the user-generated breakpoints). Thanks, Aleksandar Ristovski QNX Software Systems ChangeLog for your reference: * infrun.c (adjust_pc_after_break): On systems with adjusted PC after break, make sure hard-coded breakpoint is stepped-over. --------------050709000105040609010703 Content-Type: text/x-patch; name="infrun.c-adjust_pc_after_break-permanent-breakpoints-20090316.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename*0="infrun.c-adjust_pc_after_break-permanent-breakpoints-2009031"; filename*1="6.diff" Content-length: 1309 Index: gdb/infrun.c =================================================================== RCS file: /cvs/src/src/gdb/infrun.c,v retrieving revision 1.361 diff -u -p -r1.361 infrun.c --- gdb/infrun.c 1 Mar 2009 23:18:36 -0000 1.361 +++ gdb/infrun.c 16 Mar 2009 17:33:22 -0000 @@ -2089,14 +2089,29 @@ adjust_pc_after_break (struct execution_ we have nothing to do. */ regcache = get_thread_regcache (ecs->ptid); gdbarch = get_regcache_arch (regcache); - if (gdbarch_decr_pc_after_break (gdbarch) == 0) - return; /* Find the location where (if we've hit a breakpoint) the breakpoint would be. */ breakpoint_pc = regcache_read_pc (regcache) - gdbarch_decr_pc_after_break (gdbarch); + if (gdbarch_decr_pc_after_break (gdbarch) == 0) + { + /* Check if we have stopped at a permanent breakpoint. */ + int len; + const gdb_byte *brk; + gdb_byte *target_mem = alloca(32); + + brk = gdbarch_breakpoint_from_pc (gdbarch, &breakpoint_pc, &len); + if (!target_read_memory (breakpoint_pc, target_mem, len) + && memcmp (target_mem, brk, len) == 0) + { + breakpoint_pc += len; + regcache_write_pc (regcache, breakpoint_pc); + } + return; + } + /* Check whether there actually is a software breakpoint inserted at that location. --------------050709000105040609010703--