Skip to content

Commit

Permalink
detach with in-line step over in progress
Browse files Browse the repository at this point in the history
A following patch will add a testcase that has a number of threads
constantly stepping over a breakpoint, and then has GDB detach the
process.  That testcase exercises both "set displaced-stepping
on/off".  Testing with "set displaced-stepping off" reveals that GDB
does not handle the case of the user typing "detach" just while some
thread is in the middle of an in-line step over.  If that thread
belongs to the inferior that is being detached, then the step-over
never finishes, and threads of other inferiors are never re-resumed.
This fixes it.

gdb/ChangeLog:

	* infrun.c (struct step_over_info): Initialize fields.
	(prepare_for_detach): Handle ongoing in-line step over.
  • Loading branch information
palves committed Feb 3, 2021
1 parent e87f0fe commit ac7d717
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 4 deletions.
5 changes: 5 additions & 0 deletions gdb/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
2021-02-03 Pedro Alves <pedro@palves.net>

* infrun.c (struct step_over_info): Initialize fields.
(prepare_for_detach): Handle ongoing in-line step over.

2021-02-03 Pedro Alves <pedro@palves.net>

* linux-nat.c (linux_nat_target::detach): Remove breakpoints
Expand Down
45 changes: 41 additions & 4 deletions gdb/infrun.c
Original file line number Diff line number Diff line change
Expand Up @@ -1261,15 +1261,15 @@ struct step_over_info
and address of the instruction the breakpoint is set at. We'll
skip inserting all breakpoints here. Valid iff ASPACE is
non-NULL. */
const address_space *aspace;
CORE_ADDR address;
const address_space *aspace = nullptr;
CORE_ADDR address = 0;

/* The instruction being stepped over triggers a nonsteppable
watchpoint. If true, we'll skip inserting watchpoints. */
int nonsteppable_watchpoint_p;
int nonsteppable_watchpoint_p = 0;

/* The thread's global number. */
int thread;
int thread = -1;
};

/* The step-over info of the location that is being stepped over.
Expand Down Expand Up @@ -3566,6 +3566,7 @@ struct wait_one_event
};

static bool handle_one (const wait_one_event &event);
static void restart_threads (struct thread_info *event_thread);

/* Prepare and stabilize the inferior for detaching it. E.g.,
detaching while a thread is displaced stepping is a recipe for
Expand Down Expand Up @@ -3593,6 +3594,35 @@ prepare_for_detach (void)
global_thread_step_over_chain_remove (tp);
}

/* If we were already in the middle of an inline step-over, and the
thread stepping belongs to the inferior we're detaching, we need
to restart the threads of other inferiors. */
if (step_over_info.thread != -1)
{
infrun_debug_printf ("inline step-over in-process while detaching");

thread_info *thr = find_thread_global_id (step_over_info.thread);
if (thr->inf == inf)
{
/* Since we removed threads of INF from the step-over chain,
we know this won't start a step-over for INF. */
clear_step_over_info ();

if (target_is_non_stop_p ())
{
/* Start a new step-over in another thread if there's
one that needs it. */
start_step_over ();

/* Restart all other threads (except the
previously-stepping thread, since that one is still
running). */
if (!step_over_info_valid_p ())
restart_threads (thr);
}
}
}

if (displaced_step_in_progress (inf))
{
infrun_debug_printf ("displaced-stepping in-process while detaching");
Expand Down Expand Up @@ -5528,6 +5558,13 @@ restart_threads (struct thread_info *event_thread)

for (thread_info *tp : all_non_exited_threads ())
{
if (tp->inf->detaching)
{
infrun_debug_printf ("restart threads: [%s] inferior detaching",
target_pid_to_str (tp->ptid).c_str ());
continue;
}

switch_to_thread_no_regs (tp);

if (tp == event_thread)
Expand Down

0 comments on commit ac7d717

Please sign in to comment.