diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/linux-thread-db.c | 39 | ||||
-rw-r--r-- | gdb/proc-service.c | 19 |
2 files changed, 46 insertions, 12 deletions
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c index 0e16f6a..c2fea86 100644 --- a/gdb/linux-thread-db.c +++ b/gdb/linux-thread-db.c @@ -104,7 +104,7 @@ set_libthread_db_search_path (char *ignored, int from_tty, /* If non-zero, print details of libthread_db processing. */ -static unsigned int libthread_db_debug; +unsigned int libthread_db_debug; static void show_libthread_db_debug (struct ui_file *file, int from_tty, @@ -354,13 +354,19 @@ thread_from_lwp (ptid_t ptid) err = info->td_ta_map_lwp2thr_p (info->thread_agent, ptid_get_lwp (ptid), &th); if (err != TD_OK) - error (_("Cannot find user-level thread for LWP %ld: %s"), - ptid_get_lwp (ptid), thread_db_err_str (err)); + { + warning (_("Cannot find user-level thread for LWP %ld: %s"), + ptid_get_lwp (ptid), thread_db_err_str (err)); + return NULL; + } err = info->td_thr_get_info_p (&th, &ti); if (err != TD_OK) - error (_("thread_get_info_callback: cannot get thread info: %s"), - thread_db_err_str (err)); + { + warning (_("thread_get_info_callback: cannot get thread info: %s"), + thread_db_err_str (err)); + return NULL; + } /* Fill the cache. */ tp = find_thread_ptid (ptid); @@ -1429,7 +1435,7 @@ thread_db_get_thread_local_address (struct target_ops *ops, if (thread_info != NULL && thread_info->priv == NULL) thread_info = thread_from_lwp (ptid); - if (thread_info != NULL && thread_info->priv != NULL) + if (true) { td_err_e err; psaddr_t address; @@ -1437,6 +1443,21 @@ thread_db_get_thread_local_address (struct target_ops *ops, info = get_thread_db_info (ptid_get_pid (ptid)); + /* Handle executables that don't link with pthread. We still + use libthread_db.so with those in order to be able to access + TLS variables. This bakes in awareness that the main + thread's special handle is "0". Should maybe make + td_ta_map_lwp2thr return that handle instead for non-threaded + programs. */ + td_thrhandle_t main_thr_th {}; + main_thr_th.th_ta_p = info->thread_agent; + + td_thrhandle_t *th; + if (thread_info == NULL || thread_info->priv == NULL) + th = &main_thr_th; + else + th = &thread_info->priv->th; + /* Finally, get the address of the variable. */ if (lm != 0) { @@ -1448,7 +1469,8 @@ thread_db_get_thread_local_address (struct target_ops *ops, /* Note the cast through uintptr_t: this interface only works if a target address fits in a psaddr_t, which is a host pointer. So a 32-bit debugger can not access 64-bit TLS through this. */ - err = info->td_thr_tls_get_addr_p (&thread_info->priv->th, + + err = info->td_thr_tls_get_addr_p (th, (psaddr_t)(uintptr_t) lm, offset, &address); } @@ -1466,8 +1488,7 @@ thread_db_get_thread_local_address (struct target_ops *ops, PR libc/16831 due to GDB PR threads/16954 LOAD_MODULE is also NULL. The constant number 1 depends on GNU __libc_setup_tls initialization of l_tls_modid to 1. */ - err = info->td_thr_tlsbase_p (&thread_info->priv->th, - 1, &address); + err = info->td_thr_tlsbase_p (th, 1, &address); address = (char *) address + offset; } diff --git a/gdb/proc-service.c b/gdb/proc-service.c index 4620fea..940993c 100644 --- a/gdb/proc-service.c +++ b/gdb/proc-service.c @@ -102,6 +102,8 @@ ps_xfer_memory (const struct ps_prochandle *ph, psaddr_t addr, } +extern unsigned int libthread_db_debug; + /* Search for the symbol named NAME within the object named OBJ within the target process PH. If the symbol is found the address of the symbol is stored in SYM_ADDR. */ @@ -119,9 +121,20 @@ ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *obj, /* FIXME: kettenis/2000-09-03: What should we do with OBJ? */ bound_minimal_symbol ms = lookup_minimal_symbol (name, NULL, NULL); if (ms.minsym == NULL) - return PS_NOSYM; - - *sym_addr = core_addr_to_ps_addr (BMSYMBOL_VALUE_ADDRESS (ms)); + { + if (libthread_db_debug) + fprintf_unfiltered (gdb_stdlog, + "ps_pglobal_lookup: name=\"%s\" => PS_NOSYM\n", + name); + return PS_NOSYM; + } + + CORE_ADDR ms_addr = BMSYMBOL_VALUE_ADDRESS (ms); + if (libthread_db_debug) + fprintf_unfiltered (gdb_stdlog, + "ps_pglobal_lookup: name=\"%s\" => PS_OK, %s\n", name, + paddress (target_gdbarch (), ms_addr)); + *sym_addr = core_addr_to_ps_addr (ms_addr); return PS_OK; } |