Compare commits

...

1 Commits

Author SHA1 Message Date
Pedro Alves
bb276fc224 Use libthread_db.so with non-threaded programs, for TLS
(This is a hack for experimentation.)
2017-09-13 11:43:15 +01:00
2 changed files with 45 additions and 11 deletions

View File

@@ -104,7 +104,7 @@ set_libthread_db_search_path (char *ignored, int from_tty,
/* If non-zero, print details of libthread_db processing. */ /* If non-zero, print details of libthread_db processing. */
static unsigned int libthread_db_debug; unsigned int libthread_db_debug;
static void static void
show_libthread_db_debug (struct ui_file *file, int from_tty, 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), err = info->td_ta_map_lwp2thr_p (info->thread_agent, ptid_get_lwp (ptid),
&th); &th);
if (err != TD_OK) 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); err = info->td_thr_get_info_p (&th, &ti);
if (err != TD_OK) 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. */ /* Fill the cache. */
tp = find_thread_ptid (ptid); 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) if (thread_info != NULL && thread_info->priv == NULL)
thread_info = thread_from_lwp (ptid); thread_info = thread_from_lwp (ptid);
if (thread_info != NULL && thread_info->priv != NULL) if (true)
{ {
td_err_e err; td_err_e err;
psaddr_t address; 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)); 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. */ /* Finally, get the address of the variable. */
if (lm != 0) 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 /* Note the cast through uintptr_t: this interface only works if
a target address fits in a psaddr_t, which is a host pointer. 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. */ 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, (psaddr_t)(uintptr_t) lm,
offset, &address); 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. PR libc/16831 due to GDB PR threads/16954 LOAD_MODULE is also NULL.
The constant number 1 depends on GNU __libc_setup_tls The constant number 1 depends on GNU __libc_setup_tls
initialization of l_tls_modid to 1. */ initialization of l_tls_modid to 1. */
err = info->td_thr_tlsbase_p (&thread_info->priv->th, err = info->td_thr_tlsbase_p (th, 1, &address);
1, &address);
address = (char *) address + offset; address = (char *) address + offset;
} }

View File

@@ -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 /* 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 the target process PH. If the symbol is found the address of the
symbol is stored in SYM_ADDR. */ 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? */ /* FIXME: kettenis/2000-09-03: What should we do with OBJ? */
bound_minimal_symbol ms = lookup_minimal_symbol (name, NULL, NULL); bound_minimal_symbol ms = lookup_minimal_symbol (name, NULL, NULL);
if (ms.minsym == NULL) if (ms.minsym == NULL)
return PS_NOSYM; {
if (libthread_db_debug)
fprintf_unfiltered (gdb_stdlog,
"ps_pglobal_lookup: name=\"%s\" => PS_NOSYM\n",
name);
return PS_NOSYM;
}
*sym_addr = core_addr_to_ps_addr (BMSYMBOL_VALUE_ADDRESS (ms)); 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; return PS_OK;
} }