aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2015-11-30 16:05:15 +0000
committerPedro Alves <palves@redhat.com>2015-11-30 18:37:25 +0000
commit34c6591498f4363ef2c71d683cdaaa33d6a6ad64 (patch)
tree92e113842ee8c135ad264294d8b0852a28f5d280 /gdb/gdbserver
parent066f6b6edcb63b363cc9a95c3727b996d1895549 (diff)
downloadgdb-34c6591498f4363ef2c71d683cdaaa33d6a6ad64.zip
gdb-34c6591498f4363ef2c71d683cdaaa33d6a6ad64.tar.gz
gdb-34c6591498f4363ef2c71d683cdaaa33d6a6ad64.tar.bz2
gdbserver crash running gdb.threads/non-ldr-exc-1.exp
This fixes a gdbserver crash when running gdb.threads/non-ldr-exc-1.exp with "maint set target-non-stop on". The problem is that qSymbol is called when gdbserver has current_thread == NULL. gdb/gdbserver/ChangeLog: 2015-11-30 Pedro Alves <palves@redhat.com> * gdbthread.h (find_any_thread_of_pid): Declare. * inferiors.c (thread_of_pid, find_any_thread_of_pid): New functions. * server.c (handle_query): If current_thread is NULL, look for another thread of the selected process.
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r--gdb/gdbserver/ChangeLog8
-rw-r--r--gdb/gdbserver/gdbthread.h4
-rw-r--r--gdb/gdbserver/inferiors.c23
-rw-r--r--gdb/gdbserver/server.c24
4 files changed, 59 insertions, 0 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index c9e2157..28ff0e1 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,11 @@
+2015-11-30 Pedro Alves <palves@redhat.com>
+
+ * gdbthread.h (find_any_thread_of_pid): Declare.
+ * inferiors.c (thread_of_pid, find_any_thread_of_pid): New
+ functions.
+ * server.c (handle_query): If current_thread is NULL, look for
+ another thread of the selected process.
+
2015-11-26 Daniel Colascione <dancol@dancol.org>
Simon Marchi <simon.marchi@ericsson.com>
diff --git a/gdb/gdbserver/gdbthread.h b/gdb/gdbserver/gdbthread.h
index d6959f4..0510419 100644
--- a/gdb/gdbserver/gdbthread.h
+++ b/gdb/gdbserver/gdbthread.h
@@ -80,6 +80,10 @@ struct thread_info *get_first_thread (void);
struct thread_info *find_thread_ptid (ptid_t ptid);
+/* Find any thread of the PID process. Returns NULL if none is
+ found. */
+struct thread_info *find_any_thread_of_pid (int pid);
+
/* Get current thread ID (Linux task ID). */
#define current_ptid (current_thread->entry.id)
diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
index 72a3ef1..95f3ad0 100644
--- a/gdb/gdbserver/inferiors.c
+++ b/gdb/gdbserver/inferiors.c
@@ -162,6 +162,29 @@ find_thread_process (const struct process_info *const process)
find_inferior (&all_threads, thread_pid_matches_callback, &pid);
}
+/* Helper for find_any_thread_of_pid. Returns true if a thread
+ matches a PID. */
+
+static int
+thread_of_pid (struct inferior_list_entry *entry, void *pid_p)
+{
+ int pid = *(int *) pid_p;
+
+ return (ptid_get_pid (entry->id) == pid);
+}
+
+/* See gdbthread.h. */
+
+struct thread_info *
+find_any_thread_of_pid (int pid)
+{
+ struct inferior_list_entry *entry;
+
+ entry = find_inferior (&all_threads, thread_of_pid, &pid);
+
+ return (struct thread_info *) entry;
+}
+
ptid_t
gdb_id_to_thread_id (ptid_t gdb_id)
{
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 0105b99..9d65f65 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -1975,6 +1975,28 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
if (strcmp ("qSymbol::", own_buf) == 0)
{
+ struct thread_info *save_thread = current_thread;
+
+ /* For qSymbol, GDB only changes the current thread if the
+ previous current thread was of a different process. So if
+ the previous thread is gone, we need to pick another one of
+ the same process. This can happen e.g., if we followed an
+ exec in a non-leader thread. */
+ if (current_thread == NULL)
+ {
+ current_thread
+ = find_any_thread_of_pid (ptid_get_pid (general_thread));
+
+ /* Just in case, if we didn't find a thread, then bail out
+ instead of crashing. */
+ if (current_thread == NULL)
+ {
+ write_enn (own_buf);
+ current_thread = save_thread;
+ return;
+ }
+ }
+
/* GDB is suggesting new symbols have been loaded. This may
mean a new shared library has been detected as loaded, so
take the opportunity to check if breakpoints we think are
@@ -1993,6 +2015,8 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
if (current_thread != NULL && the_target->look_up_symbols != NULL)
(*the_target->look_up_symbols) ();
+ current_thread = save_thread;
+
strcpy (own_buf, "OK");
return;
}