mirror of git://sourceware.org/git/glibc.git
* init.c (__nptl_initial_report_events): New variable.
(__pthread_initialize_minimal_internal): Initialize pd->report_events to that.
This commit is contained in:
parent
0ecf9c1064
commit
7d9d8bd189
|
@ -1,3 +1,9 @@
|
||||||
|
2007-05-16 Roland McGrath <roland@redhat.com>
|
||||||
|
|
||||||
|
* init.c (__nptl_initial_report_events): New variable.
|
||||||
|
(__pthread_initialize_minimal_internal): Initialize pd->report_events
|
||||||
|
to that.
|
||||||
|
|
||||||
2007-06-22 Jakub Jelinek <jakub@redhat.com>
|
2007-06-22 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* pthread_getattr_np.c (pthread_getattr_np): Clear cpuset and
|
* pthread_getattr_np.c (pthread_getattr_np): Clear cpuset and
|
||||||
|
|
|
@ -1,3 +1,26 @@
|
||||||
|
2007-05-16 Roland McGrath <roland@redhat.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2006-10-26 Pete Eberlein <eberlein@us.ibm.com>
|
2006-10-26 Pete Eberlein <eberlein@us.ibm.com>
|
||||||
|
|
||||||
* nptl_db/db_info.c [TLS_DTV_AT_TP]: Fixed size init for dtvp
|
* nptl_db/db_info.c [TLS_DTV_AT_TP]: Fixed size init for dtvp
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* This file is included by pthread_create.c to define in libpthread
|
/* This file is included by pthread_create.c to define in libpthread
|
||||||
all the magic symbols required by libthread_db.
|
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.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
@ -38,6 +38,8 @@ typedef struct
|
||||||
|
|
||||||
typedef struct link_map link_map;
|
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
|
#define schedparam_sched_priority schedparam.sched_priority
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* List of types and symbols in libpthread examined by libthread_db.
|
/* 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.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
@ -56,6 +56,7 @@ DB_FUNCTION (__nptl_death_event)
|
||||||
DB_SYMBOL (__nptl_threads_events)
|
DB_SYMBOL (__nptl_threads_events)
|
||||||
DB_VARIABLE (__nptl_nthreads)
|
DB_VARIABLE (__nptl_nthreads)
|
||||||
DB_VARIABLE (__nptl_last_event)
|
DB_VARIABLE (__nptl_last_event)
|
||||||
|
DB_VARIABLE (__nptl_initial_report_events)
|
||||||
|
|
||||||
DB_ARRAY_VARIABLE (__pthread_keys)
|
DB_ARRAY_VARIABLE (__pthread_keys)
|
||||||
DB_STRUCT (pthread_key_struct)
|
DB_STRUCT (pthread_key_struct)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Which thread is running on an LWP?
|
/* 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.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
|
|
||||||
td_err_e
|
td_err_e
|
||||||
td_ta_map_lwp2thr (const td_thragent_t *ta_arg,
|
__td_ta_lookup_th_unique (const td_thragent_t *ta_arg,
|
||||||
lwpid_t lwpid, td_thrhandle_t *th)
|
lwpid_t lwpid, td_thrhandle_t *th)
|
||||||
{
|
{
|
||||||
td_thragent_t *const ta = (td_thragent_t *) ta_arg;
|
td_thragent_t *const ta = (td_thragent_t *) ta_arg;
|
||||||
|
@ -118,9 +118,6 @@ td_ta_map_lwp2thr (const td_thragent_t *ta_arg,
|
||||||
|
|
||||||
switch (ta->ta_howto)
|
switch (ta->ta_howto)
|
||||||
{
|
{
|
||||||
case ta_howto_unknown:
|
|
||||||
return TD_DBERR;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return TD_DBERR;
|
return TD_DBERR;
|
||||||
|
|
||||||
|
@ -132,6 +129,7 @@ td_ta_map_lwp2thr (const td_thragent_t *ta_arg,
|
||||||
0, regs, &addr);
|
0, regs, &addr);
|
||||||
if (terr != TD_OK)
|
if (terr != TD_OK)
|
||||||
return terr;
|
return terr;
|
||||||
|
|
||||||
/* In this descriptor the nelem word is overloaded as the bias. */
|
/* In this descriptor the nelem word is overloaded as the bias. */
|
||||||
addr += (int32_t) DB_DESC_NELEM (ta->ta_howto_data.reg);
|
addr += (int32_t) DB_DESC_NELEM (ta->ta_howto_data.reg);
|
||||||
th->th_unique = addr;
|
th->th_unique = addr;
|
||||||
|
@ -143,7 +141,7 @@ td_ta_map_lwp2thr (const td_thragent_t *ta_arg,
|
||||||
if (&ps_get_thread_area == NULL)
|
if (&ps_get_thread_area == NULL)
|
||||||
return TD_NOCAPAB;
|
return TD_NOCAPAB;
|
||||||
|
|
||||||
/* A la x86-64, there is a constant magic index for get_thread_area. */
|
/* A la x86-64, there is a magic index for get_thread_area. */
|
||||||
if (ps_get_thread_area (ta->ph, lwpid,
|
if (ps_get_thread_area (ta->ph, lwpid,
|
||||||
ta->ta_howto_data.const_thread_area,
|
ta->ta_howto_data.const_thread_area,
|
||||||
&th->th_unique) != PS_OK)
|
&th->th_unique) != PS_OK)
|
||||||
|
@ -154,11 +152,11 @@ td_ta_map_lwp2thr (const td_thragent_t *ta_arg,
|
||||||
if (&ps_get_thread_area == NULL)
|
if (&ps_get_thread_area == NULL)
|
||||||
return TD_NOCAPAB;
|
return TD_NOCAPAB;
|
||||||
|
|
||||||
/* A la i386, there is a register with an index for get_thread_area. */
|
/* A la i386, a register holds the index for get_thread_area. */
|
||||||
if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
|
if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
|
||||||
return TD_ERR;
|
return TD_ERR;
|
||||||
terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg_thread_area, -1,
|
terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg_thread_area,
|
||||||
0, regs, &addr);
|
-1, 0, regs, &addr);
|
||||||
if (terr != TD_OK)
|
if (terr != TD_OK)
|
||||||
return terr;
|
return terr;
|
||||||
/* In this descriptor the nelem word is overloaded as scale factor. */
|
/* In this descriptor the nelem word is overloaded as scale factor. */
|
||||||
|
@ -172,7 +170,40 @@ td_ta_map_lwp2thr (const td_thragent_t *ta_arg,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Found it. Now complete the `td_thrhandle_t' object. */
|
/* 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;
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* Iterate over a process's threads.
|
/* 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.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@
|
||||||
static td_err_e
|
static td_err_e
|
||||||
iterate_thread_list (td_thragent_t *ta, td_thr_iter_f *callback,
|
iterate_thread_list (td_thragent_t *ta, td_thr_iter_f *callback,
|
||||||
void *cbdata_p, td_thr_state_e state, int ti_pri,
|
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;
|
td_err_e err;
|
||||||
psaddr_t next, ofs;
|
psaddr_t next, ofs;
|
||||||
|
@ -41,13 +42,13 @@ iterate_thread_list (td_thragent_t *ta, td_thr_iter_f *callback,
|
||||||
|
|
||||||
if (next == 0 && fake_empty)
|
if (next == 0 && fake_empty)
|
||||||
{
|
{
|
||||||
/* __pthread_initialize_minimal has not run.
|
/* __pthread_initialize_minimal has not run. There is just the main
|
||||||
There is just the main thread to return. */
|
thread to return. We cannot rely on its thread register. They
|
||||||
td_thrhandle_t th;
|
sometimes contain garbage that would confuse us, left by the
|
||||||
err = td_ta_map_lwp2thr (ta, ps_getpid (ta->ph), &th);
|
kernel at exec. So if it looks like initialization is incomplete,
|
||||||
if (err == TD_OK)
|
we only fake a special descriptor for the initial thread. */
|
||||||
err = callback (&th, cbdata_p) != 0 ? TD_DBERR : TD_OK;
|
td_thrhandle_t th = { ta, 0 };
|
||||||
return err;
|
return callback (&th, cbdata_p) != 0 ? TD_DBERR : TD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cache the offset from struct pthread to its list_t member. */
|
/* Cache the offset from struct pthread to its list_t member. */
|
||||||
|
@ -136,13 +137,15 @@ td_ta_thr_iter (const td_thragent_t *ta_arg, td_thr_iter_f *callback,
|
||||||
|
|
||||||
err = DB_GET_SYMBOL (list, ta, __stack_user);
|
err = DB_GET_SYMBOL (list, ta, __stack_user);
|
||||||
if (err == TD_OK)
|
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. */
|
/* And the threads with stacks allocated by the implementation. */
|
||||||
if (err == TD_OK)
|
if (err == TD_OK)
|
||||||
err = DB_GET_SYMBOL (list, ta, stack_used);
|
err = DB_GET_SYMBOL (list, ta, stack_used);
|
||||||
if (err == TD_OK)
|
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;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Enable event process-wide.
|
/* 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.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
||||||
|
|
||||||
|
@ -28,7 +28,25 @@ td_thr_event_enable (th, onoff)
|
||||||
{
|
{
|
||||||
LOG ("td_thr_event_enable");
|
LOG ("td_thr_event_enable");
|
||||||
|
|
||||||
|
if (th->th_unique != 0)
|
||||||
|
{
|
||||||
/* Write the new value into the thread data structure. */
|
/* Write the new value into the thread data structure. */
|
||||||
return DB_PUT_FIELD (th->th_ta_p, th->th_unique, pthread, report_events, 0,
|
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));
|
(psaddr_t) 0 + (onoff != 0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Get thread information.
|
/* 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.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
||||||
|
|
||||||
|
@ -32,6 +32,19 @@ td_thr_get_info (const td_thrhandle_t *th, td_thrinfo_t *infop)
|
||||||
|
|
||||||
LOG ("td_thr_get_info");
|
LOG ("td_thr_get_info");
|
||||||
|
|
||||||
|
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
|
/* Copy the whole descriptor in once so we can access the several
|
||||||
fields locally. Excess copying in one go is much better than
|
fields locally. Excess copying in one go is much better than
|
||||||
multiple ps_pdread calls. */
|
multiple ps_pdread calls. */
|
||||||
|
@ -61,6 +74,7 @@ td_thr_get_info (const td_thrhandle_t *th, td_thrinfo_t *infop)
|
||||||
return err;
|
return err;
|
||||||
err = DB_GET_FIELD_LOCAL (report_events, th->th_ta_p, copy, pthread,
|
err = DB_GET_FIELD_LOCAL (report_events, th->th_ta_p, copy, pthread,
|
||||||
report_events, 0);
|
report_events, 0);
|
||||||
|
}
|
||||||
if (err != TD_OK)
|
if (err != TD_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -87,9 +101,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_lid = tid == 0 ? ps_getpid (th->th_ta_p->ph) : (uintptr_t) tid;
|
||||||
infop->ti_traceme = report_events != 0;
|
infop->ti_traceme = report_events != 0;
|
||||||
|
|
||||||
|
if (copy != NULL)
|
||||||
err = DB_GET_FIELD_LOCAL (infop->ti_startfunc, th->th_ta_p, copy, pthread,
|
err = DB_GET_FIELD_LOCAL (infop->ti_startfunc, th->th_ta_p, copy, pthread,
|
||||||
start_routine, 0);
|
start_routine, 0);
|
||||||
if (err == TD_OK)
|
if (copy != NULL && err == TD_OK)
|
||||||
{
|
{
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
for (idx = 0; idx < TD_EVENTSIZE; ++idx)
|
for (idx = 0; idx < TD_EVENTSIZE; ++idx)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Get a thread's floating-point register set.
|
/* 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.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
||||||
|
|
||||||
|
@ -29,6 +29,11 @@ td_thr_getfpregs (const td_thrhandle_t *th, prfpregset_t *regset)
|
||||||
|
|
||||||
LOG ("td_thr_getfpregs");
|
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. */
|
/* 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,
|
err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread,
|
||||||
cancelhandling, 0);
|
cancelhandling, 0);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Get a thread's general register set.
|
/* 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.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
||||||
|
|
||||||
|
@ -29,6 +29,11 @@ td_thr_getgregs (const td_thrhandle_t *th, prgregset_t regset)
|
||||||
|
|
||||||
LOG ("td_thr_getgregs");
|
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. */
|
/* 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,
|
err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread,
|
||||||
cancelhandling, 0);
|
cancelhandling, 0);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Set a thread's floating-point register set.
|
/* 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.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
||||||
|
|
||||||
|
@ -29,6 +29,11 @@ td_thr_setfpregs (const td_thrhandle_t *th, const prfpregset_t *fpregs)
|
||||||
|
|
||||||
LOG ("td_thr_setfpregs");
|
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. */
|
/* 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,
|
err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread,
|
||||||
cancelhandling, 0);
|
cancelhandling, 0);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Set a thread's general register set.
|
/* 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.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
||||||
|
|
||||||
|
@ -29,6 +29,11 @@ td_thr_setgregs (const td_thrhandle_t *th, prgregset_t gregs)
|
||||||
|
|
||||||
LOG ("td_thr_setgregs");
|
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. */
|
/* 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,
|
err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread,
|
||||||
cancelhandling, 0);
|
cancelhandling, 0);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Locate TLS data for a thread.
|
/* 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.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
@ -30,8 +30,29 @@ td_thr_tlsbase (const td_thrhandle_t *th,
|
||||||
if (modid < 1)
|
if (modid < 1)
|
||||||
return TD_NOTLS;
|
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. */
|
/* 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)
|
if (err != TD_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Validate a thread handle.
|
/* 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.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
|
||||||
|
|
||||||
|
@ -75,16 +75,10 @@ td_thr_validate (const td_thrhandle_t *th)
|
||||||
if (err == TD_OK)
|
if (err == TD_OK)
|
||||||
err = check_thread_list (th, list, &uninit);
|
err = check_thread_list (th, list, &uninit);
|
||||||
|
|
||||||
if (err == TD_NOTHR && uninit)
|
if (err == TD_NOTHR && uninit && th->th_unique == 0)
|
||||||
{
|
|
||||||
/* __pthread_initialize_minimal has not run yet.
|
/* __pthread_initialize_minimal has not run yet.
|
||||||
But the main thread still has a valid ID. */
|
There is only the special case thread handle. */
|
||||||
td_thrhandle_t main_th;
|
err = TD_OK;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Private header for thread debug library
|
/* 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.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
@ -251,4 +251,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,
|
extern td_err_e _td_check_sizeof (td_thragent_t *ta, uint32_t *sizep,
|
||||||
int sizep_name) attribute_hidden;
|
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 */
|
#endif /* thread_dbP.h */
|
||||||
|
|
Loading…
Reference in New Issue