Make handle_no_resumed transfer terminal
authorPedro Alves <pedro@palves.net>
Sat, 4 Jul 2020 19:51:36 +0000 (20:51 +0100)
committerPedro Alves <palves@redhat.com>
Fri, 10 Jul 2020 22:50:39 +0000 (23:50 +0100)
commitd6cc5d980a902d273d424c49fc55e77757c3a05d
tree4c08ab5c21adbe84c357e708b682e9be6a974c65
parent7d3badc6a88b510f96c9aa0bab8f3375292d23bf
Make handle_no_resumed transfer terminal

Let's consider the same use case as in the previous commit:

Say you have two inferiors 1 and 2, each connected to a different
target, A and B.

Now say you set inferior 2 running, with "continue &".

Now you select a thread of inferior 1, say thread 1.2, and continue in
the foreground.  All other threads of inferior 1 are left stopped.
Thread 1.2 exits, and thus target A has no other resumed thread, so it
reports TARGET_WAITKIND_NO_RESUMED.

At this point, because the threads of inferior 2 are still executing
the TARGET_WAITKIND_NO_RESUMED event is ignored.

Now, the user types Ctrl-C.  Because GDB had previously put inferior 1
in the foreground, the kernel sends the SIGINT to that inferior.
However, no thread in that inferior is executing right now, so ptrace
never intercepts the SIGINT -- it is never dequeued by any thread.
The result is that GDB's CLI is stuck.  There's no way to get back the
prompt (unless inferior 2 happens to report some event).

The fix in this commit is to make handle_no_resumed give the terminal
to some other inferior that still has threads executing so that a
subsequent Ctrl-C reaches that target first (and then GDB intercepts
the SIGINT).  This is a bit hacky, but seems like the best we can do
with the current design.

I think that putting all native inferiors in their own session would
help fixing this in a clean way, since with that a Ctrl-C on GDB's
terminal will _always_ reach GDB first, and then GDB can decide how to
pause the inferior.  But that's a much larger change.

The testcase added by the following patch needs this fix.

gdb/ChangeLog:

PR gdb/26199
* infrun.c (handle_no_resumed): Transfer terminal to inferior with
executing threads.
gdb/ChangeLog
gdb/infrun.c