aboutsummaryrefslogtreecommitdiff
path: root/gdb/infrun.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2012-06-28 16:34:04 +0000
committerPedro Alves <palves@redhat.com>2012-06-28 16:34:04 +0000
commite5ef252af07bfbf40e78b0ebcc5eef2e3b0af7a3 (patch)
tree802ef5f4182c89facf11b44253f0ae0c96a8ca53 /gdb/infrun.c
parentdc60a23811c4d144c0a1242d30c3f64e1d13e941 (diff)
downloadgdb-e5ef252af07bfbf40e78b0ebcc5eef2e3b0af7a3.zip
gdb-e5ef252af07bfbf40e78b0ebcc5eef2e3b0af7a3.tar.gz
gdb-e5ef252af07bfbf40e78b0ebcc5eef2e3b0af7a3.tar.bz2
gdb/
2012-06-28 Jan Kratochvil <jan.kratochvil@redhat.com> Pedro Alves <palves@redhat.com> * gdbthread.h (ALL_THREADS): New macro. (thread_list): Declare. * infrun.c (handle_inferior_event) <spurious signal>: Don't keep going, but instead fall through to the stepping handling. * linux-nat.c (resume_lwp): New parameter 'signo'. Resume with the passed in signal. Adjust debug output. (resume_callback): Rename to ... (linux_nat_resume_callback): ... this. Pass the thread's last stop signal, if in "pass" state. (linux_nat_resume): Adjust to rename. (stop_wait_callback): New assertion. Don't respawn signals; instead let the LWP remain with SIGNALLED set. (linux_nat_wait_1): Remove flushing of pending SIGSTOPs. * remote.c (append_pending_thread_resumptions): New. (remote_vcont_resume): Call it. * target.h (target_resume): Extend comment. gdb/testsuite/ 2012-06-28 Jan Kratochvil <jan.kratochvil@redhat.com> Pedro Alves <palves@redhat.com> * gdb.threads/siginfo-threads.exp: New file. * gdb.threads/siginfo-threads.c: New file. * gdb.threads/sigstep-threads.exp: New file. * gdb.threads/sigstep-threads.c: New file.
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r--gdb/infrun.c372
1 files changed, 186 insertions, 186 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 53db335..2f66ddc 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -4363,227 +4363,227 @@ process_event_stop_test:
(leaving the inferior at the step-resume-breakpoint without
actually executing it). Either way continue until the
breakpoint is really hit. */
- keep_going (ecs);
- return;
}
+ else
+ {
+ /* Handle cases caused by hitting a breakpoint. */
- /* Handle cases caused by hitting a breakpoint. */
- {
- CORE_ADDR jmp_buf_pc;
- struct bpstat_what what;
-
- what = bpstat_what (ecs->event_thread->control.stop_bpstat);
-
- if (what.call_dummy)
- {
- stop_stack_dummy = what.call_dummy;
- }
-
- /* If we hit an internal event that triggers symbol changes, the
- current frame will be invalidated within bpstat_what (e.g., if
- we hit an internal solib event). Re-fetch it. */
- frame = get_current_frame ();
- gdbarch = get_frame_arch (frame);
-
- switch (what.main_action)
- {
- case BPSTAT_WHAT_SET_LONGJMP_RESUME:
- /* If we hit the breakpoint at longjmp while stepping, we
- install a momentary breakpoint at the target of the
- jmp_buf. */
-
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog,
- "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME\n");
+ CORE_ADDR jmp_buf_pc;
+ struct bpstat_what what;
- ecs->event_thread->stepping_over_breakpoint = 1;
+ what = bpstat_what (ecs->event_thread->control.stop_bpstat);
- if (what.is_longjmp)
- {
- struct value *arg_value;
-
- /* If we set the longjmp breakpoint via a SystemTap probe,
- then use it to extract the arguments. The destination
- PC is the third argument to the probe. */
- arg_value = probe_safe_evaluate_at_pc (frame, 2);
- if (arg_value)
- jmp_buf_pc = value_as_address (arg_value);
- else if (!gdbarch_get_longjmp_target_p (gdbarch)
- || !gdbarch_get_longjmp_target (gdbarch,
- frame, &jmp_buf_pc))
- {
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog,
- "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME "
- "(!gdbarch_get_longjmp_target)\n");
- keep_going (ecs);
- return;
- }
-
- /* Insert a breakpoint at resume address. */
- insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc);
- }
- else
- check_exception_resume (ecs, frame);
- keep_going (ecs);
- return;
-
- case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
+ if (what.call_dummy)
{
- struct frame_info *init_frame;
-
- /* There are several cases to consider.
-
- 1. The initiating frame no longer exists. In this case
- we must stop, because the exception or longjmp has gone
- too far.
-
- 2. The initiating frame exists, and is the same as the
- current frame. We stop, because the exception or longjmp
- has been caught.
+ stop_stack_dummy = what.call_dummy;
+ }
- 3. The initiating frame exists and is different from the
- current frame. This means the exception or longjmp has
- been caught beneath the initiating frame, so keep
- going.
+ /* If we hit an internal event that triggers symbol changes, the
+ current frame will be invalidated within bpstat_what (e.g.,
+ if we hit an internal solib event). Re-fetch it. */
+ frame = get_current_frame ();
+ gdbarch = get_frame_arch (frame);
- 4. longjmp breakpoint has been placed just to protect
- against stale dummy frames and user is not interested in
- stopping around longjmps. */
+ switch (what.main_action)
+ {
+ case BPSTAT_WHAT_SET_LONGJMP_RESUME:
+ /* If we hit the breakpoint at longjmp while stepping, we
+ install a momentary breakpoint at the target of the
+ jmp_buf. */
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
- "infrun: BPSTAT_WHAT_CLEAR_LONGJMP_RESUME\n");
+ "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME\n");
- gdb_assert (ecs->event_thread->control.exception_resume_breakpoint
- != NULL);
- delete_exception_resume_breakpoint (ecs->event_thread);
+ ecs->event_thread->stepping_over_breakpoint = 1;
if (what.is_longjmp)
{
- check_longjmp_breakpoint_for_call_dummy (ecs->event_thread->num);
-
- if (!frame_id_p (ecs->event_thread->initiating_frame))
+ struct value *arg_value;
+
+ /* If we set the longjmp breakpoint via a SystemTap
+ probe, then use it to extract the arguments. The
+ destination PC is the third argument to the
+ probe. */
+ arg_value = probe_safe_evaluate_at_pc (frame, 2);
+ if (arg_value)
+ jmp_buf_pc = value_as_address (arg_value);
+ else if (!gdbarch_get_longjmp_target_p (gdbarch)
+ || !gdbarch_get_longjmp_target (gdbarch,
+ frame, &jmp_buf_pc))
{
- /* Case 4. */
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog,
+ "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME "
+ "(!gdbarch_get_longjmp_target)\n");
keep_going (ecs);
return;
}
+
+ /* Insert a breakpoint at resume address. */
+ insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc);
}
+ else
+ check_exception_resume (ecs, frame);
+ keep_going (ecs);
+ return;
- init_frame = frame_find_by_id (ecs->event_thread->initiating_frame);
+ case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
+ {
+ struct frame_info *init_frame;
- if (init_frame)
- {
- struct frame_id current_id
- = get_frame_id (get_current_frame ());
- if (frame_id_eq (current_id,
- ecs->event_thread->initiating_frame))
- {
- /* Case 2. Fall through. */
- }
- else
- {
- /* Case 3. */
- keep_going (ecs);
- return;
- }
- }
+ /* There are several cases to consider.
- /* For Cases 1 and 2, remove the step-resume breakpoint,
- if it exists. */
- delete_step_resume_breakpoint (ecs->event_thread);
+ 1. The initiating frame no longer exists. In this case
+ we must stop, because the exception or longjmp has gone
+ too far.
- ecs->event_thread->control.stop_step = 1;
- print_end_stepping_range_reason ();
- stop_stepping (ecs);
- }
- return;
-
- case BPSTAT_WHAT_SINGLE:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_SINGLE\n");
- ecs->event_thread->stepping_over_breakpoint = 1;
- /* Still need to check other stuff, at least the case
- where we are stepping and step out of the right range. */
- break;
+ 2. The initiating frame exists, and is the same as the
+ current frame. We stop, because the exception or
+ longjmp has been caught.
- case BPSTAT_WHAT_STEP_RESUME:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STEP_RESUME\n");
+ 3. The initiating frame exists and is different from
+ the current frame. This means the exception or longjmp
+ has been caught beneath the initiating frame, so keep
+ going.
- delete_step_resume_breakpoint (ecs->event_thread);
- if (ecs->event_thread->control.proceed_to_finish
- && execution_direction == EXEC_REVERSE)
- {
- struct thread_info *tp = ecs->event_thread;
-
- /* We are finishing a function in reverse, and just hit
- the step-resume breakpoint at the start address of the
- function, and we're almost there -- just need to back
- up by one more single-step, which should take us back
- to the function call. */
- tp->control.step_range_start = tp->control.step_range_end = 1;
- keep_going (ecs);
- return;
- }
- fill_in_stop_func (gdbarch, ecs);
- if (stop_pc == ecs->stop_func_start
- && execution_direction == EXEC_REVERSE)
- {
- /* We are stepping over a function call in reverse, and
- just hit the step-resume breakpoint at the start
- address of the function. Go back to single-stepping,
- which should take us back to the function call. */
- ecs->event_thread->stepping_over_breakpoint = 1;
- keep_going (ecs);
- return;
- }
- break;
+ 4. longjmp breakpoint has been placed just to protect
+ against stale dummy frames and user is not interested
+ in stopping around longjmps. */
- case BPSTAT_WHAT_STOP_NOISY:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_NOISY\n");
- stop_print_frame = 1;
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog,
+ "infrun: BPSTAT_WHAT_CLEAR_LONGJMP_RESUME\n");
- /* We are about to nuke the step_resume_breakpointt via the
- cleanup chain, so no need to worry about it here. */
+ gdb_assert (ecs->event_thread->control.exception_resume_breakpoint
+ != NULL);
+ delete_exception_resume_breakpoint (ecs->event_thread);
- stop_stepping (ecs);
- return;
+ if (what.is_longjmp)
+ {
+ check_longjmp_breakpoint_for_call_dummy (ecs->event_thread->num);
- case BPSTAT_WHAT_STOP_SILENT:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_SILENT\n");
- stop_print_frame = 0;
+ if (!frame_id_p (ecs->event_thread->initiating_frame))
+ {
+ /* Case 4. */
+ keep_going (ecs);
+ return;
+ }
+ }
- /* We are about to nuke the step_resume_breakpoin via the
- cleanup chain, so no need to worry about it here. */
+ init_frame = frame_find_by_id (ecs->event_thread->initiating_frame);
- stop_stepping (ecs);
- return;
+ if (init_frame)
+ {
+ struct frame_id current_id
+ = get_frame_id (get_current_frame ());
+ if (frame_id_eq (current_id,
+ ecs->event_thread->initiating_frame))
+ {
+ /* Case 2. Fall through. */
+ }
+ else
+ {
+ /* Case 3. */
+ keep_going (ecs);
+ return;
+ }
+ }
- case BPSTAT_WHAT_HP_STEP_RESUME:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_HP_STEP_RESUME\n");
+ /* For Cases 1 and 2, remove the step-resume breakpoint,
+ if it exists. */
+ delete_step_resume_breakpoint (ecs->event_thread);
- delete_step_resume_breakpoint (ecs->event_thread);
- if (ecs->event_thread->step_after_step_resume_breakpoint)
- {
- /* Back when the step-resume breakpoint was inserted, we
- were trying to single-step off a breakpoint. Go back
- to doing that. */
- ecs->event_thread->step_after_step_resume_breakpoint = 0;
- ecs->event_thread->stepping_over_breakpoint = 1;
- keep_going (ecs);
- return;
+ ecs->event_thread->control.stop_step = 1;
+ print_end_stepping_range_reason ();
+ stop_stepping (ecs);
}
- break;
+ return;
- case BPSTAT_WHAT_KEEP_CHECKING:
- break;
- }
- }
+ case BPSTAT_WHAT_SINGLE:
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_SINGLE\n");
+ ecs->event_thread->stepping_over_breakpoint = 1;
+ /* Still need to check other stuff, at least the case where
+ we are stepping and step out of the right range. */
+ break;
+
+ case BPSTAT_WHAT_STEP_RESUME:
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STEP_RESUME\n");
+
+ delete_step_resume_breakpoint (ecs->event_thread);
+ if (ecs->event_thread->control.proceed_to_finish
+ && execution_direction == EXEC_REVERSE)
+ {
+ struct thread_info *tp = ecs->event_thread;
+
+ /* We are finishing a function in reverse, and just hit
+ the step-resume breakpoint at the start address of
+ the function, and we're almost there -- just need to
+ back up by one more single-step, which should take us
+ back to the function call. */
+ tp->control.step_range_start = tp->control.step_range_end = 1;
+ keep_going (ecs);
+ return;
+ }
+ fill_in_stop_func (gdbarch, ecs);
+ if (stop_pc == ecs->stop_func_start
+ && execution_direction == EXEC_REVERSE)
+ {
+ /* We are stepping over a function call in reverse, and
+ just hit the step-resume breakpoint at the start
+ address of the function. Go back to single-stepping,
+ which should take us back to the function call. */
+ ecs->event_thread->stepping_over_breakpoint = 1;
+ keep_going (ecs);
+ return;
+ }
+ break;
+
+ case BPSTAT_WHAT_STOP_NOISY:
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_NOISY\n");
+ stop_print_frame = 1;
+
+ /* We are about to nuke the step_resume_breakpointt via the
+ cleanup chain, so no need to worry about it here. */
+
+ stop_stepping (ecs);
+ return;
+
+ case BPSTAT_WHAT_STOP_SILENT:
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_SILENT\n");
+ stop_print_frame = 0;
+
+ /* We are about to nuke the step_resume_breakpoin via the
+ cleanup chain, so no need to worry about it here. */
+
+ stop_stepping (ecs);
+ return;
+
+ case BPSTAT_WHAT_HP_STEP_RESUME:
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_HP_STEP_RESUME\n");
+
+ delete_step_resume_breakpoint (ecs->event_thread);
+ if (ecs->event_thread->step_after_step_resume_breakpoint)
+ {
+ /* Back when the step-resume breakpoint was inserted, we
+ were trying to single-step off a breakpoint. Go back
+ to doing that. */
+ ecs->event_thread->step_after_step_resume_breakpoint = 0;
+ ecs->event_thread->stepping_over_breakpoint = 1;
+ keep_going (ecs);
+ return;
+ }
+ break;
+
+ case BPSTAT_WHAT_KEEP_CHECKING:
+ break;
+ }
+ }
/* We come here if we hit a breakpoint but should not
stop for it. Possibly we also were stepping