]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Use libthread_db.so with non-threaded programs, for TLS users/palves/tls-nonthreaded
authorPedro Alves <palves@redhat.com>
Wed, 13 Sep 2017 10:43:15 +0000 (11:43 +0100)
committerPedro Alves <palves@redhat.com>
Wed, 13 Sep 2017 10:43:15 +0000 (11:43 +0100)
(This is a hack for experimentation.)

gdb/linux-thread-db.c
gdb/proc-service.c

index 0e16f6a0d3f9d06d1a5f944ccdaf7d8c3732098d..c2fea867482b135cbdc36007ee8e1538f7287ba5 100644 (file)
@@ -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;
        }
 
index 4620fea21a2a1d7e2bfc0b58f67baf160601e084..940993c9d07cc3d40acd4e8c8da4ed6bd33de1a6 100644 (file)
@@ -102,6 +102,8 @@ ps_xfer_memory (const struct ps_prochandle *ph, psaddr_t addr,
 }
 \f
 
+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;
 }