* win32-i386-low.c: Add 64-bit support.
[deliverable/binutils-gdb.git] / gdb / gdbserver / thread-db.c
index 8af0539da7eea6dd0230d66fb91f3fc57873eac0..8e7d7a9361a4813b491f6c510e35141ade3ce868 100644 (file)
@@ -1,5 +1,5 @@
 /* Thread management interface, for the remote server for GDB.
-   Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    Contributed by MontaVista Software.
@@ -71,8 +71,8 @@ struct thread_db
                                sigset_t *ti_sigmask_p,
                                unsigned int ti_user_flags);
   td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
-                                    void *map_address,
-                                    size_t offset, void **address);
+                                    psaddr_t map_address,
+                                    size_t offset, psaddr_t *address);
   const char ** (*td_symbol_list_p) (void);
 };
 
@@ -596,6 +596,8 @@ try_thread_db_load_1 (void *handle)
   return 1;
 }
 
+#ifdef HAVE_DLADDR
+
 /* Lookup a library in which given symbol resides.
    Note: this is looking in the GDBSERVER process, not in the inferior.
    Returns library name, or NULL.  */
@@ -610,6 +612,8 @@ dladdr_to_soname (const void *addr)
   return NULL;
 }
 
+#endif
+
 static int
 try_thread_db_load (const char *library)
 {
@@ -626,6 +630,7 @@ try_thread_db_load (const char *library)
       return 0;
     }
 
+#ifdef HAVE_DLADDR
   if (debug_threads && strchr (library, '/') == NULL)
     {
       void *td_init;
@@ -640,6 +645,7 @@ try_thread_db_load (const char *library)
                     library, libpath);
        }
     }
+#endif
 
   if (try_thread_db_load_1 (handle))
     return 1;
@@ -737,7 +743,7 @@ thread_db_init (int use_events)
       if (use_events && thread_db_enable_reporting () == 0)
        {
          /* Keep trying; maybe event reporting will work later.  */
-         thread_db_free (proc);
+         thread_db_mourn (proc);
          return 0;
        }
       thread_db_find_new_threads ();
@@ -749,41 +755,83 @@ thread_db_init (int use_events)
   return 0;
 }
 
+static int
+any_thread_of (struct inferior_list_entry *entry, void *args)
+{
+  int *pid_p = args;
+
+  if (ptid_get_pid (entry->id) == *pid_p)
+    return 1;
+
+  return 0;
+}
+
 /* Disconnect from libthread_db and free resources.  */
 
-void
-thread_db_free (struct process_info *proc)
+static void
+disable_thread_event_reporting (struct process_info *proc)
 {
   struct thread_db *thread_db = proc->private->thread_db;
   if (thread_db)
     {
-#ifndef USE_LIBTHREAD_DB_DIRECTLY
-      td_err_e (*td_ta_delete_p) (td_thragent_t *);
       td_err_e (*td_ta_clear_event_p) (const td_thragent_t *ta,
                                       td_thr_events_t *event);
 
+#ifndef USE_LIBTHREAD_DB_DIRECTLY
       td_ta_clear_event_p = dlsym (thread_db->handle, "td_ta_clear_event");
+#else
+      td_ta_clear_event_p = &td_ta_clear_event;
+#endif
+
       if (td_ta_clear_event_p != NULL)
        {
+         struct thread_info *saved_inferior;
          td_thr_events_t events;
+         int pid;
 
-         /* Set the process wide mask saying we aren't interested in any
-            events anymore.  */
+         pid = pid_of (proc);
+         saved_inferior = current_inferior;
+         current_inferior =
+           (struct thread_info *) find_inferior (&all_threads,
+                                                 any_thread_of, &pid);
+
+         /* Set the process wide mask saying we aren't interested
+            in any events anymore.  */
          td_event_fillset (&events);
          (*td_ta_clear_event_p) (thread_db->thread_agent, &events);
+
+         current_inferior = saved_inferior;
        }
+    }
+}
+
+void
+thread_db_detach (struct process_info *proc)
+{
+  disable_thread_event_reporting (proc);
+}
+
+/* Disconnect from libthread_db and free resources.  */
+
+void
+thread_db_mourn (struct process_info *proc)
+{
+  struct thread_db *thread_db = proc->private->thread_db;
+  if (thread_db)
+    {
+      td_err_e (*td_ta_delete_p) (td_thragent_t *);
 
+#ifndef USE_LIBTHREAD_DB_DIRECTLY
       td_ta_delete_p = dlsym (thread_db->handle, "td_ta_delete");
+#else
+      td_ta_delete_p = &td_ta_delete;
+#endif
+
       if (td_ta_delete_p != NULL)
        (*td_ta_delete_p) (thread_db->thread_agent);
 
+#ifndef USE_LIBTHREAD_DB_DIRECTLY
       dlclose (thread_db->handle);
-#else
-      td_thd_events_t events;
-
-      td_event_fillset (&events);
-      td_ta_clear_event (thread_db->thread_agent, &events);
-      td_ta_delete (thread_db->thread_agent);
 #endif  /* USE_LIBTHREAD_DB_DIRECTLY  */
 
       free (thread_db);
This page took 0.025565 seconds and 4 git commands to generate.