fprintf_filtered (file, _("Displace stepping debugging is %s.\n"), value);
}
-int debug_infrun = 0;
+unsigned int debug_infrun = 0;
static void
show_debug_infrun (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
remove_displaced_stepping_state (inf->pid);
}
-/* Enum strings for "set|show displaced-stepping". */
-
-static const char can_use_displaced_stepping_auto[] = "auto";
-static const char can_use_displaced_stepping_on[] = "on";
-static const char can_use_displaced_stepping_off[] = "off";
-static const char *const can_use_displaced_stepping_enum[] =
-{
- can_use_displaced_stepping_auto,
- can_use_displaced_stepping_on,
- can_use_displaced_stepping_off,
- NULL,
-};
-
/* If ON, and the architecture supports it, GDB will use displaced
stepping to step over breakpoints. If OFF, or if the architecture
doesn't support it, GDB will instead use the traditional
which of all-stop or non-stop mode is active --- displaced stepping
in non-stop mode; hold-and-step in all-stop mode. */
-static const char *can_use_displaced_stepping =
- can_use_displaced_stepping_auto;
+static enum auto_boolean can_use_displaced_stepping = AUTO_BOOLEAN_AUTO;
static void
show_can_use_displaced_stepping (struct ui_file *file, int from_tty,
struct cmd_list_element *c,
const char *value)
{
- if (can_use_displaced_stepping == can_use_displaced_stepping_auto)
+ if (can_use_displaced_stepping == AUTO_BOOLEAN_AUTO)
fprintf_filtered (file,
_("Debugger's willingness to use displaced stepping "
"to step over breakpoints is %s (currently %s).\n"),
static int
use_displaced_stepping (struct gdbarch *gdbarch)
{
- return (((can_use_displaced_stepping == can_use_displaced_stepping_auto
- && non_stop)
- || can_use_displaced_stepping == can_use_displaced_stepping_on)
+ return (((can_use_displaced_stepping == AUTO_BOOLEAN_AUTO && non_stop)
+ || can_use_displaced_stepping == AUTO_BOOLEAN_TRUE)
&& gdbarch_displaced_step_copy_insn_p (gdbarch)
&& !RECORD_IS_USED);
}
}
if (ecs->ws.kind != TARGET_WAITKIND_EXITED
- && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
- && !ptid_equal (ecs->ptid, minus_one_ptid))
+ && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED)
{
ecs->event_thread = find_thread_ptid (ecs->ptid);
/* If it's a new thread, add it to the thread database. */
case TARGET_WAITKIND_SPURIOUS:
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SPURIOUS\n");
- if (!ptid_equal (ecs->ptid, inferior_ptid)
- && !ptid_equal (ecs->ptid, minus_one_ptid))
+ if (!ptid_equal (ecs->ptid, inferior_ptid))
context_switch (ecs->ptid);
resume (0, GDB_SIGNAL_0);
prepare_to_wait (ecs);
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_HISTORY\n");
/* Reverse execution: target ran out of history info. */
+
+ /* Pull the single step breakpoints out of the target. */
+ if (singlestep_breakpoints_inserted_p)
+ {
+ if (!ptid_equal (ecs->ptid, inferior_ptid))
+ context_switch (ecs->ptid);
+ remove_single_step_breakpoints ();
+ singlestep_breakpoints_inserted_p = 0;
+ }
stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
print_no_history_reason ();
stop_stepping (ecs);
skip_inline_frames call would break things. Fortunately
that's an extremely unlikely scenario. */
if (!pc_at_non_inline_function (aspace, stop_pc, &ecs->ws)
- && !(ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
- && ecs->event_thread->control.trap_expected
- && pc_at_non_inline_function (aspace,
- ecs->event_thread->prev_pc,
+ && !(ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
+ && ecs->event_thread->control.trap_expected
+ && pc_at_non_inline_function (aspace,
+ ecs->event_thread->prev_pc,
&ecs->ws)))
- skip_inline_frames (ecs->ptid);
+ {
+ skip_inline_frames (ecs->ptid);
+
+ /* Re-fetch current thread's frame in case that invalidated
+ the frame cache. */
+ frame = get_current_frame ();
+ gdbarch = get_frame_arch (frame);
+ }
}
if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
(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;
+ CORE_ADDR jmp_buf_pc;
+ struct bpstat_what what;
- what = bpstat_what (ecs->event_thread->control.stop_bpstat);
+ what = bpstat_what (ecs->event_thread->control.stop_bpstat);
- if (what.call_dummy)
- {
- stop_stack_dummy = what.call_dummy;
- }
+ 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);
+ /* 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. */
+ 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");
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog,
+ "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME\n");
- ecs->event_thread->stepping_over_breakpoint = 1;
+ ecs->event_thread->stepping_over_breakpoint = 1;
- 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;
- }
+ 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;
+ /* 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:
- {
- struct frame_info *init_frame;
+ case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
+ {
+ struct frame_info *init_frame;
- /* There are several cases to consider.
+ /* 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.
+ 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.
+ 2. The initiating frame exists, and is the same as the
+ current frame. We stop, because the exception or
+ longjmp has been caught.
- 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. */
+ 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 (debug_infrun)
- fprintf_unfiltered (gdb_stdlog,
- "infrun: BPSTAT_WHAT_CLEAR_LONGJMP_RESUME\n");
+ 4. longjmp breakpoint has been placed just to protect
+ against stale dummy frames and user is not interested
+ in stopping around longjmps. */
- init_frame = frame_find_by_id (ecs->event_thread->initiating_frame);
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog,
+ "infrun: BPSTAT_WHAT_CLEAR_LONGJMP_RESUME\n");
- gdb_assert (ecs->event_thread->control.exception_resume_breakpoint
- != NULL);
- delete_exception_resume_breakpoint (ecs->event_thread);
+ gdb_assert (ecs->event_thread->control.exception_resume_breakpoint
+ != NULL);
+ delete_exception_resume_breakpoint (ecs->event_thread);
- 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;
- }
- }
+ if (what.is_longjmp)
+ {
+ check_longjmp_breakpoint_for_call_dummy (ecs->event_thread->num);
- /* For Cases 1 and 2, remove the step-resume breakpoint,
- if it exists. */
- delete_step_resume_breakpoint (ecs->event_thread);
+ if (!frame_id_p (ecs->event_thread->initiating_frame))
+ {
+ /* Case 4. */
+ keep_going (ecs);
+ return;
+ }
+ }
- 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;
+ init_frame = frame_find_by_id (ecs->event_thread->initiating_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;
+ }
+ }
- case BPSTAT_WHAT_STEP_RESUME:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_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->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;
+ ecs->event_thread->control.stop_step = 1;
+ print_end_stepping_range_reason ();
+ stop_stepping (ecs);
}
- break;
+ return;
- case BPSTAT_WHAT_STOP_NOISY:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_NOISY\n");
- stop_print_frame = 1;
+ 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;
- /* We are about to nuke the step_resume_breakpointt via the
- cleanup chain, so no need to worry about it here. */
+ case BPSTAT_WHAT_STEP_RESUME:
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STEP_RESUME\n");
- stop_stepping (ecs);
- return;
+ 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_SILENT:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_SILENT\n");
- stop_print_frame = 0;
+ 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_breakpoin via the
- cleanup chain, so no need to worry about it here. */
+ /* 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;
+ stop_stepping (ecs);
+ return;
- case BPSTAT_WHAT_HP_STEP_RESUME:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_HP_STEP_RESUME\n");
+ case BPSTAT_WHAT_STOP_SILENT:
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_SILENT\n");
+ stop_print_frame = 0;
- 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;
+ /* We are about to nuke the step_resume_breakpoin via the
+ cleanup chain, so no need to worry about it here. */
- case BPSTAT_WHAT_KEEP_CHECKING:
- break;
- }
- }
+ 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
static void
insert_exception_resume_from_probe (struct thread_info *tp,
const struct probe *probe,
- struct objfile *objfile,
struct frame_info *frame)
{
struct value *arg_value;
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: exception resume at %s\n",
- paddress (get_objfile_arch (objfile),
+ paddress (get_objfile_arch (probe->objfile),
handler));
bp = set_momentary_breakpoint_at_pc (get_frame_arch (frame),
struct frame_info *frame)
{
volatile struct gdb_exception e;
- struct objfile *objfile;
const struct probe *probe;
struct symbol *func;
SystemTap probe point. If so, the probe has two arguments: the
CFA and the HANDLER. We ignore the CFA, extract the handler, and
set a breakpoint there. */
- probe = find_probe_by_pc (get_frame_pc (frame), &objfile);
+ probe = find_probe_by_pc (get_frame_pc (frame));
if (probe)
{
- insert_exception_resume_from_probe (ecs->event_thread, probe,
- objfile, frame);
+ insert_exception_resume_from_probe (ecs->event_thread, probe, frame);
return;
}
struct infcall_suspend_state
{
struct thread_suspend_state thread_suspend;
+#if 0 /* Currently unused and empty structures are not valid C. */
struct inferior_suspend_state inferior_suspend;
+#endif
/* Other fields: */
CORE_ADDR stop_pc;
}
inf_state->thread_suspend = tp->suspend;
+#if 0 /* Currently unused and empty structures are not valid C. */
inf_state->inferior_suspend = inf->suspend;
+#endif
/* run_inferior_call will not use the signal due to its `proceed' call with
GDB_SIGNAL_0 anyway. */
struct gdbarch *gdbarch = get_regcache_arch (regcache);
tp->suspend = inf_state->thread_suspend;
+#if 0 /* Currently unused and empty structures are not valid C. */
inf->suspend = inf_state->inferior_suspend;
+#endif
stop_pc = inf_state->stop_pc;
This allows you to set a list of commands to be run each time execution\n\
of the program stops."), &cmdlist);
- add_setshow_zinteger_cmd ("infrun", class_maintenance, &debug_infrun, _("\
+ add_setshow_zuinteger_cmd ("infrun", class_maintenance, &debug_infrun, _("\
Set inferior debugging."), _("\
Show inferior debugging."), _("\
When non-zero, inferior specific debugging is enabled."),
- NULL,
- show_debug_infrun,
- &setdebuglist, &showdebuglist);
+ NULL,
+ show_debug_infrun,
+ &setdebuglist, &showdebuglist);
add_setshow_boolean_cmd ("displaced", class_maintenance,
&debug_displaced, _("\
show_step_stop_if_no_debug,
&setlist, &showlist);
- add_setshow_enum_cmd ("displaced-stepping", class_run,
- can_use_displaced_stepping_enum,
- &can_use_displaced_stepping, _("\
+ add_setshow_auto_boolean_cmd ("displaced-stepping", class_run,
+ &can_use_displaced_stepping, _("\
Set debugger's willingness to use displaced stepping."), _("\
Show debugger's willingness to use displaced stepping."), _("\
If on, gdb will use displaced stepping to step over breakpoints if it is\n\
architecture. If auto (which is the default), gdb will use displaced stepping\n\
if the target architecture supports it and non-stop mode is active, but will not\n\
use it in all-stop mode (see help set non-stop)."),
- NULL,
- show_can_use_displaced_stepping,
- &setlist, &showlist);
+ NULL,
+ show_can_use_displaced_stepping,
+ &setlist, &showlist);
add_setshow_enum_cmd ("exec-direction", class_run, exec_direction_names,
&exec_direction, _("Set direction of execution.\n\