Ping. On 4/28/2015 11:07 AM, Sheng Yong wrote: > From: Roland McGrath <[email protected]> > > (__pthread_initialize_minimal_internal): Initialize pd->report_events > to that. > > This patch helps NPTL report TD_CREATE event, so that GDB could catch the > event and update its thread_list. > Link: http://lists.uclibc.org/pipermail/uclibc/2015-April/048921.html > [shengyong: > - original patch from glibc: commit 7d9d8bd18906fdd17364f372b160d7ab896ce909 > - context adjust > - update nptl_db/ChangeLog] > Signed-off-by: Sheng Yong <[email protected]> > --- > libpthread/nptl_db/ChangeLog | 23 +++++++++ > libpthread/nptl_db/db_info.c | 4 +- > libpthread/nptl_db/structs.def | 3 +- > libpthread/nptl_db/td_ta_map_lwp2thr.c | 69 +++++++++++++++++++-------- > libpthread/nptl_db/td_ta_thr_iter.c | 25 +++++----- > libpthread/nptl_db/td_thr_event_enable.c | 24 ++++++++-- > libpthread/nptl_db/td_thr_get_info.c | 81 > +++++++++++++++++++------------- > libpthread/nptl_db/td_thr_getfpregs.c | 7 ++- > libpthread/nptl_db/td_thr_getgregs.c | 7 ++- > libpthread/nptl_db/td_thr_setfpregs.c | 7 ++- > libpthread/nptl_db/td_thr_setgregs.c | 7 ++- > libpthread/nptl_db/td_thr_tlsbase.c | 25 +++++++++- > libpthread/nptl_db/td_thr_validate.c | 16 ++----- > libpthread/nptl_db/thread_dbP.h | 5 +- > 14 files changed, 217 insertions(+), 86 deletions(-) > > diff --git a/libpthread/nptl_db/ChangeLog b/libpthread/nptl_db/ChangeLog > index 52c8491..92021cb 100644 > --- a/libpthread/nptl_db/ChangeLog > +++ b/libpthread/nptl_db/ChangeLog > @@ -1,3 +1,26 @@ > +2007-05-16 Roland McGrath <[email protected]> > + > + * td_thr_get_info.c: Fake the results for TH->th_unique == 0. > + * td_thr_validate.c: Likewise. > + * td_thr_setgregs.c: Likewise. > + * td_thr_setfpregs.c: Likewise. > + * td_thr_getgregs.c: Likewise. > + * td_thr_getfpregs.c: Likewise. > + * td_thr_tlsbase.c: Likewise. > + > + * structs.def: Add DB_VARIABLE (__nptl_initial_report_events). > + * db_info.c: Add necessary declaration. > + * td_thr_event_enable.c: Set __nptl_initial_report_events too. > + > + * td_ta_thr_iter.c (iterate_thread_list): Make FAKE_EMPTY bool. > + Use th_unique=0 in fake descriptor before initialization. > + > + * td_ta_map_lwp2thr.c (__td_ta_lookup_th_unique): New function, broken > + out of ... > + (td_ta_map_lwp2thr): ... here, call it. But don't before __stack_user > + is initialized, then fake a handle with th_unique=0. > + * thread_dbP.h: Declare it. > + > 2004-09-09 Roland McGrath <[email protected]> > > * td_ta_map_lwp2thr.c (td_ta_map_lwp2thr): Don't abort if inferior's > diff --git a/libpthread/nptl_db/db_info.c b/libpthread/nptl_db/db_info.c > index 521ad78..a57a053 100644 > --- a/libpthread/nptl_db/db_info.c > +++ b/libpthread/nptl_db/db_info.c > @@ -1,7 +1,7 @@ > /* This file is included by pthread_create.c to define in libpthread > all the magic symbols required by libthread_db. > > - Copyright (C) 2003, 2004 Free Software Foundation, Inc. > + Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc. > This file is part of the GNU C Library. > > The GNU C Library is free software; you can redistribute it and/or > @@ -37,6 +37,8 @@ typedef struct > > typedef struct link_map link_map; > > +/* Actually static in nptl/init.c, but we only need it for typeof. */ > +extern bool __nptl_initial_report_events; > > #define schedparam_sched_priority schedparam.sched_priority > > diff --git a/libpthread/nptl_db/structs.def b/libpthread/nptl_db/structs.def > index 915867b..bb571d4 100644 > --- a/libpthread/nptl_db/structs.def > +++ b/libpthread/nptl_db/structs.def > @@ -1,5 +1,5 @@ > /* List of types and symbols in libpthread examined by libthread_db. > - Copyright (C) 2003, 2006 Free Software Foundation, Inc. > + Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc. > This file is part of the GNU C Library. > > The GNU C Library is free software; you can redistribute it and/or > @@ -55,6 +55,7 @@ DB_FUNCTION (__nptl_death_event) > DB_SYMBOL (__nptl_threads_events) > DB_VARIABLE (__nptl_nthreads) > DB_VARIABLE (__nptl_last_event) > +DB_VARIABLE (__nptl_initial_report_events) > > DB_ARRAY_VARIABLE (__pthread_keys) > DB_STRUCT (pthread_key_struct) > diff --git a/libpthread/nptl_db/td_ta_map_lwp2thr.c > b/libpthread/nptl_db/td_ta_map_lwp2thr.c > index 9709777..6b4382f 100644 > --- a/libpthread/nptl_db/td_ta_map_lwp2thr.c > +++ b/libpthread/nptl_db/td_ta_map_lwp2thr.c > @@ -1,5 +1,5 @@ > /* Which thread is running on an LWP? > - Copyright (C) 2003, 2004 Free Software Foundation, Inc. > + Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc. > This file is part of the GNU C Library. > > The GNU C Library is free software; you can redistribute it and/or > @@ -23,8 +23,8 @@ > > > td_err_e > -td_ta_map_lwp2thr (const td_thragent_t *ta_arg, > - lwpid_t lwpid, td_thrhandle_t *th) > +__td_ta_lookup_th_unique (const td_thragent_t *ta_arg, > + lwpid_t lwpid, td_thrhandle_t *th) > { > td_thragent_t *const ta = (td_thragent_t *) ta_arg; > ps_err_e err; > @@ -117,9 +117,6 @@ td_ta_map_lwp2thr (const td_thragent_t *ta_arg, > > switch (ta->ta_howto) > { > - case ta_howto_unknown: > - return TD_DBERR; > - > default: > return TD_DBERR; > > @@ -131,6 +128,7 @@ td_ta_map_lwp2thr (const td_thragent_t *ta_arg, > 0, regs, &addr); > if (terr != TD_OK) > return terr; > + > /* In this descriptor the nelem word is overloaded as the bias. */ > addr += (int32_t) DB_DESC_NELEM (ta->ta_howto_data.reg); > th->th_unique = addr; > @@ -142,22 +140,22 @@ td_ta_map_lwp2thr (const td_thragent_t *ta_arg, > if (&ps_get_thread_area == NULL) > return TD_NOCAPAB; > > - /* A la x86-64, there is a constant magic index for get_thread_area. > */ > - if (ps_get_thread_area (ta->ph, lwpid, > - ta->ta_howto_data.const_thread_area, > - &th->th_unique) != PS_OK) > - return TD_ERR; /* XXX Other error value? */ > - break; > + /* A la x86-64, there is a magic index for get_thread_area. */ > + if (ps_get_thread_area (ta->ph, lwpid, > + ta->ta_howto_data.const_thread_area, > + &th->th_unique) != PS_OK) > + return TD_ERR; /* XXX Other error value? */ > + break; > > - case ta_howto_reg_thread_area: > + case ta_howto_reg_thread_area: > if (&ps_get_thread_area == NULL) > return TD_NOCAPAB; > > - /* A la i386, there is a register with an index for get_thread_area. > */ > - if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK) > - return TD_ERR; > - terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg_thread_area, > -1, > - 0, regs, &addr); > + /* A la i386, a register holds the index for get_thread_area. */ > + if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK) > + return TD_ERR; > + terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg_thread_area, > + -1, 0, regs, &addr); > if (terr != TD_OK) > return terr; > /* In this descriptor the nelem word is overloaded as scale factor. */ > @@ -171,7 +169,40 @@ td_ta_map_lwp2thr (const td_thragent_t *ta_arg, > } > > /* Found it. Now complete the `td_thrhandle_t' object. */ > - th->th_ta_p = (td_thragent_t *) ta; > + th->th_ta_p = ta; > > return TD_OK; > } > + > +td_err_e > +td_ta_map_lwp2thr (const td_thragent_t *ta_arg, > + lwpid_t lwpid, td_thrhandle_t *th) > +{ > + td_thragent_t *const ta = (td_thragent_t *) ta_arg; > + > + /* We cannot rely on thread registers and such information at all > + before __pthread_initialize_minimal has gotten far enough. They > + sometimes contain garbage that would confuse us, left by the kernel > + at exec. So if it looks like initialization is incomplete, we only > + fake a special descriptor for the initial thread. */ > + > + psaddr_t list; > + td_err_e err = DB_GET_SYMBOL (list, ta, __stack_user); > + if (err != TD_OK) > + return err; > + > + err = DB_GET_FIELD (list, ta, list, list_t, next, 0); > + if (err != TD_OK) > + return err; > + > + if (list == 0) > + { > + if (ps_getpid (ta->ph) != lwpid) > + return TD_ERR; > + th->th_ta_p = ta; > + th->th_unique = 0; > + return TD_OK; > + } > + > + return __td_ta_lookup_th_unique (ta_arg, lwpid, th); > +} > diff --git a/libpthread/nptl_db/td_ta_thr_iter.c > b/libpthread/nptl_db/td_ta_thr_iter.c > index 1fd02ef..0f1b2bf 100644 > --- a/libpthread/nptl_db/td_ta_thr_iter.c > +++ b/libpthread/nptl_db/td_ta_thr_iter.c > @@ -1,5 +1,6 @@ > /* Iterate over a process's threads. > - Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. > + Copyright (C) 1999,2000,2001,2002,2003,2004,2007 > + Free Software Foundation, Inc. > This file is part of the GNU C Library. > Contributed by Ulrich Drepper <[email protected]>, 1999. > > @@ -23,7 +24,7 @@ > static td_err_e > iterate_thread_list (td_thragent_t *ta, td_thr_iter_f *callback, > void *cbdata_p, td_thr_state_e state, int ti_pri, > - psaddr_t head, int fake_empty) > + psaddr_t head, bool fake_empty) > { > td_err_e err; > psaddr_t next, ofs; > @@ -40,13 +41,13 @@ iterate_thread_list (td_thragent_t *ta, td_thr_iter_f > *callback, > > if (next == 0 && fake_empty) > { > - /* __pthread_initialize_minimal has not run. > - There is just the main thread to return. */ > - td_thrhandle_t th; > - err = td_ta_map_lwp2thr (ta, ps_getpid (ta->ph), &th); > - if (err == TD_OK) > - err = callback (&th, cbdata_p) != 0 ? TD_DBERR : TD_OK; > - return err; > + /* __pthread_initialize_minimal has not run. There is just the main > + thread to return. We cannot rely on its thread register. They > + sometimes contain garbage that would confuse us, left by the > + kernel at exec. So if it looks like initialization is incomplete, > + we only fake a special descriptor for the initial thread. */ > + td_thrhandle_t th = { ta, 0 }; > + return callback (&th, cbdata_p) != 0 ? TD_DBERR : TD_OK; > } > > /* Cache the offset from struct pthread to its list_t member. */ > @@ -135,13 +136,15 @@ td_ta_thr_iter (const td_thragent_t *ta_arg, > td_thr_iter_f *callback, > > err = DB_GET_SYMBOL (list, ta, __stack_user); > if (err == TD_OK) > - err = iterate_thread_list (ta, callback, cbdata_p, state, ti_pri, list, > 1); > + err = iterate_thread_list (ta, callback, cbdata_p, state, ti_pri, > + list, true); > > /* And the threads with stacks allocated by the implementation. */ > if (err == TD_OK) > err = DB_GET_SYMBOL (list, ta, stack_used); > if (err == TD_OK) > - err = iterate_thread_list (ta, callback, cbdata_p, state, ti_pri, list, > 0); > + err = iterate_thread_list (ta, callback, cbdata_p, state, ti_pri, > + list, false); > > return err; > } > diff --git a/libpthread/nptl_db/td_thr_event_enable.c > b/libpthread/nptl_db/td_thr_event_enable.c > index f49682d..fd94580 100644 > --- a/libpthread/nptl_db/td_thr_event_enable.c > +++ b/libpthread/nptl_db/td_thr_event_enable.c > @@ -1,5 +1,5 @@ > /* Enable event process-wide. > - Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. > + Copyright (C) 1999, 2001, 2002, 2003, 2007 Free Software Foundation, Inc. > This file is part of the GNU C Library. > Contributed by Ulrich Drepper <[email protected]>, 1999. > > @@ -25,7 +25,25 @@ td_thr_event_enable (const td_thrhandle_t *th, int onoff) > { > LOG ("td_thr_event_enable"); > > - /* Write the new value into the thread data structure. */ > - return DB_PUT_FIELD (th->th_ta_p, th->th_unique, pthread, report_events, 0, > + if (th->th_unique != 0) > + { > + /* Write the new value into the thread data structure. */ > + td_err_e err = DB_PUT_FIELD (th->th_ta_p, th->th_unique, pthread, > + report_events, 0, > + (psaddr_t) 0 + (onoff != 0)); > + if (err != TD_OK) > + return err; > + > + /* Just in case we are in the window between initializing __stack_user > + and copying from __nptl_initial_report_events, we set it too. > + It doesn't hurt to do this for non-initial threads, since it > + won't be consulted again anyway. It would take another fetch > + to get the tid and determine this isn't the initial thread, > + so just do it always. */ > + } > + > + /* We are faking it for the initial thread before its thread > + descriptor is set up. */ > + return DB_PUT_VALUE (th->th_ta_p, __nptl_initial_report_events, 0, > (psaddr_t) 0 + (onoff != 0)); > } > diff --git a/libpthread/nptl_db/td_thr_get_info.c > b/libpthread/nptl_db/td_thr_get_info.c > index 09d0d1a..27d5d70 100644 > --- a/libpthread/nptl_db/td_thr_get_info.c > +++ b/libpthread/nptl_db/td_thr_get_info.c > @@ -1,5 +1,5 @@ > /* Get thread information. > - Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. > + Copyright (C) 1999,2000,2001,2002,2003,2007 Free Software Foundation, Inc. > This file is part of the GNU C Library. > Contributed by Ulrich Drepper <[email protected]>, 1999. > > @@ -31,35 +31,49 @@ td_thr_get_info (const td_thrhandle_t *th, td_thrinfo_t > *infop) > > LOG ("td_thr_get_info"); > > - /* Copy the whole descriptor in once so we can access the several > - fields locally. Excess copying in one go is much better than > - multiple ps_pdread calls. */ > - err = DB_GET_STRUCT (copy, th->th_ta_p, th->th_unique, pthread); > - if (err != TD_OK) > - return err; > - > - err = DB_GET_FIELD_ADDRESS (tls, th->th_ta_p, th->th_unique, > - pthread, specific, 0); > - if (err != TD_OK) > - return err; > - > - err = DB_GET_FIELD_LOCAL (schedpolicy, th->th_ta_p, copy, pthread, > - schedpolicy, 0); > - if (err != TD_OK) > - return err; > - err = DB_GET_FIELD_LOCAL (schedprio, th->th_ta_p, copy, pthread, > - schedparam_sched_priority, 0); > - if (err != TD_OK) > - return err; > - err = DB_GET_FIELD_LOCAL (tid, th->th_ta_p, copy, pthread, tid, 0); > - if (err != TD_OK) > - return err; > - err = DB_GET_FIELD_LOCAL (cancelhandling, th->th_ta_p, copy, pthread, > - cancelhandling, 0); > - if (err != TD_OK) > - return err; > - err = DB_GET_FIELD_LOCAL (report_events, th->th_ta_p, copy, pthread, > - report_events, 0); > + if (th->th_unique == 0) > + { > + /* Special case for the main thread before initialization. */ > + copy = NULL; > + tls = 0; > + cancelhandling = 0; > + schedprio = 0; > + tid = 0; > + err = DB_GET_VALUE (report_events, th->th_ta_p, > + __nptl_initial_report_events, 0); > + } > + else > + { > + /* Copy the whole descriptor in once so we can access the several > + fields locally. Excess copying in one go is much better than > + multiple ps_pdread calls. */ > + err = DB_GET_STRUCT (copy, th->th_ta_p, th->th_unique, pthread); > + if (err != TD_OK) > + return err; > + > + err = DB_GET_FIELD_ADDRESS (tls, th->th_ta_p, th->th_unique, > + pthread, specific, 0); > + if (err != TD_OK) > + return err; > + > + err = DB_GET_FIELD_LOCAL (schedpolicy, th->th_ta_p, copy, pthread, > + schedpolicy, 0); > + if (err != TD_OK) > + return err; > + err = DB_GET_FIELD_LOCAL (schedprio, th->th_ta_p, copy, pthread, > + schedparam_sched_priority, 0); > + if (err != TD_OK) > + return err; > + err = DB_GET_FIELD_LOCAL (tid, th->th_ta_p, copy, pthread, tid, 0); > + if (err != TD_OK) > + return err; > + err = DB_GET_FIELD_LOCAL (cancelhandling, th->th_ta_p, copy, pthread, > + cancelhandling, 0); > + if (err != TD_OK) > + return err; > + err = DB_GET_FIELD_LOCAL (report_events, th->th_ta_p, copy, pthread, > + report_events, 0); > + } > if (err != TD_OK) > return err; > > @@ -86,9 +100,10 @@ td_thr_get_info (const td_thrhandle_t *th, td_thrinfo_t > *infop) > infop->ti_lid = tid == 0 ? ps_getpid (th->th_ta_p->ph) : (uintptr_t) tid; > infop->ti_traceme = report_events != 0; > > - err = DB_GET_FIELD_LOCAL (infop->ti_startfunc, th->th_ta_p, copy, pthread, > - start_routine, 0); > - if (err == TD_OK) > + if (copy != NULL) > + err = DB_GET_FIELD_LOCAL (infop->ti_startfunc, th->th_ta_p, copy, > pthread, > + start_routine, 0); > + if (copy != NULL && err == TD_OK) > { > uint32_t idx; > for (idx = 0; idx < TD_EVENTSIZE; ++idx) > diff --git a/libpthread/nptl_db/td_thr_getfpregs.c > b/libpthread/nptl_db/td_thr_getfpregs.c > index ff4b599..4f4742a 100644 > --- a/libpthread/nptl_db/td_thr_getfpregs.c > +++ b/libpthread/nptl_db/td_thr_getfpregs.c > @@ -1,5 +1,5 @@ > /* Get a thread's floating-point register set. > - Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. > + Copyright (C) 1999, 2001, 2002, 2003, 2007 Free Software Foundation, Inc. > This file is part of the GNU C Library. > Contributed by Ulrich Drepper <[email protected]>, 1999. > > @@ -28,6 +28,11 @@ td_thr_getfpregs (const td_thrhandle_t *th, prfpregset_t > *regset) > > LOG ("td_thr_getfpregs"); > > + if (th->th_unique == 0) > + /* Special case for the main thread before initialization. */ > + return ps_lgetfpregs (th->th_ta_p->ph, ps_getpid (th->th_ta_p->ph), > + regset) != PS_OK ? TD_ERR : TD_OK; > + > /* We have to get the state and the PID for this thread. */ > err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread, > cancelhandling, 0); > diff --git a/libpthread/nptl_db/td_thr_getgregs.c > b/libpthread/nptl_db/td_thr_getgregs.c > index 497941b..d5f0f61 100644 > --- a/libpthread/nptl_db/td_thr_getgregs.c > +++ b/libpthread/nptl_db/td_thr_getgregs.c > @@ -1,5 +1,5 @@ > /* Get a thread's general register set. > - Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. > + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2007 Free Software > Foundation, Inc. > This file is part of the GNU C Library. > Contributed by Ulrich Drepper <[email protected]>, 1999. > > @@ -28,6 +28,11 @@ td_thr_getgregs (const td_thrhandle_t *th, prgregset_t > regset) > > LOG ("td_thr_getgregs"); > > + if (th->th_unique == 0) > + /* Special case for the main thread before initialization. */ > + return ps_lgetregs (th->th_ta_p->ph, ps_getpid (th->th_ta_p->ph), > + regset) != PS_OK ? TD_ERR : TD_OK; > + > /* We have to get the state and the PID for this thread. */ > err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread, > cancelhandling, 0); > diff --git a/libpthread/nptl_db/td_thr_setfpregs.c > b/libpthread/nptl_db/td_thr_setfpregs.c > index 3c4e8ed..3154953 100644 > --- a/libpthread/nptl_db/td_thr_setfpregs.c > +++ b/libpthread/nptl_db/td_thr_setfpregs.c > @@ -1,5 +1,5 @@ > /* Set a thread's floating-point register set. > - Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. > + Copyright (C) 1999, 2001, 2002, 2003, 2007 Free Software Foundation, Inc. > This file is part of the GNU C Library. > Contributed by Ulrich Drepper <[email protected]>, 1999. > > @@ -28,6 +28,11 @@ td_thr_setfpregs (const td_thrhandle_t *th, const > prfpregset_t *fpregs) > > LOG ("td_thr_setfpregs"); > > + if (th->th_unique == 0) > + /* Special case for the main thread before initialization. */ > + return ps_lsetfpregs (th->th_ta_p->ph, ps_getpid (th->th_ta_p->ph), > + fpregs) != PS_OK ? TD_ERR : TD_OK; > + > /* We have to get the state and the PID for this thread. */ > err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread, > cancelhandling, 0); > diff --git a/libpthread/nptl_db/td_thr_setgregs.c > b/libpthread/nptl_db/td_thr_setgregs.c > index 83d2cd9..5945dea 100644 > --- a/libpthread/nptl_db/td_thr_setgregs.c > +++ b/libpthread/nptl_db/td_thr_setgregs.c > @@ -1,5 +1,5 @@ > /* Set a thread's general register set. > - Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. > + Copyright (C) 1999, 2001, 2002, 2003, 2007 Free Software Foundation, Inc. > This file is part of the GNU C Library. > Contributed by Ulrich Drepper <[email protected]>, 1999. > > @@ -28,6 +28,11 @@ td_thr_setgregs (const td_thrhandle_t *th, prgregset_t > gregs) > > LOG ("td_thr_setgregs"); > > + if (th->th_unique == 0) > + /* Special case for the main thread before initialization. */ > + return ps_lsetregs (th->th_ta_p->ph, ps_getpid (th->th_ta_p->ph), > + gregs) != PS_OK ? TD_ERR : TD_OK; > + > /* We have to get the state and the PID for this thread. */ > err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread, > cancelhandling, 0); > diff --git a/libpthread/nptl_db/td_thr_tlsbase.c > b/libpthread/nptl_db/td_thr_tlsbase.c > index f7d4c29..9f98bd9 100644 > --- a/libpthread/nptl_db/td_thr_tlsbase.c > +++ b/libpthread/nptl_db/td_thr_tlsbase.c > @@ -1,5 +1,5 @@ > /* Locate TLS data for a thread. > - Copyright (C) 2003, 2006 Free Software Foundation, Inc. > + Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc. > This file is part of the GNU C Library. > > The GNU C Library is free software; you can redistribute it and/or > @@ -29,8 +29,29 @@ td_thr_tlsbase (const td_thrhandle_t *th, > if (modid < 1) > return TD_NOTLS; > > + psaddr_t pd = th->th_unique; > + if (pd == 0) > + { > + /* This is the fake handle for the main thread before libpthread > + initialization. We are using 0 for its th_unique because we can't > + trust that its thread register has been initialized. But we need > + a real pointer to have any TLS access work. In case of dlopen'd > + libpthread, initialization might not be for quite some time. So > + try looking up the thread register now. Worst case, it's nonzero > + uninitialized garbage and we get bogus results for TLS access > + attempted too early. Tough. */ > + > + td_thrhandle_t main_th; > + err = __td_ta_lookup_th_unique (th->th_ta_p, ps_getpid > (th->th_ta_p->ph), > + &main_th); > + if (err == 0) > + pd = main_th.th_unique; > + if (pd == 0) > + return TD_TLSDEFER; > + } > + > /* Get the DTV pointer from the thread descriptor. */ > - err = DB_GET_FIELD (dtv, th->th_ta_p, th->th_unique, pthread, dtvp, 0); > + err = DB_GET_FIELD (dtv, th->th_ta_p, pd, pthread, dtvp, 0); > if (err != TD_OK) > return err; > > diff --git a/libpthread/nptl_db/td_thr_validate.c > b/libpthread/nptl_db/td_thr_validate.c > index 49c30c1..1b96b51 100644 > --- a/libpthread/nptl_db/td_thr_validate.c > +++ b/libpthread/nptl_db/td_thr_validate.c > @@ -1,5 +1,5 @@ > /* Validate a thread handle. > - Copyright (C) 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. > + Copyright (C) 1999,2001,2002,2003,2004,2007 Free Software Foundation, Inc. > This file is part of the GNU C Library. > Contributed by Ulrich Drepper <[email protected]>, 1999. > > @@ -74,16 +74,10 @@ td_thr_validate (const td_thrhandle_t *th) > if (err == TD_OK) > err = check_thread_list (th, list, &uninit); > > - if (err == TD_NOTHR && uninit) > - { > - /* __pthread_initialize_minimal has not run yet. > - But the main thread still has a valid ID. */ > - td_thrhandle_t main_th; > - err = td_ta_map_lwp2thr (th->th_ta_p, > - ps_getpid (th->th_ta_p->ph), &main_th); > - if (err == TD_OK && th->th_unique != main_th.th_unique) > - err = TD_NOTHR; > - } > + if (err == TD_NOTHR && uninit && th->th_unique == 0) > + /* __pthread_initialize_minimal has not run yet. > + There is only the special case thread handle. */ > + err = TD_OK; > } > > return err; > diff --git a/libpthread/nptl_db/thread_dbP.h b/libpthread/nptl_db/thread_dbP.h > index 24623ef..b8399f7 100644 > --- a/libpthread/nptl_db/thread_dbP.h > +++ b/libpthread/nptl_db/thread_dbP.h > @@ -1,5 +1,5 @@ > /* Private header for thread debug library > - Copyright (C) 2003, 2004 Free Software Foundation, Inc. > + Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc. > This file is part of the GNU C Library. > > The GNU C Library is free software; you can redistribute it and/or > @@ -254,4 +254,7 @@ extern td_err_e _td_store_value_local (td_thragent_t *ta, > extern td_err_e _td_check_sizeof (td_thragent_t *ta, uint32_t *sizep, > int sizep_name) attribute_hidden; > > +extern td_err_e __td_ta_lookup_th_unique (const td_thragent_t *ta, > + lwpid_t lwpid, td_thrhandle_t *th); > + > #endif /* thread_dbP.h */ >
_______________________________________________ uClibc mailing list [email protected] http://lists.busybox.net/mailman/listinfo/uclibc
