summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2017-09-13 11:43:15 +0100
committerPedro Alves <palves@redhat.com>2017-09-13 11:43:15 +0100
commitbb276fc2244d56b254728fb54fbae1f517d401f2 (patch)
tree196da2331e060b2e74bb23c34bfa6510037a8344
parent9f2815a079efa19ae520293c455ec2910a9879ac (diff)
downloadbinutils-gdb-users/palves/tls-nonthreaded.tar.gz
Use libthread_db.so with non-threaded programs, for TLSusers/palves/tls-nonthreaded
(This is a hack for experimentation.)
-rw-r--r--gdb/linux-thread-db.c39
-rw-r--r--gdb/proc-service.c19
2 files changed, 46 insertions, 12 deletions
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
index 0e16f6a0d3f..c2fea867482 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 4620fea21a2..940993c9d07 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;
}