From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6286 invoked by alias); 10 May 2007 10:57:31 -0000 Received: (qmail 6267 invoked by uid 22791); 10 May 2007 10:57:29 -0000 X-Spam-Check-By: sourceware.org Received: from imx12.toshiba.co.jp (HELO imx12.toshiba.co.jp) (61.202.160.132) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 10 May 2007 10:57:22 +0000 Received: from wall11.toshiba.co.jp (wall11 [133.199.90.149]) by imx12.toshiba.co.jp with ESMTP id l4AAuXmj019494; Thu, 10 May 2007 19:56:33 +0900 (JST) Received: (from root@localhost) by wall11.toshiba.co.jp id l4AAuXEK002430; Thu, 10 May 2007 19:56:33 +0900 (JST) Received: from ovp11.toshiba.co.jp [133.199.90.148] by wall11.toshiba.co.jp with ESMTP id VAA02426; Thu, 10 May 2007 19:56:32 +0900 Received: from mx2.toshiba.co.jp (localhost [127.0.0.1]) by ovp11.toshiba.co.jp with ESMTP id l4AAuW9a014210; Thu, 10 May 2007 19:56:32 +0900 (JST) Received: from mx.tjsys.co.jp by toshiba.co.jp id l4AAuVUd021884; Thu, 10 May 2007 19:56:31 +0900 (JST) Received: from is-com10 (IDENT:U2FsdGVkX19iOYKnM6Q0wk3ph2XEIM4sY/Wc/2D8Rec@filtering.tjsys.co.jp [157.79.3.71]) by mx.tjsys.co.jp (8.12.11/8.12.11) with SMTP id l4AAuV8e018518; Thu, 10 May 2007 19:56:31 +0900 (JST) Received: from localhost ([157.79.51.61]) by ims.tjsys.co.jp (iPlanet Messaging Server 5.2 HotFix 2.10 (built Dec 26 2005)) with ESMTP id <0JHT001T0NQ4NR@ims.tjsys.co.jp>; Thu, 10 May 2007 19:56:28 +0900 (JST) Date: Thu, 10 May 2007 10:57:00 -0000 From: Emi SUZUKI Subject: Re: [RFC] "single step" atomic instruction sequences as a whole on PPC In-reply-to: <20070509183319.GA29991@host0.dyn.jankratochvil.net> To: jan.kratochvil@redhat.com Cc: luisgpm@linux.vnet.ibm.com, gdb-patches@sourceware.org Message-id: <20070510.195725.01365398.emi-suzuki@tjsys.co.jp> MIME-version: 1.0 X-Mailer: Mew version 5.2 on Emacs 22.0.90 / Mule 5.0 (SAKAKI) Content-type: Multipart/Mixed; boundary="--Next_Part(Thu_May_10_19_57_25_2007_577)--" Content-transfer-encoding: 7bit References: <20070509181206.GA6543@caradoc.them.org> <1178734875.4754.6.camel@localhost> <20070509183319.GA29991@host0.dyn.jankratochvil.net> X-WAuditID: 0705101956280000032080 X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-05/txt/msg00154.txt.bz2 ----Next_Part(Thu_May_10_19_57_25_2007_577)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-length: 4662 Hello Jan, From: Jan Kratochvil Subject: Re: [RFC] "single step" atomic instruction sequences as a whole on PPC Date: Wed, 09 May 2007 20:33:19 +0200 > please check the attached two testcases and run them at least 100x etc. > > Unfortunately the threaded one fails for me in some 7% of cases IMO due to > a race at the `infrun.c' line: > remove_status = remove_breakpoints (); I'm not sure, but I guess the issue you may see on your testcase resembles to the session log below: -- GNU gdb 6.6.50.20070510-cvs Copyright (C) 2007 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "powerpc64-linux"... Using host libthread_db library "/lib64/libthread_db.so.1". (gdb) tb 161 Breakpoint 1 at 0x10001230: file gdb/testsuite/gdb.threads/atomic-seq-threaded.c, line 161. (gdb) r Starting program: gdb/testsuite/gdb.threads/atomic-seq-threaded [Thread debugging using libthread_db enabled] [New Thread 4160631792 (LWP 11609)] [New Thread 4160627904 (LWP 11612)] [Switching to Thread 4160631792 (LWP 11609)] main (argc=1, argv=0xffe92484) at gdb/testsuite/gdb.threads/atomic-seq-threaded.c:161 161 assert (i == 0); /* _create_behind_ */ (gdb) b 167 Breakpoint 2 at 0x1000126c: file gdb/testsuite/gdb.threads/atomic-seq-threaded.c, line 167. (gdb) b 151 Breakpoint 3 at 0x100011d0: file gdb/testsuite/gdb.threads/atomic-seq-threaded.c, line 151. (gdb) b 133 Breakpoint 4 at 0x10001120: file gdb/testsuite/gdb.threads/atomic-seq-threaded.c, line 133. (gdb) set can-use-hw-watchpoints 0 (gdb) watch unused Watchpoint 5: unused (gdb) c Continuing. [Switching to Thread 4160627904 (LWP 11612)] Breakpoint 4, start1 (arg=0x0) at gdb/testsuite/gdb.threads/atomic-seq-threaded.c:133 133 return arg; /* _delete1_ */ (gdb) d Delete all breakpoints? (y or n) y (gdb) c Continuing. Program received signal SIGTRAP, Trace/breakpoint trap. [Switching to Thread 4160631792 (LWP 11609)] 0x0ff3b748 in __libc_enable_asynccancel () from /lib/libc.so.6 (gdb) disassemble 0x0ff3b734 0x0ff3b750 Dump of assembler code from 0xff3b734 to 0xff3b750: 0x0ff3b734 <__libc_enable_asynccancel+52>: addi r9,r11,100 0x0ff3b738 <__libc_enable_asynccancel+56>: lwarx r10,0,r9 0x0ff3b73c <__libc_enable_asynccancel+60>: cmpw r10,r3 0x0ff3b740 <__libc_enable_asynccancel+64>: bne- 0xff3b74c <__libc_enable_asynccancel+76> 0x0ff3b744 <__libc_enable_asynccancel+68>: stwcx. r0,0,r9 0x0ff3b748 <__libc_enable_asynccancel+72>: bne- 0xff3b738 <__libc_enable_asynccancel+56> 0x0ff3b74c <__libc_enable_asynccancel+76>: isync End of assembler dump. -- If it is, the line in `infrun.c' you have pointed is not the cause. But whether it is or not, I think there is an issue for handling multiple trap events while doing software single stepping. In the testcase, GDB always does hardware single stepping by setting a software watchpoint. And when a thread running through an atomic sequence of instruction, it will be done by software one. So, during one thread is running through an atomic sequence of instructions, GDB can detects multiple SIGTRAP events on the target process, as you have already known. When that multiple SIGTRAP events occured, GDB selects one event and cancels the other if the cause of SIGTRAP is a breakpoint hit, or just leave it pended. The procedure will be done by `cancel_breakpoints_callback' in linux-nat.c. And the pended events will be deteced and noticed when the next time the target resumes. The probrem is that GDB doesn't check if the breakpoint is inserted for software single stepping when cancelling the trap event: when the event occured by a software single step breakpoint is not selected, GDB would not cancel it but leave it pended. When the next time the target resumes, GDB restores the pended event. But if you have removed the watchpoint that the target get stopped by before resuming, GDB can never decide the cause of SIGTRAP anymore. The session log above shows the phenomenon. I attach the source code modified from yours, Jan, which is much easier to reproduce the issue on my environment. And I'm so sorry for not sending any patch for resolving it, for my copyright assignment to FSF is STILL NOT ready. And Luis, it's just FYI: 'Emi' is one of common female names in Japan :-) -- Emi SUZUKI / emi-suzuki at tjsys.co.jp ----Next_Part(Thu_May_10_19_57_25_2007_577)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="atomic-seq-threaded.c" Content-length: 4294 /* This testcase is part of GDB, the GNU debugger. Copyright 2007 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Test stepping over RISC atomic sequences. This variant testcases the code for stepping another thread while skipping over the atomic sequence in the former thread (STEPPING_PAST_SINGLESTEP_BREAKPOINT). Code comes from gcc/testsuite/gcc.dg/sync-2.c */ /* { dg-options "-march=i486" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ /* { dg-options "-mcpu=v9" { target sparc*-*-* } } */ /* Test functionality of the intrinsics for 'short' and 'char'. */ #include #include #include #include #include #define LOOPS 2 static int unused; static char AI[18]; static char init_qi[18] = { 3,5,7,9,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0 }; static char test_qi[18] = { 3,5,7,9,1,4,22,-12,7,8,9,7,1,-12,7,8,9,7 }; static void do_qi (void) { if (__sync_fetch_and_add(AI+4, 1) != 0) abort (); if (__sync_fetch_and_add(AI+5, 4) != 0) abort (); if (__sync_fetch_and_add(AI+6, 22) != 0) abort (); if (__sync_fetch_and_sub(AI+7, 12) != 0) abort (); if (__sync_fetch_and_and(AI+8, 7) != (char)-1) abort (); if (__sync_fetch_and_or(AI+9, 8) != 0) abort (); if (__sync_fetch_and_xor(AI+10, 9) != 0) abort (); if (__sync_fetch_and_nand(AI+11, 7) != 0) abort (); if (__sync_add_and_fetch(AI+12, 1) != 1) abort (); if (__sync_sub_and_fetch(AI+13, 12) != (char)-12) abort (); if (__sync_and_and_fetch(AI+14, 7) != 7) abort (); if (__sync_or_and_fetch(AI+15, 8) != 8) abort (); if (__sync_xor_and_fetch(AI+16, 9) != 9) abort (); if (__sync_nand_and_fetch(AI+17, 7) != 7) abort (); } static short AL[18]; static short init_hi[18] = { 3,5,7,9,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0 }; static short test_hi[18] = { 3,5,7,9,1,4,22,-12,7,8,9,7,1,-12,7,8,9,7 }; static void do_hi (void) { if (__sync_fetch_and_add(AL+4, 1) != 0) abort (); if (__sync_fetch_and_add(AL+5, 4) != 0) abort (); if (__sync_fetch_and_add(AL+6, 22) != 0) abort (); if (__sync_fetch_and_sub(AL+7, 12) != 0) abort (); if (__sync_fetch_and_and(AL+8, 7) != -1) abort (); if (__sync_fetch_and_or(AL+9, 8) != 0) abort (); if (__sync_fetch_and_xor(AL+10, 9) != 0) abort (); if (__sync_fetch_and_nand(AL+11, 7) != 0) abort (); if (__sync_add_and_fetch(AL+12, 1) != 1) abort (); if (__sync_sub_and_fetch(AL+13, 12) != -12) abort (); if (__sync_and_and_fetch(AL+14, 7) != 7) abort (); if (__sync_or_and_fetch(AL+15, 8) != 8) abort (); if (__sync_xor_and_fetch(AL+16, 9) != 9) abort (); if (__sync_nand_and_fetch(AL+17, 7) != 7) abort (); } static void * start1 (void *arg) { unsigned loop; sleep(1); for (loop = 0; loop < LOOPS; loop++) { memcpy(AI, init_qi, sizeof(init_qi)); do_qi (); if (memcmp (AI, test_qi, sizeof(test_qi))) abort (); } return arg; /* _delete1_ */ } static void * start2 (void *arg) { unsigned loop; for (loop = 0; loop < LOOPS; loop++) { memcpy(AL, init_hi, sizeof(init_hi)); do_hi (); if (memcmp (AL, test_hi, sizeof(test_hi))) abort (); } return arg; /* _delete2_ */ } int main (int argc, char **argv) { pthread_t thread; int i; i = pthread_create (&thread, NULL, start1, NULL); /* _create_ */ assert (i == 0); /* _create_behind_ */ sleep(1); start2 (NULL); i = pthread_join (thread, NULL); /* _delete_ */ assert (i == 0); return 0; /* _success_ */ } ----Next_Part(Thu_May_10_19_57_25_2007_577)----