This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fwd: [RFC][Patch] Fix gdb failure to access tls data for parent thread


Hello,

Could anyone please provide feedback regarding this?

Thanks,
Vinay

Vinay Sridhar,
IBM-Linux Technology Centre,
vinay@linux.vnet.ibm.com
--- Begin Message ---
Hello,

While using gdb to access tls data for a parent thread of a multi-threaded program, we get the following error :

"Cannot find thread-local storage for LWP 11884,  executable file /home/test/test
TLS not supported on this target"

This can be recreated as follows :

$ cat test.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <omp.h>

__thread int thread;

void initTlsData() {
    printf("Initialising %d\n",thread);
}
int main(int argc, char *argv[]) {
    #pragma omp parallel
    {
        thread = omp_get_thread_num();
        initTlsData();
    }
    return(0);
}

0. export "OMP_NUM_THREADS=5" 	// 5 for example
1. gdb ./test
2. break initTlsData
3. run
4. thread 1		// Switch to the parent thread
5. print thread

The above stated error occurs.

The reason for this is gdb does not fill in the private field of the thread_info structure of the
parent thread. The below patch sets up this private field before the child
threads are added to gdb's list.

I'm not sure if the patch below breaks any existing behaviour. I'm also not sure if this is the right way to go about this. 
This is purely RFC.
If there's a better way of doing this please let me know.

--- linux-thread-db.c.old	2008-12-11 14:19:12.000000000 -0500
+++ linux-thread-db.c	2008-12-30 00:26:52.000000000 -0500
@@ -879,9 +879,33 @@ check_event (ptid_t ptid)
   while (loop);
 }
 
+void set_private_data (ptid_t ptid)
+{
+  td_thrhandle_t th;
+  struct thread_info *thread_info;
+  td_thrinfo_t ti;
+  td_err_e err;
+  struct private_thread_info *private;
+
+  private = xmalloc (sizeof (struct private_thread_info));
+  memset (private, 0, sizeof (struct private_thread_info));
+
+  err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
+  thread_get_info_callback (&th, &thread_info);
+  err = td_thr_get_info_p (&th, &ti);
+
+  if (ti.ti_tid == 0)
+    err = td_thr_event_enable_p (&th, 1);
+
+  private->th = th;
+  private->tid = ti.ti_tid;
+  thread_info->private = private;
+}
+
 static ptid_t
 thread_db_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
 {
+  struct thread_info *tp;
   ptid = target_beneath->to_wait (ptid, ourstatus);
 
   if (ourstatus->kind == TARGET_WAITKIND_IGNORE)
@@ -900,6 +924,13 @@ thread_db_wait (ptid_t ptid, struct targ
       return ptid;
     }
 
+    tp = find_thread_pid (ptid);
+
+    if (!tp->private)
+      set_private_data(ptid);
+    else if (tp->private->tid == 0)
+      set_private_data(ptid);
+
   /* If we do not know about the main thread yet, this would be a good time to
      find it.  */
   if (ourstatus->kind == TARGET_WAITKIND_STOPPED && !have_threads ())



Regards,
VInay

---
Vinay Sridhar,
Linux Technology Center,
IBM ISTL,
Bangalore, India

--- End Message ---

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]