From 18493a005acc8fbccbee4a2b767334eaaf636dd2 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Thu, 18 Jun 2020 21:28:21 +0100 Subject: [PATCH] Don't write to inferior_ptid in infrun.c gdb/ChangeLog: 2020-06-18 Pedro Alves * infrun.c (generic_mourn_inferior): Use switch_to_thread instead of writing to inferior_ptid. (scoped_restore_exited_inferior): Delete. (handle_vfork_child_exec_or_exit): Simplify using scoped_restore_current_pspace_and_thread. Use switch_to_thread instead of writing to inferior_ptid. (THREAD_STOPPED_BY): Delete. (thread_stopped_by_watchpoint, thread_stopped_by_sw_breakpoint) (thread_stopped_by_hw_breakpoint): Delete. (save_waitstatus): Use scoped_restore_current_thread+switch_to_thread, and call target_stopped_by_watchpoint instead of thread_stopped_by_watchpoint, target_stopped_by_sw_breakpoint instead of thread_stopped_by_sw_breakpoint, and target_stopped_by_hw_breakpoint instead of thread_stopped_by_hw_breakpoint. (handle_inferior_event) : Don't write to inferior_ptid directly, nor set_current_inferior/set_current_program_space. Use switch_to_thread / switch_to_inferior_no_thread instead. --- gdb/ChangeLog | 24 ++++++++++++ gdb/infrun.c | 101 ++++++++++++++++++++------------------------------ 2 files changed, 64 insertions(+), 61 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2890b1f662a..3af6af35de8 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,27 @@ +2020-06-18 Pedro Alves + + * infrun.c (generic_mourn_inferior): Use switch_to_thread instead + of writing to inferior_ptid. + (scoped_restore_exited_inferior): Delete. + (handle_vfork_child_exec_or_exit): Simplify using + scoped_restore_current_pspace_and_thread. Use switch_to_thread + instead of writing to inferior_ptid. + (THREAD_STOPPED_BY): Delete. + (thread_stopped_by_watchpoint, thread_stopped_by_sw_breakpoint) + (thread_stopped_by_hw_breakpoint): Delete. + (save_waitstatus): Use + scoped_restore_current_thread+switch_to_thread, and call + target_stopped_by_watchpoint instead of + thread_stopped_by_watchpoint, target_stopped_by_sw_breakpoint + instead of thread_stopped_by_sw_breakpoint, and + target_stopped_by_hw_breakpoint instead of + thread_stopped_by_hw_breakpoint. + (handle_inferior_event) + : Don't write to + inferior_ptid directly, nor + set_current_inferior/set_current_program_space. Use + switch_to_thread / switch_to_inferior_no_thread instead. + 2020-06-18 Pedro Alves * target.c (generic_mourn_inferior): Use switch_to_no_thread diff --git a/gdb/infrun.c b/gdb/infrun.c index 95fc3bfe459..7bc405f1038 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -485,8 +485,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \ switch_to_no_thread (); child_inf->symfile_flags = SYMFILE_NO_READ; push_target (parent_inf->process_target ()); - add_thread_silent (child_inf->process_target (), child_ptid); - inferior_ptid = child_ptid; + thread_info *child_thr + = add_thread_silent (child_inf->process_target (), child_ptid); /* If this is a vfork child, then the address-space is shared with the parent. */ @@ -504,6 +504,11 @@ holding the child stopped. Try \"set detach-on-fork\" or \ child_inf->pending_detach = 0; parent_inf->vfork_child = child_inf; parent_inf->pending_detach = 0; + + /* Now that the inferiors and program spaces are all + wired up, we can switch to the child thread (which + switches inferior and program space too). */ + switch_to_thread (child_thr); } else { @@ -513,6 +518,10 @@ holding the child stopped. Try \"set detach-on-fork\" or \ set_current_program_space (child_inf->pspace); clone_program_space (child_inf->pspace, parent_inf->pspace); + /* solib_create_inferior_hook relies on the current + thread. */ + switch_to_thread (child_thr); + /* Let the shared library layer (e.g., solib-svr4) learn about this new process, relocate the cloned exec, pull in shared libraries, and install the solib event @@ -628,8 +637,7 @@ holding the child stopped. Try \"set detach-on-fork\" or \ push_target (target); } - add_thread_silent (target, child_ptid); - inferior_ptid = child_ptid; + thread_info *child_thr = add_thread_silent (target, child_ptid); /* If this is a vfork child, then the address-space is shared with the parent. If we detached from the parent, then we can @@ -657,6 +665,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \ the core, this wouldn't be required. */ solib_create_inferior_hook (0); } + + switch_to_thread (child_thr); } return target_follow_fork (follow_child, detach_fork); @@ -904,22 +914,6 @@ proceed_after_vfork_done (struct thread_info *thread, return 0; } -/* Save/restore inferior_ptid, current program space and current - inferior. Only use this if the current context points at an exited - inferior (and therefore there's no current thread to save). */ -class scoped_restore_exited_inferior -{ -public: - scoped_restore_exited_inferior () - : m_saved_ptid (&inferior_ptid) - {} - -private: - scoped_restore_tmpl m_saved_ptid; - scoped_restore_current_program_space m_pspace; - scoped_restore_current_inferior m_inferior; -}; - /* Called whenever we notice an exec or exit event, to handle detaching or resuming a vfork parent. */ @@ -942,7 +936,6 @@ handle_vfork_child_exec_or_exit (int exec) time. */ if (vfork_parent->pending_detach) { - struct thread_info *tp; struct program_space *pspace; struct address_space *aspace; @@ -950,20 +943,10 @@ handle_vfork_child_exec_or_exit (int exec) vfork_parent->pending_detach = 0; - gdb::optional - maybe_restore_inferior; - gdb::optional - maybe_restore_thread; - - /* If we're handling a child exit, then inferior_ptid points - at the inferior's pid, not to a thread. */ - if (!exec) - maybe_restore_inferior.emplace (); - else - maybe_restore_thread.emplace (); + scoped_restore_current_pspace_and_thread restore_thread; /* We're letting loose of the parent. */ - tp = any_live_thread_of_inferior (vfork_parent); + thread_info *tp = any_live_thread_of_inferior (vfork_parent); switch_to_thread (tp); /* We're about to detach from the parent, which implicitly @@ -1032,11 +1015,11 @@ handle_vfork_child_exec_or_exit (int exec) go ahead and create a new one for this exiting inferior. */ - /* Switch to null_ptid while running clone_program_space, so + /* Switch to no-thread while running clone_program_space, so that clone_program_space doesn't want to read the selected frame of a dead process. */ - scoped_restore restore_ptid - = make_scoped_restore (&inferior_ptid, null_ptid); + scoped_restore_current_thread restore_thread; + switch_to_no_thread (); inf->pspace = new program_space (maybe_new_address_space ()); inf->aspace = inf->pspace->aspace; @@ -4622,25 +4605,6 @@ wait_one () } } -/* Generate a wrapper for target_stopped_by_REASON that works on PTID - instead of the current thread. */ -#define THREAD_STOPPED_BY(REASON) \ -static int \ -thread_stopped_by_ ## REASON (ptid_t ptid) \ -{ \ - scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid); \ - inferior_ptid = ptid; \ - \ - return target_stopped_by_ ## REASON (); \ -} - -/* Generate thread_stopped_by_watchpoint. */ -THREAD_STOPPED_BY (watchpoint) -/* Generate thread_stopped_by_sw_breakpoint. */ -THREAD_STOPPED_BY (sw_breakpoint) -/* Generate thread_stopped_by_hw_breakpoint. */ -THREAD_STOPPED_BY (hw_breakpoint) - /* Save the thread's event and stop reason to process it later. */ static void @@ -4672,19 +4636,22 @@ save_waitstatus (struct thread_info *tp, const target_waitstatus *ws) adjust_pc_after_break (tp, &tp->suspend.waitstatus); - if (thread_stopped_by_watchpoint (tp->ptid)) + scoped_restore_current_thread restore_thread; + switch_to_thread (tp); + + if (target_stopped_by_watchpoint ()) { tp->suspend.stop_reason = TARGET_STOPPED_BY_WATCHPOINT; } else if (target_supports_stopped_by_sw_breakpoint () - && thread_stopped_by_sw_breakpoint (tp->ptid)) + && target_stopped_by_sw_breakpoint ()) { tp->suspend.stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT; } else if (target_supports_stopped_by_hw_breakpoint () - && thread_stopped_by_hw_breakpoint (tp->ptid)) + && target_stopped_by_hw_breakpoint ()) { tp->suspend.stop_reason = TARGET_STOPPED_BY_HW_BREAKPOINT; @@ -5338,9 +5305,21 @@ handle_inferior_event (struct execution_control_state *ecs) case TARGET_WAITKIND_EXITED: case TARGET_WAITKIND_SIGNALLED: - inferior_ptid = ecs->ptid; - set_current_inferior (find_inferior_ptid (ecs->target, ecs->ptid)); - set_current_program_space (current_inferior ()->pspace); + { + /* Depending on the system, ecs->ptid may point to a thread or + to a process. On some targets, target_mourn_inferior may + need to have access to the just-exited thread. That is the + case of GNU/Linux's "checkpoint" support, for example. + Call the switch_to_xxx routine as appropriate. */ + thread_info *thr = find_thread_ptid (ecs->target, ecs->ptid); + if (thr != nullptr) + switch_to_thread (thr); + else + { + inferior *inf = find_inferior_ptid (ecs->target, ecs->ptid); + switch_to_inferior_no_thread (inf); + } + } handle_vfork_child_exec_or_exit (0); target_terminal::ours (); /* Must do this before mourn anyway. */ -- 2.30.2