mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-03 04:12:10 +08:00
Workaround remote targets that report an empty list to qfThreadInfo
In https://sourceware.org/ml/gdb-patches/2014-10/msg00652.html, Sandra shows a target that was broken by the recent update_thread_list optimization: (gdb) target remote qa8-centos32-cs:10514 ... (gdb) continue Continuing. Cannot execute this command without a live selected thread. (gdb) The error means that the current thread is in "exited" state when the continue command is processed. The root of the problem was found here: > Sending packet: $Hg0#df...Packet received: ... > Sending packet: $?#3f...Packet received: S00 > Sending packet: $qfThreadInfo#bb...Packet received: l > Sending packet: $Hc-1#09...Packet received: > Sending packet: $qC#b4...Packet received: unset This target doesn't really support threads (no thread indication in stop reply packets; no support for qC), but then supports qfThreadInfo, and returns an empty thread list to GDB. See https://sourceware.org/ml/gdb-patches/2014-10/msg00665.html for why the target does that. As remote_update_thread_list deletes threads from GDB's list that are not found in the thread list that the target reports, the result is that GDB deletes the "fake" main thread that GDB added itself. (As that thread is currently selected, it is marked "exited" instead of being deleted straight away.) This commit avoids deleting the main thread in this scenario. gdb/ 2014-10-27 Pedro Alves <palves@redhat.com> * remote.c (remote_thread_alive): New, factored out from ... (remote_thread_alive): ... this. (remote_update_thread_list): Bail out before deleting threads if the target returned an empty list, and, the current thread has a magic/fake ptid.
This commit is contained in:
parent
708d7d0d11
commit
7d1a114c44
@ -1,3 +1,11 @@
|
||||
2014-10-27 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* remote.c (remote_thread_alive): New, factored out from ...
|
||||
(remote_thread_alive): ... this.
|
||||
(remote_update_thread_list): Bail out before deleting threads if
|
||||
the target returned an empty list, and, the current thread has a
|
||||
magic/fake ptid.
|
||||
|
||||
2014-10-27 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* infrun.c (handle_signal_stop): Also skip handlers when a random
|
||||
|
35
gdb/remote.c
35
gdb/remote.c
@ -1842,11 +1842,11 @@ set_general_process (void)
|
||||
}
|
||||
|
||||
|
||||
/* Return nonzero if the thread PTID is still alive on the remote
|
||||
system. */
|
||||
/* Return nonzero if this is the main thread that we made up ourselves
|
||||
to model non-threaded targets as single-threaded. */
|
||||
|
||||
static int
|
||||
remote_thread_alive (struct target_ops *ops, ptid_t ptid)
|
||||
remote_thread_always_alive (struct target_ops *ops, ptid_t ptid)
|
||||
{
|
||||
struct remote_state *rs = get_remote_state ();
|
||||
char *p, *endp;
|
||||
@ -1861,6 +1861,23 @@ remote_thread_alive (struct target_ops *ops, ptid_t ptid)
|
||||
multi-threading. */
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return nonzero if the thread PTID is still alive on the remote
|
||||
system. */
|
||||
|
||||
static int
|
||||
remote_thread_alive (struct target_ops *ops, ptid_t ptid)
|
||||
{
|
||||
struct remote_state *rs = get_remote_state ();
|
||||
char *p, *endp;
|
||||
|
||||
/* Check if this is a thread that we made up ourselves to model
|
||||
non-threaded targets as single-threaded. */
|
||||
if (remote_thread_always_alive (ops, ptid))
|
||||
return 1;
|
||||
|
||||
p = rs->buf;
|
||||
endp = rs->buf + get_remote_packet_size ();
|
||||
|
||||
@ -2780,6 +2797,18 @@ remote_update_thread_list (struct target_ops *ops)
|
||||
|
||||
got_list = 1;
|
||||
|
||||
if (VEC_empty (thread_item_t, context.items)
|
||||
&& remote_thread_always_alive (ops, inferior_ptid))
|
||||
{
|
||||
/* Some targets don't really support threads, but still
|
||||
reply an (empty) thread list in response to the thread
|
||||
listing packets, instead of replying "packet not
|
||||
supported". Exit early so we don't delete the main
|
||||
thread. */
|
||||
do_cleanups (old_chain);
|
||||
return;
|
||||
}
|
||||
|
||||
/* CONTEXT now holds the current thread list on the remote
|
||||
target end. Delete GDB-side threads no longer found on the
|
||||
target. */
|
||||
|
Loading…
Reference in New Issue
Block a user