diff options
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r-- | gdb/infrun.c | 97 |
1 files changed, 52 insertions, 45 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c index 4687ee6..05bf6ab 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1,7 +1,7 @@ /* Target-struct-independent code to start (run) and stop an inferior process. - Copyright (C) 1986-2024 Free Software Foundation, Inc. + Copyright (C) 1986-2025 Free Software Foundation, Inc. This file is part of GDB. @@ -58,7 +58,6 @@ #include "target-descriptions.h" #include "target-dcache.h" #include "terminal.h" -#include "solist.h" #include "gdbsupport/event-loop.h" #include "thread-fsm.h" #include "gdbsupport/enum-flags.h" @@ -473,6 +472,7 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"), inferior *parent_inf = current_inferior (); inferior *child_inf = nullptr; + bool child_has_new_pspace = false; gdb_assert (parent_inf->thread_waiting_for_vfork_done == nullptr); @@ -537,6 +537,7 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"), else { child_inf->pspace = new program_space (new_address_space ()); + child_has_new_pspace = true; child_inf->aspace = child_inf->pspace->aspace; child_inf->removable = true; clone_program_space (child_inf->pspace, parent_inf->pspace); @@ -626,6 +627,7 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"), else { child_inf->pspace = new program_space (new_address_space ()); + child_has_new_pspace = true; child_inf->aspace = child_inf->pspace->aspace; child_inf->removable = true; child_inf->symfile_flags = SYMFILE_NO_READ; @@ -724,7 +726,8 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"), maybe_restore.emplace (); switch_to_thread (*child_inf->threads ().begin ()); - post_create_inferior (0); + + post_create_inferior (0, child_has_new_pspace); } return false; @@ -1322,6 +1325,7 @@ follow_exec (ptid_t ptid, const char *exec_file_target) we don't want those to be satisfied by the libraries of the previous incarnation of this process. */ no_shared_libraries (current_program_space); + current_program_space->unset_solib_ops (); inferior *execing_inferior = current_inferior (); inferior *following_inferior; @@ -1378,6 +1382,8 @@ follow_exec (ptid_t ptid, const char *exec_file_target) registers. */ target_find_description (); + current_program_space->set_solib_ops + (gdbarch_make_solib_ops (following_inferior->arch ())); gdb::observers::inferior_execd.notify (execing_inferior, following_inferior); breakpoint_re_set (); @@ -1699,15 +1705,12 @@ show_can_use_displaced_stepping (struct ui_file *file, int from_tty, "to step over breakpoints is %s.\n"), value); } -/* Return true if the gdbarch implements the required methods to use - displaced stepping. */ +/* Return true if the target behind THREAD supports displaced stepping. */ static bool -gdbarch_supports_displaced_stepping (gdbarch *arch) +target_supports_displaced_stepping (thread_info *thread) { - /* Only check for the presence of `prepare`. The gdbarch verification ensures - that if `prepare` is provided, so is `finish`. */ - return gdbarch_displaced_step_prepare_p (arch); + return thread->inf->top_target ()->supports_displaced_step (thread); } /* Return non-zero if displaced stepping can/should be used to step @@ -1726,11 +1729,8 @@ use_displaced_stepping (thread_info *tp) && !target_is_non_stop_p ()) return false; - gdbarch *gdbarch = get_thread_regcache (tp)->arch (); - - /* If the architecture doesn't implement displaced stepping, don't use - it. */ - if (!gdbarch_supports_displaced_stepping (gdbarch)) + /* If the target doesn't support displaced stepping, don't use it. */ + if (!target_supports_displaced_stepping (tp)) return false; /* If recording, don't use displaced stepping. */ @@ -1784,9 +1784,9 @@ displaced_step_prepare_throw (thread_info *tp) displaced_step_thread_state &disp_step_thread_state = tp->displaced_step_state; - /* We should never reach this function if the architecture does not + /* We should never reach this function if the target does not support displaced stepping. */ - gdb_assert (gdbarch_supports_displaced_stepping (gdbarch)); + gdb_assert (target_supports_displaced_stepping (tp)); /* Nor if the thread isn't meant to step over a breakpoint. */ gdb_assert (tp->control.trap_expected); @@ -1847,8 +1847,8 @@ displaced_step_prepare_throw (thread_info *tp) paddress (gdbarch, original_pc), dislen); } - displaced_step_prepare_status status - = gdbarch_displaced_step_prepare (gdbarch, tp, displaced_pc); + auto status + = tp->inf->top_target ()->displaced_step_prepare (tp, displaced_pc); if (status == DISPLACED_STEP_PREPARE_STATUS_CANT) { @@ -2028,6 +2028,7 @@ displaced_step_finish (thread_info *event_thread, { /* Check whether the parent is displaced stepping. */ inferior *parent_inf = event_thread->inf; + target_ops *top_target = parent_inf->top_target (); /* If this was a fork/vfork/clone, this event indicates that the displaced stepping of the syscall instruction has been done, so @@ -2044,15 +2045,10 @@ displaced_step_finish (thread_info *event_thread, gdbarch_displaced_step_restore_all_in_ptid. This is not enforced during gdbarch validation to support architectures which support displaced stepping but not forks. */ - if (event_status.kind () == TARGET_WAITKIND_FORKED) - { - struct regcache *parent_regcache = get_thread_regcache (event_thread); - struct gdbarch *gdbarch = parent_regcache->arch (); - - if (gdbarch_supports_displaced_stepping (gdbarch)) - gdbarch_displaced_step_restore_all_in_ptid - (gdbarch, parent_inf, event_status.child_ptid ()); - } + if (event_status.kind () == TARGET_WAITKIND_FORKED + && target_supports_displaced_stepping (event_thread)) + top_target->displaced_step_restore_all_in_ptid + (parent_inf, event_status.child_ptid ()); displaced_step_thread_state *displaced = &event_thread->displaced_step_state; @@ -2075,9 +2071,7 @@ displaced_step_finish (thread_info *event_thread, /* Do the fixup, and release the resources acquired to do the displaced step. */ - displaced_step_finish_status status - = gdbarch_displaced_step_finish (displaced->get_original_gdbarch (), - event_thread, event_status); + auto status = top_target->displaced_step_finish (event_thread, event_status); if (event_status.kind () == TARGET_WAITKIND_FORKED || event_status.kind () == TARGET_WAITKIND_VFORKED @@ -3831,7 +3825,7 @@ start_remote (int from_tty) /* Now that the inferior has stopped, do any bookkeeping like loading shared libraries. We want to do this before normal_stop, so that the displayed frame is up to date. */ - post_create_inferior (from_tty); + post_create_inferior (from_tty, true); normal_stop (); } @@ -3984,7 +3978,8 @@ delete_just_stopped_threads_single_step_breakpoints (void) void print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid, - const struct target_waitstatus &ws) + const struct target_waitstatus &ws, + process_stratum_target *proc_target) { infrun_debug_printf ("target_wait (%s [%s], status) =", waiton_ptid.to_string ().c_str (), @@ -3993,6 +3988,20 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid, result_ptid.to_string ().c_str (), target_pid_to_str (result_ptid).c_str ()); infrun_debug_printf (" %s", ws.to_string ().c_str ()); + + if (proc_target != nullptr) + infrun_debug_printf (" from target %d (%s)", + proc_target->connection_number, + proc_target->shortname ()); +} + +/* Wrapper for print_target_wait_results above for convenience. */ + +static void +print_target_wait_results (ptid_t waiton_ptid, + const execution_control_state &ecs) +{ + print_target_wait_results (waiton_ptid, ecs.ptid, ecs.ws, ecs.target); } /* Select a thread at random, out of those which are resumed and have @@ -4344,7 +4353,8 @@ prepare_for_detach (void) event.ptid = do_target_wait_1 (inf, pid_ptid, &event.ws, 0); if (debug_infrun) - print_target_wait_results (pid_ptid, event.ptid, event.ws); + print_target_wait_results (pid_ptid, event.ptid, event.ws, + event.target); handle_one (event); } @@ -4400,7 +4410,7 @@ wait_for_inferior (inferior *inf) ecs.target = inf->process_target (); if (debug_infrun) - print_target_wait_results (minus_one_ptid, ecs.ptid, ecs.ws); + print_target_wait_results (minus_one_ptid, ecs); /* Now figure out what to do with the result of the result. */ handle_inferior_event (&ecs); @@ -4681,7 +4691,7 @@ fetch_inferior_event () switch_to_target_no_thread (ecs.target); if (debug_infrun) - print_target_wait_results (minus_one_ptid, ecs.ptid, ecs.ws); + print_target_wait_results (minus_one_ptid, ecs); /* If an error happens while handling the event, propagate GDB's knowledge of the executing state to the frontend/user running @@ -5244,7 +5254,8 @@ poll_one_curr_target (struct target_waitstatus *ws) event_ptid = target_wait (minus_one_ptid, ws, TARGET_WNOHANG); if (debug_infrun) - print_target_wait_results (minus_one_ptid, event_ptid, *ws); + print_target_wait_results (minus_one_ptid, event_ptid, *ws, + current_inferior ()->process_target ()); return event_ptid; } @@ -6683,9 +6694,8 @@ restart_threads (struct thread_info *event_thread, inferior *inf) /* Callback for iterate_over_threads. Find a resumed thread that has a pending waitstatus. */ -static int -resumed_thread_with_pending_status (struct thread_info *tp, - void *arg) +static bool +resumed_thread_with_pending_status (struct thread_info *tp) { return tp->resumed () && tp->has_pending_waitstatus (); } @@ -6763,8 +6773,7 @@ finish_step_over (struct execution_control_state *ecs) if (ecs->ws.kind () == TARGET_WAITKIND_THREAD_EXITED) return 0; - pending = iterate_over_threads (resumed_thread_with_pending_status, - nullptr); + pending = iterate_over_threads (resumed_thread_with_pending_status); if (pending != nullptr) { struct thread_info *tp = ecs->event_thread; @@ -9458,7 +9467,7 @@ struct stop_context ptid_t ptid; - /* If stopp for a thread event, this is the thread that caused the + /* If stopped for a thread event, this is the thread that caused the stop. */ thread_info_ref thread; @@ -10529,9 +10538,7 @@ infrun_thread_ptid_changed () #endif /* GDB_SELF_TEST */ -void _initialize_infrun (); -void -_initialize_infrun () +INIT_GDB_FILE (infrun) { struct cmd_list_element *c; |