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?