/* Validate a thread handle.
- Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
#include "thread_dbP.h"
-
+#include <stdbool.h>
static td_err_e
-check_thread_list (const td_thrhandle_t *th, psaddr_t head)
+check_thread_list (const td_thrhandle_t *th, psaddr_t head, bool *uninit)
{
- list_t list;
- td_err_e result = TD_NOTHR;
-
- if (ps_pdread (th->th_ta_p->ph, head, &list.next, sizeof (list.next))
- != PS_OK)
- return TD_ERR; /* XXX Other error value? */
-
- while (list.next != head)
- if ((psaddr_t) list.next - offsetof (struct pthread, header.data.list)
- == th->th_unique)
- {
- result = TD_OK;
- break;
- }
- else if (ps_pdread (th->th_ta_p->ph, list.next, &list.next,
- sizeof (list.next)) != PS_OK)
- {
- result = TD_ERR; /* XXX Other error value? */
- break;
- }
-
- return result;
+ td_err_e err;
+ psaddr_t next, ofs;
+
+ err = DB_GET_FIELD (next, th->th_ta_p, head, list_t, next, 0);
+ if (err == TD_OK)
+ {
+ if (next == 0)
+ {
+ *uninit = true;
+ return TD_NOTHR;
+ }
+ err = DB_GET_FIELD_ADDRESS (ofs, th->th_ta_p, 0, pthread, list, 0);
+ }
+
+ while (err == TD_OK)
+ {
+ if (next == head)
+ return TD_NOTHR;
+
+ if (next - (ofs - (psaddr_t) 0) == th->th_unique)
+ return TD_OK;
+
+ err = DB_GET_FIELD (next, th->th_ta_p, next, list_t, next, 0);
+ }
+
+ return err;
}
td_err_e
td_thr_validate (const td_thrhandle_t *th)
{
+ td_err_e err;
+ psaddr_t list;
+
LOG ("td_thr_validate");
/* First check the list with threads using user allocated stacks. */
- td_err_e result = check_thread_list (th, th->th_ta_p->stack_user);
+ bool uninit = false;
+ err = DB_GET_SYMBOL (list, th->th_ta_p, __stack_user);
+ if (err == TD_OK)
+ err = check_thread_list (th, list, &uninit);
/* If our thread is not on this list search the list with stack
using implementation allocated stacks. */
- if (result == TD_NOTHR)
- result = check_thread_list (th, th->th_ta_p->stack_used);
+ if (err == TD_NOTHR)
+ {
+ err = DB_GET_SYMBOL (list, th->th_ta_p, stack_used);
+ if (err == TD_OK)
+ err = check_thread_list (th, list, &uninit);
+
+ 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 result;
+ return err;
}