This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [pushed] gdbserver: redo stepping over breakpoint that was on top of a permanent breakpoint




On 09/24/2015 06:43 AM, Yao Qi wrote:
Pedro Alves <palves@redhat.com> 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 = {<text variable, no debug info>} 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: [<all threads>]
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?


Indeed I have a fix for this see : https://sourceware.org/ml/gdb-patches/2015-09/msg00222.html

But I thought it would not trigger until conditional breakpoints are implemented thus I had not included it in this patchset.

Could you share how exactly you get GDBServer to insert an internal breakpoint, I'm unfamiliar with : "I force GDBserver to use thread event breakpoint" ?





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]