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] Add thread_db_notice_clone to gdbserver


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

commit 8629910955a751a93f2f12389ff1f497556cc260
Author: Kevin Buettner <kevinb@redhat.com>
Date:   Tue Apr 4 15:25:43 2017 -0700

    Add thread_db_notice_clone to gdbserver
    
    While working on a patch for fetching a thread handle in gdbserver, I
    ran into a circumstance in which tests in gdb.mi/mi-nsmoribund.exp
    would occasionally fail.  Over a large enough number of runs, it would
    fail roughly 2% of the time.
    
    That thread handle patch caused find_one_thread() to be called on
    every stop.  find_one_thread() calls td_ta_map_lwp2thr() which, in
    turn, can cause ps_get_thread_area() to be called.
    ps_get_thread_area() makes a call to ptrace() for getting the thread
    area address.  If this should happen when the thread is not stopped,
    the call to ptrace will return error which in turn propogates back to
    find_one_thread().  find_one_thread() calls error() in this instance
    which causes the program to die.
    
    This patch causes find_one_thread() to be called upon reciept of a
    clone event.  Since the clone is stopped, the circumstances described
    above cannot occur.
    
    gdb/gdbserver/ChangeLog:
    
    	* linux-low.c (handle_extended_wait): Call thread_db_notice_clone().
    	* linux-low.h (thread_db_notice_clone): Declare.
    	* thread-db.c (thread_db_notice_clone): New function.

Diff:
---
 gdb/gdbserver/ChangeLog   |  6 ++++++
 gdb/gdbserver/linux-low.c |  2 ++
 gdb/gdbserver/linux-low.h |  6 ++++++
 gdb/gdbserver/thread-db.c | 16 ++++++++++++++++
 4 files changed, 30 insertions(+)

diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index fa21333..b075eb3 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,9 @@
+2017-09-21  Kevin Buettner  <kevinb@redhat.com>
+
+	* linux-low.c (handle_extended_wait): Call thread_db_notice_clone().
+	* linux-low.h (thread_db_notice_clone): Declare.
+	* thread-db.c (thread_db_notice_clone): New function.
+
 2017-09-21  Pedro Alves  <palves@redhat.com>
 
 	* server.c (gdb_read_memory, handle_status, process_serial_event)
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 1bc8f38..a3f9ab9 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -656,6 +656,8 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
 	  new_lwp->status_pending = status;
 	}
 
+      thread_db_notice_clone (get_thread_process (event_thr), ptid);
+
       /* Don't report the event.  */
       return 1;
     }
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
index 9106144..be27c92 100644
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -410,4 +410,10 @@ int thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
 			       CORE_ADDR load_module, CORE_ADDR *address);
 int thread_db_look_up_one_symbol (const char *name, CORE_ADDR *addrp);
 
+/* Called from linux-low.c when a clone event is detected.  Upon entry,
+   both the clone and the parent should be stopped.  This function does
+   whatever is required have the clone under thread_db's control.  */
+
+void thread_db_notice_clone (struct process_info *proc, ptid_t lwp);
+
 extern int have_ptrace_getregset;
diff --git a/gdb/gdbserver/thread-db.c b/gdb/gdbserver/thread-db.c
index 9b867b8..3d57f31 100644
--- a/gdb/gdbserver/thread-db.c
+++ b/gdb/gdbserver/thread-db.c
@@ -851,3 +851,19 @@ thread_db_handle_monitor_command (char *mon)
   /* Tell server.c to perform default processing.  */
   return 0;
 }
+
+/* See linux-low.h.  */
+
+void
+thread_db_notice_clone (struct process_info *proc, ptid_t ptid)
+{
+  struct thread_db *thread_db = proc->priv->thread_db;
+
+  /* If the thread layer isn't initialized, return.  It may just
+     be that the program uses clone, but does not use libthread_db.  */
+  if (thread_db == NULL || !thread_db->all_symbols_looked_up)
+    return;
+
+  if (!find_one_thread (ptid))
+    warning ("Cannot find thread after clone.\n");
+}


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