summaryrefslogtreecommitdiff
path: root/gdb/gdbserver/thread-db.c
diff options
context:
space:
mode:
authorPedro Alves <pedro@codesourcery.com>2010-05-03 18:13:36 +0000
committerPedro Alves <pedro@codesourcery.com>2010-05-03 18:13:36 +0000
commiteeb30181669a21f349574a169469936a9516c88a (patch)
treec156f87491d9eb76763f697af6df62453d8277df /gdb/gdbserver/thread-db.c
parent5b6d7b27faf540240234d9e0893bd06e61a9a44e (diff)
downloadgdb-eeb30181669a21f349574a169469936a9516c88a.tar.gz
gdb/gdbserver/
* proc-service.c (ps_pglobal_lookup): Use thread_db_look_up_one_symbol. * remote-utils.c (look_up_one_symbol): Add new `may_ask_gdb' parameter. Use it instead of all_symbols_looked_up. * server.h (struct process_info) <all_symbols_looked_up>: Delete field. (all_symbols_looked_up): Don't declare. (look_up_one_symbol): Add new `may_ask_gdb' parameter. * thread-db.c (struct thread_db) <all_symbols_looked_up>: New field. (thread_db_look_up_symbols): Adjust call to look_up_one_symbol. Set all_symbols_looked_up here. (thread_db_look_up_one_symbol): New. (thread_db_get_tls_address): Adjust. (thread_db_load_search, try_thread_db_load_1): Always allocate the thread_db object on the heap, and tentatively set it in the process structure. (thread_db_init): Don't set all_symbols_looked_up here. * linux-low.h (thread_db_look_up_one_symbol): Declare.
Diffstat (limited to 'gdb/gdbserver/thread-db.c')
-rw-r--r--gdb/gdbserver/thread-db.c100
1 files changed, 63 insertions, 37 deletions
diff --git a/gdb/gdbserver/thread-db.c b/gdb/gdbserver/thread-db.c
index 7dec30dafab..86c4e181472 100644
--- a/gdb/gdbserver/thread-db.c
+++ b/gdb/gdbserver/thread-db.c
@@ -47,6 +47,11 @@ struct thread_db
/* Connection to the libthread_db library. */
td_thragent_t *thread_agent;
+ /* If this flag has been set, we've already asked GDB for all
+ symbols we might need; assume symbol cache misses are
+ failures. */
+ int all_symbols_looked_up;
+
#ifndef USE_LIBTHREAD_DB_DIRECTLY
/* Handle of the libthread_db from dlopen. */
void *handle;
@@ -452,7 +457,25 @@ thread_db_look_up_symbols (void)
CORE_ADDR unused;
for (sym_list = thread_db->td_symbol_list_p (); *sym_list; sym_list++)
- look_up_one_symbol (*sym_list, &unused);
+ look_up_one_symbol (*sym_list, &unused, 1);
+
+ /* We're not interested in any other libraries loaded after this
+ point, only in symbols in libpthread.so. */
+ thread_db->all_symbols_looked_up = 1;
+}
+
+int
+thread_db_look_up_one_symbol (const char *name, CORE_ADDR *addrp)
+{
+ struct thread_db *thread_db = current_process ()->private->thread_db;
+ int may_ask_gdb = !thread_db->all_symbols_looked_up;
+
+ /* If we've passed the call to thread_db_look_up_symbols, then
+ anything not in the cache must not exist; we're not interested
+ in any libraries loaded after that point, only in symbols in
+ libpthread.so. It might not be an appropriate time to look
+ up a symbol, e.g. while we're trying to fetch registers. */
+ return look_up_one_symbol (name, addrp, may_ask_gdb);
}
int
@@ -470,7 +493,7 @@ thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
thread_db = proc->private->thread_db;
/* If the thread layer is not (yet) initialized, fail. */
- if (!proc->all_symbols_looked_up)
+ if (!thread_db->all_symbols_looked_up)
return TD_ERR;
if (thread_db->td_thr_tls_get_addr_p == NULL)
@@ -506,41 +529,41 @@ static int
thread_db_load_search (void)
{
td_err_e err;
- struct thread_db tdb;
+ struct thread_db *tdb;
struct process_info *proc = current_process ();
if (proc->private->thread_db != NULL)
fatal ("unexpected: proc->private->thread_db != NULL");
- memset (&tdb, 0, sizeof (tdb));
+ tdb = xcalloc (1, sizeof (*tdb));
+ proc->private->thread_db = tdb;
- tdb.td_ta_new_p = &td_ta_new;
+ tdb->td_ta_new_p = &td_ta_new;
/* Attempt to open a connection to the thread library. */
- err = tdb.td_ta_new_p (&tdb.proc_handle, &tdb.thread_agent);
+ err = tdb->td_ta_new_p (&tdb->proc_handle, &tdb->thread_agent);
if (err != TD_OK)
{
if (debug_threads)
fprintf (stderr, "td_ta_new(): %s\n", thread_db_err_str (err));
+ free (tdb);
+ proc->private->thread_db = NULL;
return 0;
}
- tdb.td_ta_map_lwp2thr_p = &td_ta_map_lwp2thr;
- tdb.td_thr_get_info_p = &td_thr_get_info;
- tdb.td_ta_thr_iter_p = &td_ta_thr_iter;
- tdb.td_symbol_list_p = &td_symbol_list;
+ tdb->td_ta_map_lwp2thr_p = &td_ta_map_lwp2thr;
+ tdb->td_thr_get_info_p = &td_thr_get_info;
+ tdb->td_ta_thr_iter_p = &td_ta_thr_iter;
+ tdb->td_symbol_list_p = &td_symbol_list;
/* This is required only when thread_db_use_events is on. */
- tdb.td_thr_event_enable_p = &td_thr_event_enable;
+ tdb->td_thr_event_enable_p = &td_thr_event_enable;
/* These are not essential. */
- tdb.td_ta_event_addr_p = &td_ta_event_addr;
- tdb.td_ta_set_event_p = &td_ta_set_event;
- tdb.td_ta_event_getmsg_p = &td_ta_event_getmsg;
- tdb.td_thr_tls_get_addr_p = &td_thr_tls_get_addr;
-
- proc->private->thread_db = xmalloc (sizeof (tdb));
- memcpy (proc->private->thread_db, &tdb, sizeof (tdb));
+ tdb->td_ta_event_addr_p = &td_ta_event_addr;
+ tdb->td_ta_set_event_p = &td_ta_set_event;
+ tdb->td_ta_event_getmsg_p = &td_ta_event_getmsg;
+ tdb->td_thr_tls_get_addr_p = &td_thr_tls_get_addr;
return 1;
}
@@ -551,15 +574,16 @@ static int
try_thread_db_load_1 (void *handle)
{
td_err_e err;
- struct thread_db tdb;
+ struct thread_db *tdb;
struct process_info *proc = current_process ();
if (proc->private->thread_db != NULL)
fatal ("unexpected: proc->private->thread_db != NULL");
- memset (&tdb, 0, sizeof (tdb));
+ tdb = xcalloc (1, sizeof (*tdb));
+ proc->private->thread_db = tdb;
- tdb.handle = handle;
+ tdb->handle = handle;
/* Initialize pointers to the dynamic library functions we will use.
Essential functions first. */
@@ -572,42 +596,45 @@ try_thread_db_load_1 (void *handle)
if (debug_threads) \
fprintf (stderr, "dlsym: %s\n", dlerror ()); \
if (required) \
- return 0; \
+ { \
+ free (tdb); \
+ proc->private->thread_db = NULL; \
+ return 0; \
+ } \
} \
} \
while (0)
- CHK (1, tdb.td_ta_new_p = dlsym (handle, "td_ta_new"));
+ CHK (1, tdb->td_ta_new_p = dlsym (handle, "td_ta_new"));
/* Attempt to open a connection to the thread library. */
- err = tdb.td_ta_new_p (&tdb.proc_handle, &tdb.thread_agent);
+ err = tdb->td_ta_new_p (&tdb->proc_handle, &tdb->thread_agent);
if (err != TD_OK)
{
if (debug_threads)
fprintf (stderr, "td_ta_new(): %s\n", thread_db_err_str (err));
+ free (tdb);
+ proc->private->thread_db = NULL;
return 0;
}
- CHK (1, tdb.td_ta_map_lwp2thr_p = dlsym (handle, "td_ta_map_lwp2thr"));
- CHK (1, tdb.td_thr_get_info_p = dlsym (handle, "td_thr_get_info"));
- CHK (1, tdb.td_ta_thr_iter_p = dlsym (handle, "td_ta_thr_iter"));
- CHK (1, tdb.td_symbol_list_p = dlsym (handle, "td_symbol_list"));
+ CHK (1, tdb->td_ta_map_lwp2thr_p = dlsym (handle, "td_ta_map_lwp2thr"));
+ CHK (1, tdb->td_thr_get_info_p = dlsym (handle, "td_thr_get_info"));
+ CHK (1, tdb->td_ta_thr_iter_p = dlsym (handle, "td_ta_thr_iter"));
+ CHK (1, tdb->td_symbol_list_p = dlsym (handle, "td_symbol_list"));
/* This is required only when thread_db_use_events is on. */
CHK (thread_db_use_events,
- tdb.td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable"));
+ tdb->td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable"));
/* These are not essential. */
- CHK (0, tdb.td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr"));
- CHK (0, tdb.td_ta_set_event_p = dlsym (handle, "td_ta_set_event"));
- CHK (0, tdb.td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg"));
- CHK (0, tdb.td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr"));
+ CHK (0, tdb->td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr"));
+ CHK (0, tdb->td_ta_set_event_p = dlsym (handle, "td_ta_set_event"));
+ CHK (0, tdb->td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg"));
+ CHK (0, tdb->td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr"));
#undef CHK
- proc->private->thread_db = xmalloc (sizeof (tdb));
- memcpy (proc->private->thread_db, &tdb, sizeof (tdb));
-
return 1;
}
@@ -763,7 +790,6 @@ thread_db_init (int use_events)
}
thread_db_find_new_threads ();
thread_db_look_up_symbols ();
- proc->all_symbols_looked_up = 1;
return 1;
}