aboutsummaryrefslogtreecommitdiff
path: root/gdb/infrun.c
diff options
context:
space:
mode:
authorMichael Snyder <msnyder@vmware.com>2001-06-26 00:26:42 +0000
committerMichael Snyder <msnyder@vmware.com>2001-06-26 00:26:42 +0000
commitef5cf84e219f3d26788d55e01ca7ebfb5b39406d (patch)
tree64beb6af54fcc9d2032c140c9baf24e456b92a67 /gdb/infrun.c
parent36d4f364392cc35890608b56adb8c288dc9f5bfe (diff)
downloadgdb-ef5cf84e219f3d26788d55e01ca7ebfb5b39406d.zip
gdb-ef5cf84e219f3d26788d55e01ca7ebfb5b39406d.tar.gz
gdb-ef5cf84e219f3d26788d55e01ca7ebfb5b39406d.tar.bz2
2001-06-25 Michael Snyder <msnyder@redhat.com>
* infrun.c: Eliminate the "thread_step_needed" state variable, and replace it with a relatively simple test in resume. (resume): Replace thread_step_needed logic with a test for stepping, breakpoint_here_p and breakpoints_inserted. Move CANNOT_STEP_BREAKPOINT logic to after thread_step logic. (proceed): Discard thread_step_needed logic. (wait_for_inferior, fetch_inferior_event, handle_inferior_event): Discard thread_step_needed logic.
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r--gdb/infrun.c122
1 files changed, 24 insertions, 98 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c
index ba62333..a500e97 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -110,31 +110,6 @@ static ptid_t previous_inferior_ptid;
static int may_follow_exec = MAY_FOLLOW_EXEC;
-/* resume and wait_for_inferior use this to ensure that when
- stepping over a hit breakpoint in a threaded application
- only the thread that hit the breakpoint is stepped and the
- other threads don't continue. This prevents having another
- thread run past the breakpoint while it is temporarily
- removed.
-
- This is not thread-specific, so it isn't saved as part of
- the infrun state.
-
- Versions of gdb which don't use the "step == this thread steps
- and others continue" model but instead use the "step == this
- thread steps and others wait" shouldn't do this. */
-
-static int thread_step_needed = 0;
-
-/* This is true if thread_step_needed should actually be used. At
- present this is only true for HP-UX native. */
-
-#ifndef USE_THREAD_STEP_NEEDED
-#define USE_THREAD_STEP_NEEDED (0)
-#endif
-
-static int use_thread_step_needed = USE_THREAD_STEP_NEEDED;
-
/* GET_LONGJMP_TARGET returns the PC at which longjmp() will resume the
program. It needs to examine the jmp_buf argument and extract the PC
from it. The return value is non-zero on success, zero otherwise. */
@@ -821,13 +796,8 @@ resume (int step, enum target_signal sig)
struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0);
QUIT;
-#ifdef CANNOT_STEP_BREAKPOINT
- /* Most targets can step a breakpoint instruction, thus executing it
- normally. But if this one cannot, just continue and we will hit
- it anyway. */
- if (step && breakpoints_inserted && breakpoint_here_p (read_pc ()))
- step = 0;
-#endif
+ /* FIXME: calling breakpoint_here_p (read_pc ()) three times! */
+
/* Some targets (e.g. Solaris x86) have a kernel bug when stepping
over an instruction that causes a page fault without triggering
@@ -910,41 +880,34 @@ resume (int step, enum target_signal sig)
{
ptid_t resume_ptid;
- if (use_thread_step_needed && thread_step_needed)
+ resume_ptid = RESUME_ALL; /* Default */
+
+ if ((step || singlestep_breakpoints_inserted_p) &&
+ !breakpoints_inserted && breakpoint_here_p (read_pc ()))
{
- /* We stopped on a BPT instruction;
- don't continue other threads and
- just step this thread. */
- thread_step_needed = 0;
+ /* Stepping past a breakpoint without inserting breakpoints.
+ Make sure only the current thread gets to step, so that
+ other threads don't sneak past breakpoints while they are
+ not inserted. */
- if (!breakpoint_here_p (read_pc ()))
- {
- /* Breakpoint deleted: ok to do regular resume
- where all the threads either step or continue. */
- resume_ptid = RESUME_ALL;
- }
- else
- {
- if (!step)
- {
- warning ("Internal error, changing continue to step.");
- remove_breakpoints ();
- breakpoints_inserted = 0;
- trap_expected = 1;
- step = 1;
- }
- resume_ptid = inferior_ptid;
- }
+ resume_ptid = inferior_ptid;
}
- else
+
+ if ((scheduler_mode == schedlock_on) ||
+ (scheduler_mode == schedlock_step &&
+ (step || singlestep_breakpoints_inserted_p)))
{
- /* Vanilla resume. */
- if ((scheduler_mode == schedlock_on) ||
- (scheduler_mode == schedlock_step && step != 0))
+ /* User-settable 'scheduler' mode requires solo thread resume. */
resume_ptid = inferior_ptid;
- else
- resume_ptid = RESUME_ALL;
}
+
+#ifdef CANNOT_STEP_BREAKPOINT
+ /* Most targets can step a breakpoint instruction, thus executing it
+ normally. But if this one cannot, just continue and we will hit
+ it anyway. */
+ if (step && breakpoints_inserted && breakpoint_here_p (read_pc ()))
+ step = 0;
+#endif
target_resume (resume_ptid, step, sig);
}
@@ -1019,16 +982,6 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
else
{
write_pc (addr);
-
- /* New address; we don't need to single-step a thread
- over a breakpoint we just hit, 'cause we aren't
- continuing from there.
-
- It's not worth worrying about the case where a user
- asks for a "jump" at the current PC--if they get the
- hiccup of re-hiting a hit breakpoint, what else do
- they expect? */
- thread_step_needed = 0;
}
#ifdef PREPARE_TO_PROCEED
@@ -1046,7 +999,6 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
if (PREPARE_TO_PROCEED (1) && breakpoint_here_p (read_pc ()))
{
oneproc = 1;
- thread_step_needed = 1;
}
#endif /* PREPARE_TO_PROCEED */
@@ -1287,8 +1239,6 @@ wait_for_inferior (void)
/* Fill in with reasonable starting values. */
init_execution_control_state (ecs);
- thread_step_needed = 0;
-
/* We'll update this if & when we switch to a new thread. */
previous_inferior_ptid = inferior_ptid;
@@ -1347,8 +1297,6 @@ fetch_inferior_event (void *client_data)
/* Fill in with reasonable starting values. */
init_execution_control_state (async_ecs);
- thread_step_needed = 0;
-
/* We'll update this if & when we switch to a new thread. */
previous_inferior_ptid = inferior_ptid;
@@ -1498,11 +1446,6 @@ handle_inferior_event (struct execution_control_state *ecs)
/* Fall thru to the normal_state case. */
case infwait_normal_state:
- /* Since we've done a wait, we have a new event. Don't
- carry over any expectations about needing to step over a
- breakpoint. */
- thread_step_needed = 0;
-
/* See comments where a TARGET_WAITKIND_SYSCALL_RETURN event
is serviced in this loop, below. */
if (ecs->enable_hw_watchpoints_after_wait)
@@ -1934,30 +1877,14 @@ handle_inferior_event (struct execution_control_state *ecs)
context_switch (ecs);
ecs->waiton_ptid = ecs->ptid;
ecs->wp = &(ecs->ws);
- thread_step_needed = 1;
ecs->another_trap = 1;
- /* keep_stepping will call resume, and the
- combination of "thread_step_needed" and
- "ecs->another_trap" will cause resume to
- solo-step the thread. The subsequent trap
- event will be handled like any other singlestep
- event. */
-
ecs->infwait_state = infwait_thread_hop_state;
keep_going (ecs);
registers_changed ();
return;
}
}
- else
- {
- /* This breakpoint matches--either it is the right
- thread or it's a generic breakpoint for all threads.
- Remember that we'll need to step just _this_ thread
- on any following user continuation! */
- thread_step_needed = 1;
- }
}
}
else
@@ -2413,7 +2340,6 @@ handle_inferior_event (struct execution_control_state *ecs)
case BPSTAT_WHAT_SINGLE:
if (breakpoints_inserted)
{
- thread_step_needed = 1;
remove_breakpoints ();
}
breakpoints_inserted = 0;