void _initialize_infrun (void);
-int inferior_ignoring_startup_exec_events = 0;
int inferior_ignoring_leading_exec_events = 0;
/* When set, stop the 'step' command if we enter a function which has
if (breakpoint_here_p (read_pc ()) == permanent_breakpoint_here)
{
if (gdbarch_skip_permanent_breakpoint_p (current_gdbarch))
- gdbarch_skip_permanent_breakpoint (current_gdbarch, current_regcache);
+ gdbarch_skip_permanent_breakpoint (current_gdbarch,
+ get_current_regcache ());
else
error (_("\
The program is stopped at a permanent breakpoint, but GDB does not know\n\
a command like `return' or `jump' to continue execution."));
}
- if (SOFTWARE_SINGLE_STEP_P () && step)
+ if (step && gdbarch_software_single_step_p (current_gdbarch))
{
/* Do it the hard way, w/temp breakpoints */
- if (SOFTWARE_SINGLE_STEP (get_current_frame ()))
+ if (gdbarch_software_single_step (current_gdbarch, get_current_frame ()))
{
/* ...and don't ask hardware to do it. */
step = 0;
proceed_to_finish = 0;
breakpoint_proceeded = 1; /* We're about to proceed... */
+ if (stop_registers)
+ {
+ regcache_xfree (stop_registers);
+ stop_registers = NULL;
+ }
+
/* Discard any remaining commands or status from previous stop. */
bpstat_clear (&stop_bpstat);
}
{
init_thread_list ();
init_wait_for_inferior ();
- stop_soon = STOP_QUIETLY;
+ stop_soon = STOP_QUIETLY_REMOTE;
trap_expected = 0;
/* Always go on waiting for the target, regardless of the mode. */
breakpoint_pc = read_pc_pid (ecs->ptid) - gdbarch_decr_pc_after_break
(current_gdbarch);
- if (SOFTWARE_SINGLE_STEP_P ())
- {
- /* When using software single-step, a SIGTRAP can only indicate
- an inserted breakpoint. This actually makes things
- easier. */
- if (singlestep_breakpoints_inserted_p)
- /* When software single stepping, the instruction at [prev_pc]
- is never a breakpoint, but the instruction following
- [prev_pc] (in program execution order) always is. Assume
- that following instruction was reached and hence a software
- breakpoint was hit. */
- write_pc_pid (breakpoint_pc, ecs->ptid);
- else if (software_breakpoint_inserted_here_p (breakpoint_pc))
- /* The inferior was free running (i.e., no single-step
- breakpoints inserted) and it hit a software breakpoint. */
- write_pc_pid (breakpoint_pc, ecs->ptid);
- }
- else
+ /* Check whether there actually is a software breakpoint inserted
+ at that location. */
+ if (software_breakpoint_inserted_here_p (breakpoint_pc))
{
- /* When using hardware single-step, a SIGTRAP is reported for
- both a completed single-step and a software breakpoint. Need
- to differentiate between the two as the latter needs
- adjusting but the former does not.
-
- When the thread to be examined does not match the current thread
- context we can't use currently_stepping, so assume no
- single-stepping in this case. */
- if (ptid_equal (ecs->ptid, inferior_ptid) && currently_stepping (ecs))
- {
- if (prev_pc == breakpoint_pc
- && software_breakpoint_inserted_here_p (breakpoint_pc))
- /* Hardware single-stepped a software breakpoint (as
- occures when the inferior is resumed with PC pointing
- at not-yet-hit software breakpoint). Since the
- breakpoint really is executed, the inferior needs to be
- backed up to the breakpoint address. */
- write_pc_pid (breakpoint_pc, ecs->ptid);
- }
- else
- {
- if (software_breakpoint_inserted_here_p (breakpoint_pc))
- /* The inferior was free running (i.e., no hardware
- single-step and no possibility of a false SIGTRAP) and
- hit a software breakpoint. */
- write_pc_pid (breakpoint_pc, ecs->ptid);
- }
+ /* When using hardware single-step, a SIGTRAP is reported for both
+ a completed single-step and a software breakpoint. Need to
+ differentiate between the two, as the latter needs adjusting
+ but the former does not.
+
+ The SIGTRAP can be due to a completed hardware single-step only if
+ - we didn't insert software single-step breakpoints
+ - the thread to be examined is still the current thread
+ - this thread is currently being stepped
+
+ If any of these events did not occur, we must have stopped due
+ to hitting a software breakpoint, and have to back up to the
+ breakpoint address.
+
+ As a special case, we could have hardware single-stepped a
+ software breakpoint. In this case (prev_pc == breakpoint_pc),
+ we also need to back up to the breakpoint address. */
+
+ if (singlestep_breakpoints_inserted_p
+ || !ptid_equal (ecs->ptid, inferior_ptid)
+ || !currently_stepping (ecs)
+ || prev_pc == breakpoint_pc)
+ write_pc_pid (breakpoint_pc, ecs->ptid);
}
}
case TARGET_WAITKIND_LOADED:
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_LOADED\n");
- /* Ignore gracefully during startup of the inferior, as it
- might be the shell which has just loaded some objects,
- otherwise add the symbols for the newly loaded objects. */
-#ifdef SOLIB_ADD
+ /* Ignore gracefully during startup of the inferior, as it might
+ be the shell which has just loaded some objects, otherwise
+ add the symbols for the newly loaded objects. Also ignore at
+ the beginning of an attach or remote session; we will query
+ the full list of libraries once the connection is
+ established. */
if (stop_soon == NO_STOP_QUIETLY)
{
+ int breakpoints_were_inserted;
+
/* Remove breakpoints, SOLIB_ADD might adjust
breakpoint addresses via breakpoint_re_set. */
+ breakpoints_were_inserted = breakpoints_inserted;
if (breakpoints_inserted)
remove_breakpoints ();
+ breakpoints_inserted = 0;
/* Check for any newly added shared libraries if we're
supposed to be adding them automatically. Switch
exec/process stratum, instead relying on the target stack
to propagate relevant changes (stop, section table
changed, ...) up to other layers. */
+#ifdef SOLIB_ADD
SOLIB_ADD (NULL, 0, ¤t_target, auto_solib_add);
+#else
+ solib_add (NULL, 0, ¤t_target, auto_solib_add);
+#endif
target_terminal_inferior ();
+ /* Try to reenable shared library breakpoints, additional
+ code segments in shared libraries might be mapped in now. */
+ re_enable_breakpoints_in_shlibs ();
+
+ /* If requested, stop when the dynamic linker notifies
+ gdb of events. This allows the user to get control
+ and place breakpoints in initializer routines for
+ dynamically loaded objects (among other things). */
+ if (stop_on_solib_events)
+ {
+ stop_stepping (ecs);
+ return;
+ }
+
+ /* NOTE drow/2007-05-11: This might be a good place to check
+ for "catch load". */
+
/* Reinsert breakpoints and continue. */
- if (breakpoints_inserted)
- insert_breakpoints ();
+ if (breakpoints_were_inserted)
+ {
+ insert_breakpoints ();
+ breakpoints_inserted = 1;
+ }
}
-#endif
- resume (0, TARGET_SIGNAL_0);
- prepare_to_wait (ecs);
- return;
+
+ /* If we are skipping through a shell, or through shared library
+ loading that we aren't interested in, resume the program. If
+ we're running the program normally, also resume. But stop if
+ we're attaching or setting up a remote connection. */
+ if (stop_soon == STOP_QUIETLY || stop_soon == NO_STOP_QUIETLY)
+ {
+ resume (0, TARGET_SIGNAL_0);
+ prepare_to_wait (ecs);
+ return;
+ }
+
+ break;
case TARGET_WAITKIND_SPURIOUS:
if (debug_infrun)
(LONGEST) ecs->ws.value.integer));
gdb_flush (gdb_stdout);
target_mourn_inferior ();
- singlestep_breakpoints_inserted_p = 0; /* SOFTWARE_SINGLE_STEP_P() */
+ singlestep_breakpoints_inserted_p = 0;
stop_print_frame = 0;
stop_stepping (ecs);
return;
target_mourn_inferior ();
print_stop_reason (SIGNAL_EXITED, stop_signal);
- singlestep_breakpoints_inserted_p = 0; /* SOFTWARE_SINGLE_STEP_P() */
+ singlestep_breakpoints_inserted_p = 0;
stop_stepping (ecs);
return;
if (stepping_past_singlestep_breakpoint)
{
- gdb_assert (SOFTWARE_SINGLE_STEP_P ()
- && singlestep_breakpoints_inserted_p);
+ gdb_assert (singlestep_breakpoints_inserted_p);
gdb_assert (ptid_equal (singlestep_ptid, ecs->ptid));
gdb_assert (!ptid_equal (singlestep_ptid, saved_singlestep_ptid));
if (!breakpoint_thread_match (stop_pc, ecs->ptid))
thread_hop_needed = 1;
}
- else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ else if (singlestep_breakpoints_inserted_p)
{
/* We have not context switched yet, so this should be true
no matter which thread hit the singlestep breakpoint. */
/* Saw a breakpoint, but it was hit by the wrong thread.
Just continue. */
- if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ if (singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
remove_single_step_breakpoints ();
return;
}
}
- else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ else if (singlestep_breakpoints_inserted_p)
{
sw_single_step_trap_p = 1;
ecs->random_signal = 0;
deprecated_context_hook (pid_to_thread_id (ecs->ptid));
}
- if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ if (singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
remove_single_step_breakpoints ();
will both be 0 if it doesn't work. */
find_pc_partial_function (stop_pc, &ecs->stop_func_name,
&ecs->stop_func_start, &ecs->stop_func_end);
- ecs->stop_func_start += DEPRECATED_FUNCTION_START_OFFSET;
+ ecs->stop_func_start
+ += gdbarch_deprecated_function_start_offset (current_gdbarch);
ecs->another_trap = 0;
bpstat_clear (&stop_bpstat);
stop_step = 0;
&& (stop_signal == TARGET_SIGNAL_ILL
|| stop_signal == TARGET_SIGNAL_SEGV
|| stop_signal == TARGET_SIGNAL_EMT))
- || stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_NO_SIGSTOP)
+ || stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_NO_SIGSTOP
+ || stop_soon == STOP_QUIETLY_REMOTE)
{
if (stop_signal == TARGET_SIGNAL_TRAP && stop_after_trap)
{
/* This is originated from start_remote(), start_inferior() and
shared libraries hook functions. */
- if (stop_soon == STOP_QUIETLY)
+ if (stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_REMOTE)
{
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: quietly stopped\n");
remove_breakpoints ();
breakpoints_inserted = 0;
if (!gdbarch_get_longjmp_target_p (current_gdbarch)
- || !gdbarch_get_longjmp_target (current_gdbarch, &jmp_buf_pc))
+ || !gdbarch_get_longjmp_target (current_gdbarch,
+ get_current_frame (), &jmp_buf_pc))
{
keep_going (ecs);
return;
switch (bpstat_ret)
{
case PRINT_UNKNOWN:
+ /* If we had hit a shared library event breakpoint,
+ bpstat_print would print out this message. If we hit
+ an OS-level shared library event, do the same
+ thing. */
+ if (last.kind == TARGET_WAITKIND_LOADED)
+ {
+ printf_filtered (_("Stopped due to shared library event\n"));
+ source_flag = SRC_LINE; /* something bogus */
+ do_frame_printing = 0;
+ break;
+ }
+
/* FIXME: cagney/2002-12-01: Given that a frame ID does
(or should) carry around the function and does (or
should) use that when doing a frame comparison. */
/* Save the function value return registers, if we care.
We might be about to restore their previous contents. */
if (proceed_to_finish)
- /* NB: The copy goes through to the target picking up the value of
- all the registers. */
- regcache_cpy (stop_registers, current_regcache);
+ {
+ /* This should not be necessary. */
+ if (stop_registers)
+ regcache_xfree (stop_registers);
+
+ /* NB: The copy goes through to the target picking up the value of
+ all the registers. */
+ stop_registers = regcache_dup (get_current_regcache ());
+ }
if (stop_stack_dummy)
{
CORE_ADDR step_resume_break_address;
int stop_after_trap;
int stop_soon;
- struct regcache *stop_registers;
/* These are here because if call_function_by_hand has written some
registers and then decides to call error(), we better not have changed
inf_status->restore_stack_info = restore_stack_info;
inf_status->proceed_to_finish = proceed_to_finish;
- inf_status->stop_registers = regcache_dup_no_passthrough (stop_registers);
-
- inf_status->registers = regcache_dup (current_regcache);
+ inf_status->registers = regcache_dup (get_current_regcache ());
inf_status->selected_frame_id = get_frame_id (get_selected_frame (NULL));
return inf_status;
breakpoint_proceeded = inf_status->breakpoint_proceeded;
proceed_to_finish = inf_status->proceed_to_finish;
- /* FIXME: Is the restore of stop_registers always needed. */
- regcache_xfree (stop_registers);
- stop_registers = inf_status->stop_registers;
-
/* The inferior can be gone if the user types "print exit(0)"
(and perhaps other times). */
if (target_has_execution)
/* NB: The register write goes through to the target. */
- regcache_cpy (current_regcache, inf_status->registers);
+ regcache_cpy (get_current_regcache (), inf_status->registers);
regcache_xfree (inf_status->registers);
/* FIXME: If we are being called after stopping in a function which
/* See save_inferior_status for info on stop_bpstat. */
bpstat_clear (&inf_status->stop_bpstat);
regcache_xfree (inf_status->registers);
- regcache_xfree (inf_status->stop_registers);
xfree (inf_status);
}
}
\f
-static void
-build_infrun (void)
-{
- stop_registers = regcache_xmalloc (current_gdbarch);
-}
-
void
_initialize_infrun (void)
{
int numsigs;
struct cmd_list_element *c;
- DEPRECATED_REGISTER_GDBARCH_SWAP (stop_registers);
- deprecated_register_gdbarch_swap (NULL, 0, build_infrun);
-
add_info ("signals", signals_info, _("\
What debugger does when program gets various signals.\n\
Specify a signal as argument to print info on that signal only."));