* [pushed] gdbserver: redo stepping over breakpoint that was on top of a permanent breakpoint
@ 2015-02-23 20:27 Pedro Alves
2015-02-24 12:25 ` Yao Qi
2015-09-24 10:43 ` Yao Qi
0 siblings, 2 replies; 7+ messages in thread
From: Pedro Alves @ 2015-02-23 20:27 UTC (permalink / raw)
To: gdb-patches
I'm going to add an alternate mechanism of breakpoint trap
identification to 'check_stopped_by_breakpoint' that does not rely on
checking the instruction at PC. The mechanism currently used to tell
whether we're stepping over a permanent breakpoint doesn't fit in that
new method. This patch redoes the whole logic in a different way that
works with both old and new methods, in essence moving the "stepped
permanent breakpoint" detection "one level up". It makes lower level
check_stopped_by_breakpoint always the adjust the PC, and then has
linux_wait_1 advance the PC past the breakpoint if necessary. This
ends up being better also because this now handles
non-decr_pc_after_break targets too. Before, such targets would get
stuck forever reexecuting the breakpoint instruction.
Tested on x86_64 Fedora 20.
gdb/gdbserver/ChangeLog:
2015-02-23 Pedro Alves <palves@redhat.com>
* linux-low.c (check_stopped_by_breakpoint): Don't check if the
thread was doing a step-over; always adjust the PC if
we stepped over a permanent breakpoint.
(linux_wait_1): If we stepped over breakpoint that was on top of a
permanent breakpoint, manually advance the PC past it.
---
gdb/gdbserver/ChangeLog | 8 ++++++++
gdb/gdbserver/linux-low.c | 45 +++++++++++++++++++++++++++++++++++++--------
2 files changed, 45 insertions(+), 8 deletions(-)
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index d724e6c..a130aab 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,13 @@
2015-02-23 Pedro Alves <palves@redhat.com>
+ * linux-low.c (check_stopped_by_breakpoint): Don't check if the
+ thread was doing a step-over; always adjust the PC if
+ we stepped over a permanent breakpoint.
+ (linux_wait_1): If we stepped over breakpoint that was on top of a
+ permanent breakpoint, manually advance the PC past it.
+
+2015-02-23 Pedro Alves <palves@redhat.com>
+
* linux-x86-low.c (REGSIZE): Define in both 32-bit and 64-bit
modes.
(x86_fill_gregset, x86_store_gregset): Use it when handling
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index a6e1e3d..1c66985 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -507,14 +507,8 @@ check_stopped_by_breakpoint (struct lwp_info *lwp)
/* We may have just stepped a breakpoint instruction. E.g., in
non-stop mode, GDB first tells the thread A to step a range, and
then the user inserts a breakpoint inside the range. In that
- case, we need to report the breakpoint PC. But, when we're
- trying to step past one of our own breakpoints, that happens to
- have been placed on top of a permanent breakpoint instruction, we
- shouldn't adjust the PC, otherwise the program would keep
- trapping the permanent breakpoint forever. */
- if ((!lwp->stepping
- || (!ptid_equal (ptid_of (current_thread), step_over_bkpt)
- && lwp->stop_pc == sw_breakpoint_pc))
+ case we need to report the breakpoint PC. */
+ if ((!lwp->stepping || lwp->stop_pc == sw_breakpoint_pc)
&& (*the_low_target.breakpoint_at) (sw_breakpoint_pc))
{
if (debug_threads)
@@ -2552,6 +2546,41 @@ linux_wait_1 (ptid_t ptid,
return ptid_of (current_thread);
}
+ /* 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)
+ {
+ 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;
+
+ if (debug_threads)
+ {
+ debug_printf ("step-over for %s executed software breakpoint\n",
+ target_pid_to_str (ptid_of (current_thread)));
+ }
+
+ if (increment_pc != 0)
+ {
+ struct regcache *regcache
+ = get_thread_regcache (current_thread, 1);
+
+ event_child->stop_pc += increment_pc;
+ (*the_low_target.set_pc) (regcache, event_child->stop_pc);
+
+ if (!(*the_low_target.breakpoint_at) (event_child->stop_pc))
+ event_child->stop_reason = LWP_STOPPED_BY_NO_REASON;
+ }
+ }
+
/* If this event was not handled before, and is not a SIGTRAP, we
report it. SIGILL and SIGSEGV are also treated as traps in case
a breakpoint is inserted at the current PC. If this target does
--
1.9.3
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [pushed] gdbserver: redo stepping over breakpoint that was on top of a permanent breakpoint
2015-02-23 20:27 [pushed] gdbserver: redo stepping over breakpoint that was on top of a permanent breakpoint Pedro Alves
@ 2015-02-24 12:25 ` Yao Qi
2015-02-26 19:01 ` Pedro Alves
2015-09-24 10:43 ` Yao Qi
1 sibling, 1 reply; 7+ messages in thread
From: Yao Qi @ 2015-02-24 12:25 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
Pedro Alves <palves@redhat.com> writes:
> + 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;
AFAICS, the_low_target.breakpoint_len is greater or equal to
the_low_target.decr_pc_after_break. Why don't we use .breakpoint_len
instead? The code is correct, however, the comparison here leads me to
think under what situation .breakpoint_len is less than .decr_pc_after_break.
--
Yao (齐尧)
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [pushed] gdbserver: redo stepping over breakpoint that was on top of a permanent breakpoint
2015-02-24 12:25 ` Yao Qi
@ 2015-02-26 19:01 ` Pedro Alves
0 siblings, 0 replies; 7+ messages in thread
From: Pedro Alves @ 2015-02-26 19:01 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 02/24/2015 12:25 PM, Yao Qi wrote:
> Pedro Alves <palves@redhat.com> writes:
>
>> + 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;
>
> AFAICS, the_low_target.breakpoint_len is greater or equal to
> the_low_target.decr_pc_after_break. Why don't we use .breakpoint_len
> instead? The code is correct, however, the comparison here leads me to
> think under what situation .breakpoint_len is less than .decr_pc_after_break.
Good point. The history is that I started out by always incrementing
by decr_pc_after_break. Later, I recalled that that's not always
the same as breakpoint length, and thinking that maybe archs that
set decr_pc_after_break may not set breakpoint_len, wrote
"increment = max (decr_pc_after_break, breakpoint_len);". That didn't
work (we don't define max anywhere), so I expanded that into the "if",
and never thought about it again. :-) It's hard to tell whether
there are such ports, but likely not. If there are, bp-permanent.exp
should catch them failing, I think. :-) So I went ahead and pushed
the patch below.
Thanks.
---
[PATCH] gdbserver/Linux: Simplify stepping past program breakpoint a
little
.decr_pc_after_break is never higher than .breakpoint_len, so use
.breakpoint_len directly. Based on idea from Yao here:
https://sourceware.org/ml/gdb-patches/2015-02/msg00689.html
gdb/gdbserver/ChangeLog:
2015-02-26 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_wait_1): When incrementing the PC past a
program breakpoint always use the_low_target.breakpoint_len as
increment, rather than the maximum between that and
the_low_target.decr_pc_after_break.
---
gdb/gdbserver/ChangeLog | 7 +++++++
gdb/gdbserver/linux-low.c | 7 +------
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index a130aab..6bb8950 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,10 @@
+2015-02-26 Pedro Alves <palves@redhat.com>
+
+ * linux-low.c (linux_wait_1): When incrementing the PC past a
+ program breakpoint always use the_low_target.breakpoint_len as
+ increment, rather than the maximum between that and
+ the_low_target.decr_pc_after_break.
+
2015-02-23 Pedro Alves <palves@redhat.com>
* linux-low.c (check_stopped_by_breakpoint): Don't check if the
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 1c66985..c0d3b0d 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -2555,12 +2555,7 @@ linux_wait_1 (ptid_t ptid,
if (!ptid_equal (step_over_bkpt, null_ptid)
&& event_child->stop_reason == LWP_STOPPED_BY_SW_BREAKPOINT)
{
- 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;
+ unsigned int increment_pc = the_low_target.breakpoint_len;
if (debug_threads)
{
--
1.9.3
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [pushed] gdbserver: redo stepping over breakpoint that was on top of a permanent breakpoint
2015-02-23 20:27 [pushed] gdbserver: redo stepping over breakpoint that was on top of a permanent breakpoint Pedro Alves
2015-02-24 12:25 ` Yao Qi
@ 2015-09-24 10:43 ` Yao Qi
2015-09-24 11:39 ` Antoine Tremblay
1 sibling, 1 reply; 7+ messages in thread
From: Yao Qi @ 2015-09-24 10:43 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
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?
--
Yao (齐尧)
Subject: [PATCH] Step-over breakpoint by software single step
gdb/gdbserver:
2015-09-24 Yao Qi <yao.qi@linaro.org>
* linux-low.c (linux_wait_1): Call gdb_breakpoint_here.
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;
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [pushed] gdbserver: redo stepping over breakpoint that was on top of a permanent breakpoint
2015-09-24 10:43 ` Yao Qi
@ 2015-09-24 11:39 ` Antoine Tremblay
2015-09-24 13:21 ` Yao Qi
0 siblings, 1 reply; 7+ messages in thread
From: Antoine Tremblay @ 2015-09-24 11:39 UTC (permalink / raw)
To: gdb-patches
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" ?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [pushed] gdbserver: redo stepping over breakpoint that was on top of a permanent breakpoint
2015-09-24 11:39 ` Antoine Tremblay
@ 2015-09-24 13:21 ` Yao Qi
2015-09-24 16:43 ` Antoine Tremblay
0 siblings, 1 reply; 7+ messages in thread
From: Yao Qi @ 2015-09-24 13:21 UTC (permalink / raw)
To: Antoine Tremblay; +Cc: gdb-patches
Antoine Tremblay <antoine.tremblay@ericsson.com> writes:
> Indeed I have a fix for this see :
> https://sourceware.org/ml/gdb-patches/2015-09/msg00222.html
>
Ah, I did read your patch, but I forget it when I am fixing this problem.
> 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" ?
It can be triggered when GDBserver steps over its breakpoints, what I
did is to pass 1 to thread_db_init, so that GDBserver will insert
breakpoint on __nptl_create_event. Once a new thread is created, and
hits this breakpoint, GDBserver will step over this breakpoint.
--
Yao (齐尧)
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 9fb83a8..0d88694 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -5501,7 +5501,7 @@ linux_look_up_symbols (void)
/* If the kernel supports tracing clones, then we don't need to
use the magic thread event breakpoint to learn about
threads. */
- thread_db_init (!linux_supports_traceclone ());
+ thread_db_init (1/*!linux_supports_traceclone ()*/);
#endif
}
diff --git a/gdb/remote.c b/gdb/remote.c
index b9dc4af..f1dec19 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -4157,6 +4157,13 @@ remote_check_symbols (void)
sym_addr,
¤t_target);
+ /* Hack for arm gdbserver when the thread library is compiled in
+ thumb mode. Set the LSB of address of __nptl_create_event so
+ that GDBserver can choose the right breakpoint instruction to
+ set on it. */
+ if (strcmp ("__nptl_create_event", msg) == 0)
+ sym_addr |= 1;
+
xsnprintf (msg, get_remote_packet_size (), "qSymbol:%s:%s",
phex_nz (sym_addr, addr_size), &reply[8]);
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [pushed] gdbserver: redo stepping over breakpoint that was on top of a permanent breakpoint
2015-09-24 13:21 ` Yao Qi
@ 2015-09-24 16:43 ` Antoine Tremblay
0 siblings, 0 replies; 7+ messages in thread
From: Antoine Tremblay @ 2015-09-24 16:43 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 09/24/2015 09:21 AM, Yao Qi wrote:
> Antoine Tremblay <antoine.tremblay@ericsson.com> writes:
>
>> Indeed I have a fix for this see :
>> https://sourceware.org/ml/gdb-patches/2015-09/msg00222.html
>>
>
> Ah, I did read your patch, but I forget it when I am fixing this problem.
>
Np, I think that patch is valid with the scenario you mention below,
however since it won't work properly as reinsert_addr doesn't work at
this stage I think it may be better to introduce it when I post the
single stepping support ?
> It can be triggered when GDBserver steps over its breakpoints, what I
> did is to pass 1 to thread_db_init, so that GDBserver will insert
> breakpoint on __nptl_create_event. Once a new thread is created, and
> hits this breakpoint, GDBserver will step over this breakpoint.
>
Haa I had missed that scenario!
>--- 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;
This won't work as that single step breakpoint is not a gdb breakpoint
we need to check for a reinsert breakpoint like the patch I mentioned.
I tested the scenario with my patch and the issue is solved.
Note however I'm a bit concerted about the hack to remote_check_symbols.
I need to dig into it to understand that one should we expect it to
work without this hack ?
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2015-09-24 16:43 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-23 20:27 [pushed] gdbserver: redo stepping over breakpoint that was on top of a permanent breakpoint Pedro Alves
2015-02-24 12:25 ` Yao Qi
2015-02-26 19:01 ` Pedro Alves
2015-09-24 10:43 ` Yao Qi
2015-09-24 11:39 ` Antoine Tremblay
2015-09-24 13:21 ` Yao Qi
2015-09-24 16:43 ` Antoine Tremblay
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox