summaryrefslogtreecommitdiff
path: root/libpthread/nptl_db/td_ta_map_lwp2thr.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2015-04-28 11:07:24 +0800
committerWaldemar Brodkorb <wbx@openadk.org>2015-06-10 10:17:53 -0500
commit8d92e32a73655a0820ce5085f017911abaad28b3 (patch)
tree0cb314484a17a76b3255a795f3103e41b877b8b2 /libpthread/nptl_db/td_ta_map_lwp2thr.c
parent8484e59e6b1dfe424d13f736c146aafbeac5cabf (diff)
init.c (__nptl_initial_report_events): New variable.
(__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: Roland McGrath <roland@gnu.org> Signed-off-by: Sheng Yong <shengyong1@huawei.com> Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Diffstat (limited to 'libpthread/nptl_db/td_ta_map_lwp2thr.c')
-rw-r--r--libpthread/nptl_db/td_ta_map_lwp2thr.c69
1 files changed, 50 insertions, 19 deletions
diff --git a/libpthread/nptl_db/td_ta_map_lwp2thr.c b/libpthread/nptl_db/td_ta_map_lwp2thr.c
index 97097777b..6b4382fbd 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);
+}