aboutsummaryrefslogtreecommitdiff
path: root/gdb/infrun.c
diff options
context:
space:
mode:
authorYao Qi <yao.qi@linaro.org>2016-04-25 09:16:21 +0100
committerYao Qi <yao.qi@linaro.org>2016-04-25 09:16:21 +0100
commit21edc42f4e1ec6fe8cfce171232bab27ad4af372 (patch)
treee78cffc7c9c92a0492e51e2d0b9b989518ed4e39 /gdb/infrun.c
parent101ae4cd3167bcb6fa1becee4f0c3ad1ffc41f15 (diff)
downloadgdb-21edc42f4e1ec6fe8cfce171232bab27ad4af372.zip
gdb-21edc42f4e1ec6fe8cfce171232bab27ad4af372.tar.gz
gdb-21edc42f4e1ec6fe8cfce171232bab27ad4af372.tar.bz2
Force to insert software single step breakpoint
GDB doesn't insert software single step breakpoint if the instruction branches to itself, so that the program can't stop after command "si". (gdb) b 32 Breakpoint 2 at 0x8680: file git/gdb/testsuite/gdb.base/branch-to-self.c, line 32. (gdb) c Continuing. Breakpoint 2, main () at gdb/git/gdb/testsuite/gdb.base/branch-to-self.c:32 32 asm (".Lhere: " BRANCH_INSN " .Lhere"); /* loop-line */ (gdb) si infrun: clear_proceed_status_thread (Thread 3991.3991) infrun: proceed (addr=0xffffffff, signal=GDB_SIGNAL_DEFAULT) infrun: step-over queue now empty infrun: resuming [Thread 3991.3991] for step-over infrun: skipping breakpoint: stepping past insn at: 0x8680 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Sending packet: $Z0,8678,4#f3...Packet received: OK infrun: skipping breakpoint: stepping past insn at: 0x8680 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Sending packet: $Z0,b6fe86c8,4#82...Packet received: OK infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=1, current thread [Thread 3991.3991] at 0x868 breakpoint.c:should_be_inserted thinks the breakpoint shouldn't be inserted, which is wrong. This patch restrict the condition that only skip the non-single-step breakpoints if they are inserted at the place we are stepping over, however we don't want to skip single-step breakpoint if its thread is the thread we are stepping over, so in this patch, I add a thread num in 'struct step_over_info' to record the thread we're stepping over. gdb: 2016-04-25 Yao Qi <yao.qi@linaro.org> * breakpoint.c (should_be_inserted): Return 0 if the location's owner is not single step breakpoint or single step breakpoint's thread isn't the thread which is stepping past a breakpoint. * gdbarch.sh (software_single_step): Update comments. * gdbarch.h: Regenerated. * infrun.c (struct step_over_info) <thread>: New field. (set_step_over_info): New argument 'thread'. Callers updated. (clear_step_over_info): Set field thread to -1. (thread_is_stepping_over_breakpoint): New function. * infrun.h (thread_is_stepping_over_breakpoint): Declaration.
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r--gdb/infrun.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 696105d..cfb1d06 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -1296,6 +1296,9 @@ struct step_over_info
/* The instruction being stepped over triggers a nonsteppable
watchpoint. If true, we'll skip inserting watchpoints. */
int nonsteppable_watchpoint_p;
+
+ /* The thread's global number. */
+ int thread;
};
/* The step-over info of the location that is being stepped over.
@@ -1329,11 +1332,13 @@ static struct step_over_info step_over_info;
static void
set_step_over_info (struct address_space *aspace, CORE_ADDR address,
- int nonsteppable_watchpoint_p)
+ int nonsteppable_watchpoint_p,
+ int thread)
{
step_over_info.aspace = aspace;
step_over_info.address = address;
step_over_info.nonsteppable_watchpoint_p = nonsteppable_watchpoint_p;
+ step_over_info.thread = thread;
}
/* Called when we're not longer stepping over a breakpoint / an
@@ -1348,6 +1353,7 @@ clear_step_over_info (void)
step_over_info.aspace = NULL;
step_over_info.address = 0;
step_over_info.nonsteppable_watchpoint_p = 0;
+ step_over_info.thread = -1;
}
/* See infrun.h. */
@@ -1365,6 +1371,15 @@ stepping_past_instruction_at (struct address_space *aspace,
/* See infrun.h. */
int
+thread_is_stepping_over_breakpoint (int thread)
+{
+ return (step_over_info.thread != -1
+ && thread == step_over_info.thread);
+}
+
+/* See infrun.h. */
+
+int
stepping_past_nonsteppable_watchpoint (void)
{
return step_over_info.nonsteppable_watchpoint_p;
@@ -2579,7 +2594,7 @@ resume (enum gdb_signal sig)
stop_all_threads ();
set_step_over_info (get_regcache_aspace (regcache),
- regcache_read_pc (regcache), 0);
+ regcache_read_pc (regcache), 0, tp->global_num);
step = maybe_software_singlestep (gdbarch, pc);
@@ -7750,10 +7765,11 @@ keep_going_pass_signal (struct execution_control_state *ecs)
&& (remove_wps || !use_displaced_stepping (ecs->event_thread)))
{
set_step_over_info (get_regcache_aspace (regcache),
- regcache_read_pc (regcache), remove_wps);
+ regcache_read_pc (regcache), remove_wps,
+ ecs->event_thread->global_num);
}
else if (remove_wps)
- set_step_over_info (NULL, 0, remove_wps);
+ set_step_over_info (NULL, 0, remove_wps, -1);
/* If we now need to do an in-line step-over, we need to stop
all other threads. Note this must be done before