From patchwork Thu Sep 24 10:43:13 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 8836 Received: (qmail 78916 invoked by alias); 24 Sep 2015 10:43:25 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 78902 invoked by uid 89); 24 Sep 2015 10:43:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f52.google.com Received: from mail-pa0-f52.google.com (HELO mail-pa0-f52.google.com) (209.85.220.52) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 24 Sep 2015 10:43:22 +0000 Received: by pacfv12 with SMTP id fv12so71020975pac.2 for ; Thu, 24 Sep 2015 03:43:20 -0700 (PDT) X-Received: by 10.68.68.233 with SMTP id z9mr43832152pbt.132.1443091400668; Thu, 24 Sep 2015 03:43:20 -0700 (PDT) Received: from E107787-LIN (power-aix.osuosl.org. [140.211.15.154]) by smtp.gmail.com with ESMTPSA id li11sm12985633pab.43.2015.09.24.03.43.17 (version=TLS1_2 cipher=AES128-SHA256 bits=128/128); Thu, 24 Sep 2015 03:43:20 -0700 (PDT) From: Yao Qi To: Pedro Alves Cc: gdb-patches@sourceware.org Subject: Re: [pushed] gdbserver: redo stepping over breakpoint that was on top of a permanent breakpoint References: <1424723261-15719-1-git-send-email-palves@redhat.com> Date: Thu, 24 Sep 2015 11:43:13 +0100 Message-ID: <861tdo9jy6.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 X-IsSubscribed: yes Pedro Alves writes: Hi Pedro, when I play with Antoine's patch series, [PATCH 0/5] Software breakpoints support for ARM linux. https://sourceware.org/ml/gdb-patches/2015-09/msg00448.html I force GDBserver to use thread event breakpoint in order to exercise Antoine's patch series. Something strange leads me to this patch.... > + /* If step-over executes a breakpoint instruction, it means a > + gdb/gdbserver breakpoint had been planted on top of a permanent > + breakpoint. The PC has been adjusted by > + check_stopped_by_breakpoint to point at the breakpoint address. > + Advance the PC manually past the breakpoint, otherwise the > + program would keep trapping the permanent breakpoint forever. */ > + if (!ptid_equal (step_over_bkpt, null_ptid) > + && event_child->stop_reason == LWP_STOPPED_BY_SW_BREAKPOINT) > + { The code was added to handle permanent breakpoint, but the condition can also be true when GDBserver steps over breakpoint by software single step (through breakpoint_reinsert_addr), and the following the code increase the PC, and as a result, one instruction is not executed, as shown below, > + unsigned int increment_pc; > + > + if (the_low_target.breakpoint_len > the_low_target.decr_pc_after_break) > + increment_pc = the_low_target.breakpoint_len; > + else > + increment_pc = the_low_target.decr_pc_after_break; > + the program gets SIGSEGV after calling __nptl_create_event, Breakpoint 1, main () at /home/yao/SourceCode/gnu/gdb/git/gdb/testsuite/gdb.threads/tls.c:231 231 do_pass (); (gdb) c Continuing. [New Thread 16290] Program received signal SIGSEGV, Segmentation fault. 0xb6fcb6d2 in create_thread (stackaddr=0xb6daff80, attr=0xbefff580, pd=0xb6db0440) at ../nptl/sysdeps/pthread/createthread.c:223 223 ../nptl/sysdeps/pthread/createthread.c: No such file or directory. (gdb) disassemble 0xb6fcb6c0,+20 Dump of assembler code from 0xb6fcb6c0 to 0xb6fcb6d4: 0xb6fcb6c0 <__pthread_create_2_1+1160>: ldrh r7, [r3, #58] ; 0x3a 0xb6fcb6c2 <__pthread_create_2_1+1162>: bne.n 0xb6fcb6a2 <__pthread_create_2_1+1130> 0xb6fcb6c4 <__pthread_create_2_1+1164>: bl 0xb6fca124 <__GI___nptl_create_event> 0xb6fcb6c8 <__pthread_create_2_1+1168>: add.w r0, r4, #532 ; 0x214 0xb6fcb6cc <__pthread_create_2_1+1172>: movs r2, #0 0xb6fcb6ce <__pthread_create_2_1+1174>: dmb sy => 0xb6fcb6d2 <__pthread_create_2_1+1178>: ldrex r3, [r0] (gdb) p __nptl_create_event $1 = {} 0xb6fca124 <__GI___nptl_create_event> in GDBserver, we can see the debug log, stop pc is b6fca124 [1] program hits the GDBserver brekapoint on __nptl_create_event pc is 0xb6fca124 Writing 7047 to 0xb6fca124 in process 16289 Could not find fast tracepoint jump at 0xb6fca124 in list (uninserting). Writing f0f700a0 to 0xb6fcb6c8 in process 16289 [2] GDBservers sets software breakpoint on the instruction after bl __nptl_create_event. Resuming lwp 16289 (continue, signal 0, stop not expected) pending reinsert at 0xb6fca124 stop pc is b6fca124 continue from pc 0xb6fca124 >>>> entering linux_wait_1 sigchld_handler linux_wait_1: [] step_over_bkpt set [LWP 16289.16289], doing a blocking wait my_waitpid (-1, 0x40000001) my_waitpid (-1, 0x1): status(57f), 16289 LWFE: waitpid(-1, ...) returned 16289, ERRNO-OK LLW: waitpid 16289 received Trace/breakpoint trap (stopped) stop pc is b6fcb6c8 pc is 0xb6fcb6c8 CSBB: LWP 16289.16289 stopped by software breakpoint [3] program hits the single step software breakpoint, my_waitpid (-1, 0x40000001) my_waitpid (-1, 0x80000001): status(ffffffff), 0 LWFE: waitpid(-1, ...) returned 0, ERRNO-OK stop pc is b6fcb6c8 pc is 0xb6fcb6c8 step-over for LWP 16289.16289 executed software breakpoint Finished step over. Writing 01de to 0xb6fca124 in process 16289 Could not find fast tracepoint jump at 0xb6fca124 in list (reinserting). Writing 04f50570 to 0xb6fcb6c8 in process 16289 Step-over finished. proceeding all threads. Need step over [LWP 16289]? No stop pc is b6fcb6cc pc is 0xb6fcb6cc [4] pc is incremented by 4, which means instruction on 0xb6fcb6c8 is not executed. I am not very sure what the right fix should be, but looks we need to check whether there is a breakpoint installed on event_child-stop_pc, something like this patch below, what do you think? diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 8e8b7c0..9fb83a8 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -3010,7 +3010,8 @@ linux_wait_1 (ptid_t ptid, Advance the PC manually past the breakpoint, otherwise the program would keep trapping the permanent breakpoint forever. */ if (!ptid_equal (step_over_bkpt, null_ptid) - && event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT) + && event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT + && gdb_breakpoint_here (event_child->stop_pc)) { int increment_pc = 0; CORE_ADDR stop_pc = event_child->stop_pc;