[PATCH] nptl: Export libthread_db-used symbols under GLIBC_PRIVATE

Florian Weimer via Gdb <[email protected]>
Newsgroups gmane.comp.gdb.devel,gmane.comp.lib.glibc.alpha
Message-ID <[email protected]>
Kevin, this *almost* gives us the perfect debugging experience with your
patched GDB in Fedora 35, according to my preliminary tests.  A build
with the patch is running here:

  <https://koji.fedoraproject.org/koji/buildinfo?buildID=1773177>

However, it seems that GDB still needs pthread_create in the .symtab to
trigger loading of libpthread_db.  A fully stripped libc.so.6 without
.symtab does not trigger loading in my experiments.  (The other symbols
we preserve for valgrind's sake and are immaterial to GDB.)  In other
words,

  cp /lib64/libc.so.6 . ; strip libc.so.6 ; LD_LIBRARY_PATH=. gdb …

does not result in working thread debugging.

If the pthread_create .symtab requirement is too difficult to work
around, we might as well put the _thread_db_* symbols into .symtab and
tell distributions to use:

  strip -w -K pthread_create -K _thread_db_\* libc.so.6

But then we'd need two categories of symbols in the internal consistency
check for nptl_db (the db-symbol.awk file), so maybe that's overdoing
things for a slightly smaller .dynsym size.

Thanks,
Florian

8<------------------------------------------------------------------8<
This allows distributions to strip debugging information from
libc.so.6 without impacting the debugging experience.

nptl_version had to be renamed to __nptl_version to avoid
namespace issues.
---
 nptl/Versions          | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++
 nptl/pthread_create.c  | 13 +++++++-----
 nptl_db/Makefile       |  2 +-
 nptl_db/db-symbols.awk |  4 +++-
 nptl_db/structs.def    |  2 +-
 nptl_db/td_ta_new.c    |  2 +-
 6 files changed, 70 insertions(+), 9 deletions(-)

diff --git a/nptl/Versions b/nptl/Versions
index 62bb939d54..c03ed92848 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -403,10 +403,14 @@ libc {
     __nptl_deallocate_tsd;
     __nptl_death_event;
     __nptl_free_tcb;
+    __nptl_last_event;
     __nptl_nthreads;
+    __nptl_rtld_global;
     __nptl_setxid_sighandler;
     __nptl_stack_list_add;
     __nptl_stack_list_del;
+    __nptl_threads_events;
+    __nptl_version;
     __pthread_attr_copy;
     __pthread_attr_destroy;
     __pthread_attr_init;
@@ -430,6 +434,58 @@ libc {
     __pthread_unwind;
     __sched_fifo_max_prio;
     __sched_fifo_min_prio;
+    _thread_db___nptl_last_event;
+    _thread_db___nptl_rtld_global;
+    _thread_db_const_thread_area;
+    _thread_db_dtv_dtv;
+    _thread_db_dtv_slotinfo_gen;
+    _thread_db_dtv_slotinfo_list_len;
+    _thread_db_dtv_slotinfo_list_next;
+    _thread_db_dtv_slotinfo_list_slotinfo;
+    _thread_db_dtv_slotinfo_map;
+    _thread_db_dtv_t_counter;
+    _thread_db_dtv_t_pointer_val;
+    _thread_db_link_map_l_tls_modid;
+    _thread_db_link_map_l_tls_offset;
+    _thread_db_list_t_next;
+    _thread_db_list_t_prev;
+    _thread_db_pthread_cancelhandling;
+    _thread_db_pthread_dtvp;
+    _thread_db_pthread_eventbuf;
+    _thread_db_pthread_eventbuf_eventmask;
+    _thread_db_pthread_eventbuf_eventmask_event_bits;
+    _thread_db_pthread_key_data_data;
+    _thread_db_pthread_key_data_level2_data;
+    _thread_db_pthread_key_data_seq;
+    _thread_db_pthread_key_struct_destr;
+    _thread_db_pthread_key_struct_seq;
+    _thread_db_pthread_list;
+    _thread_db_pthread_nextevent;
+    _thread_db_pthread_report_events;
+    _thread_db_pthread_schedparam_sched_priority;
+    _thread_db_pthread_schedpolicy;
+    _thread_db_pthread_specific;
+    _thread_db_pthread_start_routine;
+    _thread_db_pthread_tid;
+    _thread_db_register32;
+    _thread_db_register32_thread_area;
+    _thread_db_register64;
+    _thread_db_register64_thread_area;
+    _thread_db_rtld_global__dl_stack_used;
+    _thread_db_rtld_global__dl_stack_user;
+    _thread_db_rtld_global__dl_tls_dtv_slotinfo_list;
+    _thread_db_sizeof_dtv_slotinfo;
+    _thread_db_sizeof_dtv_slotinfo_list;
+    _thread_db_sizeof_list_t;
+    _thread_db_sizeof_pthread;
+    _thread_db_sizeof_pthread_key_data;
+    _thread_db_sizeof_pthread_key_data_level2;
+    _thread_db_sizeof_pthread_key_struct;
+    _thread_db_sizeof_td_eventbuf_t;
+    _thread_db_sizeof_td_thr_events_t;
+    _thread_db_td_eventbuf_t_eventdata;
+    _thread_db_td_eventbuf_t_eventnum;
+    _thread_db_td_thr_events_t_event_bits;
   }
 }
 
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 3f017f1e26..d1b6817a81 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -43,21 +43,24 @@
 
 
 /* Globally enabled events.  */
-static td_thr_events_t __nptl_threads_events __attribute_used__;
+td_thr_events_t __nptl_threads_events __attribute__ ((nocommon));
+libc_hidden_proto (__nptl_threads_events)
+libc_hidden_data_def (__nptl_threads_events)
 
 /* Pointer to descriptor with the last event.  */
-static struct pthread *__nptl_last_event __attribute_used__;
+struct pthread *__nptl_last_event __attribute__ ((nocommon));
+libc_hidden_proto (__nptl_last_event)
+libc_hidden_data_def (__nptl_last_event)
 
 #ifdef SHARED
 /* This variable is used to access _rtld_global from libthread_db.  If
    GDB loads libpthread before ld.so, it is not possible to resolve
    _rtld_global directly during libpthread initialization.  */
-static struct rtld_global *__nptl_rtld_global __attribute_used__
-  = &_rtld_global;
+struct rtld_global *__nptl_rtld_global = &_rtld_global;
 #endif
 
 /* Version of the library, used in libthread_db to detect mismatches.  */
-static const char nptl_version[] __attribute_used__ = VERSION;
+const char __nptl_version[] = VERSION;
 
 /* This performs the initialization necessary when going from
    single-threaded to multi-threaded mode for the first time.  */
diff --git a/nptl_db/Makefile b/nptl_db/Makefile
index ea721c1dcf..4cc51c0e7b 100644
--- a/nptl_db/Makefile
+++ b/nptl_db/Makefile
@@ -57,7 +57,7 @@ include ../Rules
 
 $(objpfx)db-symbols.out: $(objpfx)db-symbols.v.i \
 			 $(common-objpfx)libc.so
-	LC_ALL=C $(READELF) -W -s $(filter %.so,$^) | $(AWK) -f $< > $@; \
+	LC_ALL=C $(READELF) -W -D -s $(filter %.so,$^) | $(AWK) -f $< > $@; \
 	$(evaluate-test)
 
 $(objpfx)db-symbols.v.i: db-symbols.awk
diff --git a/nptl_db/db-symbols.awk b/nptl_db/db-symbols.awk
index 6f326cf379..2033f95e38 100644
--- a/nptl_db/db-symbols.awk
+++ b/nptl_db/db-symbols.awk
@@ -13,7 +13,7 @@ BEGIN {
    in_symtab = 0;
 }
 
-/Symbol table '.symtab'/ { in_symtab=1; next }
+/Symbol table for image/ { in_symtab=1; next }
 NF == 0 { in_symtab=0; next }
 
 !in_symtab { next }
@@ -24,6 +24,7 @@ END {
   status = 0;
 
   for (s in required) {
+    s = s "@@GLIBC_PRIVATE"
     if (s in seen) print s, "ok";
     else {
       status = 1;
@@ -33,6 +34,7 @@ END {
 
   any = "";
   for (s in th_unique) {
+    s = s "@@GLIBC_PRIVATE"
     if (s in seen) {
       any = s;
       break;
diff --git a/nptl_db/structs.def b/nptl_db/structs.def
index 6a726f207e..e2e51acc39 100644
--- a/nptl_db/structs.def
+++ b/nptl_db/structs.def
@@ -77,7 +77,7 @@ DB_STRUCT (td_eventbuf_t)
 DB_STRUCT_FIELD (td_eventbuf_t, eventnum)
 DB_STRUCT_FIELD (td_eventbuf_t, eventdata)
 
-DB_SYMBOL (nptl_version)
+DB_SYMBOL (__nptl_version)
 DB_MAIN_SYMBOL (__nptl_create_event)
 DB_MAIN_SYMBOL (__nptl_death_event)
 DB_SYMBOL (__nptl_threads_events)
diff --git a/nptl_db/td_ta_new.c b/nptl_db/td_ta_new.c
index 501d922ea2..eeca29d5a0 100644
--- a/nptl_db/td_ta_new.c
+++ b/nptl_db/td_ta_new.c
@@ -39,7 +39,7 @@ td_ta_new (struct ps_prochandle *ps, td_thragent_t **ta)
   LOG ("td_ta_new");
 
   /* Check whether the versions match.  */
-  if (td_lookup (ps, SYM_nptl_version, &versaddr) != PS_OK)
+  if (td_lookup (ps, SYM___nptl_version, &versaddr) != PS_OK)
     return TD_NOLIBTHREAD;
   if (ps_pdread (ps, versaddr, versbuf, sizeof (versbuf)) != PS_OK)
     return TD_ERR;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.