This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] gdbserver crash running gdb.threads/non-ldr-exc-1.exp


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=34c6591498f4363ef2c71d683cdaaa33d6a6ad64

commit 34c6591498f4363ef2c71d683cdaaa33d6a6ad64
Author: Pedro Alves <palves@redhat.com>
Date:   Mon Nov 30 16:05:15 2015 +0000

    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.

Diff:
---
 gdb/gdbserver/ChangeLog   |  8 ++++++++
 gdb/gdbserver/gdbthread.h |  4 ++++
 gdb/gdbserver/inferiors.c | 23 +++++++++++++++++++++++
 gdb/gdbserver/server.c    | 24 ++++++++++++++++++++++++
 4 files changed, 59 insertions(+)

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;
     }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]