switch inferior/thread before calling target methods

Once each inferior has its own target stack, we'll need to make sure
that the right inferior is selected before we call into target
methods.

It kind of sounds worse than it is in practice.  Not that many places
need to be concerned.

In thread.c, we add a new switch_to_thread_if_alive function that
centralizes the switching before calls to target_thread_alive.  Other
cases are handled with explicit switching.

gdb/ChangeLog:
2020-01-10  Pedro Alves  <palves@redhat.com>

	* gdbthread.h (scoped_restore_current_thread)
	<dont_restore, restore, m_dont_restore>: Declare.
	* thread.c (thread_alive): Add assertion.  Return bool.
	(switch_to_thread_if_alive): New.
	(prune_threads): Switch inferior/thread.
	(print_thread_info_1): Switch thread before calling target methods.
	(scoped_restore_current_thread::restore): New, factored out from
	...
	(scoped_restore_current_thread::~scoped_restore_current_thread):
	... this.
	(scoped_restore_current_thread::scoped_restore_current_thread):
	Add assertion.
	(thread_apply_all_command, thread_select): Use
	switch_to_thread_if_alive.
	* infrun.c (proceed, restart_threads, handle_signal_stop)
	(switch_back_to_stepped_thread): Switch current thread before
	calling target methods.
This commit is contained in:
Pedro Alves
2020-01-10 20:05:48 +00:00
parent db2d40f7d0
commit f3f8ece4b1
3 changed files with 86 additions and 22 deletions

View File

@@ -2940,6 +2940,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
{
for (thread_info *tp : all_non_exited_threads (resume_ptid))
{
switch_to_thread_no_regs (tp);
/* Ignore the current thread here. It's handled
afterwards. */
if (tp == cur_thr)
@@ -2957,6 +2959,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
thread_step_over_chain_enqueue (tp);
}
switch_to_thread (cur_thr);
}
/* Enqueue the current thread last, so that we move all other
@@ -2993,6 +2997,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
Start all other threads that are implicitly resumed too. */
for (thread_info *tp : all_non_exited_threads (resume_ptid))
{
switch_to_thread_no_regs (tp);
if (tp->resumed)
{
if (debug_infrun)
@@ -4377,6 +4383,7 @@ stop_all_threads (void)
"infrun: %s executing, "
"need stop\n",
target_pid_to_str (t->ptid).c_str ());
switch_to_thread_no_regs (t);
target_stop (t->ptid);
t->stop_requested = 1;
}
@@ -5221,6 +5228,8 @@ restart_threads (struct thread_info *event_thread)
for (thread_info *tp : all_non_exited_threads ())
{
switch_to_thread_no_regs (tp);
if (tp == event_thread)
{
if (debug_infrun)
@@ -5479,9 +5488,8 @@ handle_signal_stop (struct execution_control_state *ecs)
{
struct regcache *regcache = get_thread_regcache (ecs->event_thread);
struct gdbarch *reg_gdbarch = regcache->arch ();
scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
inferior_ptid = ecs->ptid;
switch_to_thread (ecs->event_thread);
fprintf_unfiltered (gdb_stdlog, "infrun: stop_pc = %s\n",
paddress (reg_gdbarch,
@@ -6924,6 +6932,8 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
for (thread_info *tp : all_non_exited_threads ())
{
switch_to_thread_no_regs (tp);
/* Ignore threads of processes the caller is not
resuming. */
if (!sched_multi
@@ -6975,6 +6985,8 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
return 1;
}
}
switch_to_thread (ecs->event_thread);
}
return 0;