diff options
author | Pedro Alves <palves@redhat.com> | 2012-06-28 16:34:04 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2012-06-28 16:34:04 +0000 |
commit | e5ef252af07bfbf40e78b0ebcc5eef2e3b0af7a3 (patch) | |
tree | 802ef5f4182c89facf11b44253f0ae0c96a8ca53 /gdb/infrun.c | |
parent | dc60a23811c4d144c0a1242d30c3f64e1d13e941 (diff) | |
download | gdb-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.c | 372 |
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 |