/* 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.
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);
};
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. */
return NULL;
}
+#endif
+
static int
try_thread_db_load (const char *library)
{
return 0;
}
+#ifdef HAVE_DLADDR
if (debug_threads && strchr (library, '/') == NULL)
{
void *td_init;
library, libpath);
}
}
+#endif
if (try_thread_db_load_1 (handle))
return 1;
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 ();
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);