GDBserver: don't resume all threads if the Hc thread disapears
authorPedro Alves <palves@redhat.com>
Wed, 12 Nov 2014 11:17:39 +0000 (11:17 +0000)
committerPedro Alves <palves@redhat.com>
Wed, 12 Nov 2014 11:30:49 +0000 (11:30 +0000)
commitc2c118cfe13264f5638f9e3924c7fd05a293ad40
tree8ac7652340f2430f8e8d35f9da9bbd953de8520c
parent78708b7c8ccc2138880217de9bd60eceff683f10
GDBserver: don't resume all threads if the Hc thread disapears

There's code in linux_wait_1 that resumes all threads if the Hc thread
disappears.  It's the wrong thing to do, as GDB has told GDBserver to
resume only one thread, because e.g., the user has scheduler-locking
enabled, or because GDB was stepping the program over a breakpoint.
Resuming all threads behind GDB's back can't be good in either case.

The right thing to do is to detect that that the (only) resumed thread
is gone, and let GDB know about it.  The Linux backend is already
doing that nowadays, since:

 commit fa96cb382c12b099675c5cc238aaa7352a3fd3d7
 Author:     Pedro Alves <palves@redhat.com>
 AuthorDate: Thu Feb 27 14:30:08 2014 +0000

     Teach GDBserver's Linux backend about no unwaited-for children (TARGET_WAITKIND_NO_RESUMED).

The backend detects that all resumed threads have disappeared, and
returns TARGET_WAITKIND_NO_RESUMED to the core of GDBserver, which
then reports an error to GDB.

There's no need to frob the passed in ptid to wait for the continue
thread either -- linux_wait_for_event only returns events for resumed
threads.

The badness (of resuming threads) can actually be observed in the
testsuite, if we force-disable vCont support in GDBserver -- before
the patch, gdb.threads/no-unwaited-for-left.exp hangs if we disable
vCont:

 (gdb) continue
 Continuing.
 FAIL: gdb.threads/no-unwaited-for-left.exp: continue to breakpoint: break-here (timeout)
 ... more cascading timeouts ....

After the patch, gdb.threads/no-unwaited-for-left.exp behaves the same
with or without vCont support:

 (gdb) continue
 Continuing.
 [New Thread 32226]
 [Switching to Thread 32226]

 Breakpoint 2, thread_a (arg=0x0) at /home/pedro/gdb/mygit/build/../src/gdb/testsuite/gdb.threads/no-unwaited-for-left.c:28
 28   return 0; /* break-here */
 (gdb) PASS: gdb.threads/no-unwaited-for-left.exp: continue to breakpoint: break-here
...
 continue
 Continuing.
 warning: Remote failure reply: E.No unwaited-for children left.

 [Thread 32222] #1 stopped.
 (gdb) FAIL: gdb.threads/no-unwaited-for-left.exp: continue stops when the main thread exits

Overall, this is also good for getting rid of a RSP detail from the backend.

gdb/gdbserver/
2014-11-12  Pedro Alves  <palves@redhat.com>

* linux-low.c (linux_wait_1): Don't force a wait for the Hc
thread, and don't resume all threads if the Hc thread has exited.
gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-low.c