#include "annotate.h"
#include "symfile.h"
#include "top.h"
+#include "ui.h"
#include "inf-loop.h"
#include "regcache.h"
#include "value.h"
#include "gdbsupport/buildargv.h"
#include "extension.h"
#include "disasm.h"
+#include "interps.h"
/* Prototypes for local functions */
target_follow_fork (child_inf, child_ptid, fork_kind, follow_child,
detach_fork);
+ gdb::observers::inferior_forked.notify (parent_inf, child_inf, fork_kind);
+
/* target_follow_fork must leave the parent as the current inferior. If we
want to follow the child, we make it the current one below. */
gdb_assert (current_inferior () == parent_inf);
if (tp->control.step_resume_breakpoint)
{
breakpoint_re_set_thread (tp->control.step_resume_breakpoint);
- tp->control.step_resume_breakpoint->loc->enabled = 1;
+ tp->control.step_resume_breakpoint->first_loc ().enabled = 1;
}
/* Treat exception_resume breakpoints like step_resume breakpoints. */
if (tp->control.exception_resume_breakpoint)
{
breakpoint_re_set_thread (tp->control.exception_resume_breakpoint);
- tp->control.exception_resume_breakpoint->loc->enabled = 1;
+ tp->control.exception_resume_breakpoint->first_loc ().enabled = 1;
}
/* Reinsert all breakpoints in the child. The user may have set
previous incarnation of this process. */
no_shared_libraries (nullptr, 0);
- struct inferior *inf = current_inferior ();
+ inferior *execing_inferior = current_inferior ();
+ inferior *following_inferior;
if (follow_exec_mode_string == follow_exec_mode_new)
{
inferior's pid. Having two inferiors with the same pid would confuse
find_inferior_p(t)id. Transfer the terminal state and info from the
old to the new inferior. */
- inferior *new_inferior = add_inferior_with_spaces ();
-
- swap_terminal_info (new_inferior, inf);
- exit_inferior_silent (inf);
+ following_inferior = add_inferior_with_spaces ();
- new_inferior->pid = pid;
- target_follow_exec (new_inferior, ptid, exec_file_target);
+ swap_terminal_info (following_inferior, execing_inferior);
+ exit_inferior_silent (execing_inferior);
- /* We continue with the new inferior. */
- inf = new_inferior;
+ following_inferior->pid = pid;
}
else
{
+ /* follow-exec-mode is "same", we continue execution in the execing
+ inferior. */
+ following_inferior = execing_inferior;
+
/* The old description may no longer be fit for the new image.
E.g, a 64-bit process exec'ed a 32-bit process. Clear the
old description; we'll read a new one below. No need to do
around (its description is later cleared/refetched on
restart). */
target_clear_description ();
- target_follow_exec (inf, ptid, exec_file_target);
}
- gdb_assert (current_inferior () == inf);
- gdb_assert (current_program_space == inf->pspace);
+ target_follow_exec (following_inferior, ptid, exec_file_target);
+
+ gdb_assert (current_inferior () == following_inferior);
+ gdb_assert (current_program_space == following_inferior->pspace);
/* Attempt to open the exec file. SYMFILE_DEFER_BP_RESET is used
because the proper displacement for a PIE (Position Independent
Executable) main symbol file will only be computed by
solib_create_inferior_hook below. breakpoint_re_set would fail
to insert the breakpoints with the zero displacement. */
- try_open_exec_file (exec_file_host.get (), inf, SYMFILE_DEFER_BP_RESET);
+ try_open_exec_file (exec_file_host.get (), following_inferior,
+ SYMFILE_DEFER_BP_RESET);
/* If the target can specify a description, read it. Must do this
after flipping to the new executable (because the target supplied
registers. */
target_find_description ();
- gdb::observers::inferior_execd.notify (inf);
+ gdb::observers::inferior_execd.notify (execing_inferior, following_inferior);
breakpoint_re_set ();
}
static void
-infrun_inferior_execd (inferior *inf)
+infrun_inferior_execd (inferior *exec_inf, inferior *follow_inf)
{
/* If some threads where was doing a displaced step in this inferior at the
moment of the exec, they no longer exist. Even if the exec'ing thread
doing a displaced step, we don't want to to any fixup nor restore displaced
stepping buffer bytes. */
- inf->displaced_step_state.reset ();
+ follow_inf->displaced_step_state.reset ();
- for (thread_info *thread : inf->threads ())
+ for (thread_info *thread : follow_inf->threads ())
thread->displaced_step_state.reset ();
/* Since an in-line step is done with everything else stopped, if there was
thread. */
clear_step_over_info ();
- inf->thread_waiting_for_vfork_done = nullptr;
+ follow_inf->thread_waiting_for_vfork_done = nullptr;
}
/* If ON, and the architecture supports it, GDB will use displaced
user breakpoints at PC to trigger (again) when this
hits. */
insert_hp_step_resume_breakpoint_at_frame (get_current_frame ());
- gdb_assert (tp->control.step_resume_breakpoint->loc->permanent);
+ gdb_assert (tp->control.step_resume_breakpoint->first_loc ()
+ .permanent);
tp->step_after_step_resume_breakpoint = step;
}
&& !gdb_in_secondary_prompt_p (ui))
{
target_terminal::ours ();
- gdb::observers::sync_execution_done.notify ();
+ top_level_interpreter ()->on_sync_execution_done ();
ui->register_file_handler ();
}
}
gdb_assert (ecs.ws.kind () != TARGET_WAITKIND_IGNORE);
- /* Switch to the target that generated the event, so we can do
- target calls. */
- switch_to_target_no_thread (ecs.target);
+ /* Switch to the inferior that generated the event, so we can do
+ target calls. If the event was not associated to a ptid, */
+ if (ecs.ptid != null_ptid
+ && ecs.ptid != minus_one_ptid)
+ switch_to_inferior_no_thread (find_inferior_ptid (ecs.target, ecs.ptid));
+ else
+ switch_to_target_no_thread (ecs.target);
if (debug_infrun)
print_target_wait_results (minus_one_ptid, ecs.ptid, ecs.ws);
/* Support the --return-child-result option. */
return_child_result_value = ecs->ws.exit_status ();
- gdb::observers::exited.notify (ecs->ws.exit_status ());
+ interps_notify_exited (ecs->ws.exit_status ());
}
else
{
"signal number.");
}
- gdb::observers::signal_exited.notify (ecs->ws.sig ());
+ interps_notify_signal_exited (ecs->ws.sig ());
}
gdb_flush (gdb_stdout);
list yet at this point. */
child_regcache
- = get_thread_arch_aspace_regcache (parent_inf->process_target (),
+ = get_thread_arch_aspace_regcache (parent_inf,
ecs->ws.child_ptid (),
gdbarch,
parent_inf->aspace);
if (handle_stop_requested (ecs))
return;
- gdb::observers::no_history.notify ();
+ interps_notify_no_history ();
stop_waiting (ecs);
return;
}
return 0;
}
+/* See infrun.h. */
+
+void
+notify_signal_received (gdb_signal sig)
+{
+ interps_notify_signal_received (sig);
+ gdb::observers::signal_received.notify (sig);
+}
+
+/* See infrun.h. */
+
+void
+notify_normal_stop (bpstat *bs, int print_frame)
+{
+ interps_notify_normal_stop (bs, print_frame);
+ gdb::observers::normal_stop.notify (bs, print_frame);
+}
+
+/* See infrun.h. */
+
+void notify_user_selected_context_changed (user_selected_what selection)
+{
+ interps_notify_user_selected_context_changed (selection);
+ gdb::observers::user_selected_context_changed.notify (selection);
+}
+
/* Come here when the program has stopped with a signal. */
static void
{
/* The signal table tells us to print about this signal. */
target_terminal::ours_for_output ();
- gdb::observers::signal_received.notify (ecs->event_thread->stop_signal ());
+ notify_signal_received (ecs->event_thread->stop_signal ());
target_terminal::inferior ();
}
= ecs->event_thread->control.step_resume_breakpoint;
if (sr_bp != nullptr
- && sr_bp->loc->permanent
+ && sr_bp->first_loc ().permanent
&& sr_bp->type == bp_hp_step_resume
- && sr_bp->loc->address == ecs->event_thread->prev_pc)
+ && sr_bp->first_loc ().address == ecs->event_thread->prev_pc)
{
infrun_debug_printf ("stepped permanent breakpoint, stopped in handler");
delete_step_resume_breakpoint (ecs->event_thread);
the interpreters, through observers. Interpreters then call these
with whatever uiout is right. */
-void
-print_end_stepping_range_reason (struct ui_out *uiout)
-{
- /* For CLI-like interpreters, print nothing. */
-
- if (uiout->is_mi_like_p ())
- {
- uiout->field_string ("reason",
- async_reason_lookup (EXEC_ASYNC_END_STEPPING_RANGE));
- }
-}
-
void
print_signal_exited_reason (struct ui_out *uiout, enum gdb_signal siggnal)
{
update_thread_list ();
if (last.kind () == TARGET_WAITKIND_STOPPED && stopped_by_random_signal)
- gdb::observers::signal_received.notify (inferior_thread ()->stop_signal ());
+ notify_signal_received (inferior_thread ()->stop_signal ());
/* As with the notification of thread events, we want to delay
notifying the user that we've switched thread context until
/* Notify observers about the stop. This is where the interpreters
print the stop event. */
- if (inferior_ptid != null_ptid)
- gdb::observers::normal_stop.notify (inferior_thread ()->control.stop_bpstat,
- stop_print_frame);
- else
- gdb::observers::normal_stop.notify (nullptr, stop_print_frame);
-
+ notify_normal_stop ((inferior_ptid != null_ptid
+ ? inferior_thread ()->control.stop_bpstat
+ : nullptr),
+ stop_print_frame);
annotate_stopped ();
if (target_has_execution ())