diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8a34118586c..b358dd71805 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2014-10-27 Pedro Alves + + * 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 * infrun.c (handle_signal_stop): Also skip handlers when a random diff --git a/gdb/remote.c b/gdb/remote.c index 20f2988aca2..4b9b0991c65 100644 --- a/gdb/remote.c +++ b/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. */