Back to index

glibc  2.9
Functions
td_thr_validate.c File Reference
#include "thread_dbP.h"
#include <stdbool.h>

Go to the source code of this file.

Functions

static td_err_e check_thread_list (const td_thrhandle_t *th, psaddr_t head, bool *uninit)
td_err_e td_thr_validate (const td_thrhandle_t *th)

Function Documentation

static td_err_e check_thread_list ( const td_thrhandle_t th,
psaddr_t  head,
bool *  uninit 
) [static]

Definition at line 26 of file td_thr_validate.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 58 of file td_thr_validate.c.

{
  td_err_e err;
  psaddr_t list;

  LOG ("td_thr_validate");

  /* First check the list with threads using user allocated stacks.  */
  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 (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;
    }

  if (err == TD_OK)
    {
      /* Verify that this is not a stale element in a fork child.  */
      pid_t match_pid = ps_getpid (th->th_ta_p->ph);
      psaddr_t pid;
      err = DB_GET_FIELD (pid, th->th_ta_p, th->th_unique, pthread, pid, 0);
      if (err == TD_OK && (pid_t) (uintptr_t) pid < 0)
       {
         /* This was a thread that was about to fork, or it is the new sole
            thread in a fork child.  In the latter case, its tid was stored
            via CLONE_CHILD_SETTID and so is already the proper child PID.  */
         if (-(pid_t) (uintptr_t) pid == match_pid)
           /* It is about to do a fork, but is really still the parent PID.  */
           pid = (psaddr_t) (uintptr_t) match_pid;
         else
           /* It must be a fork child, whose new PID is in the tid field.  */
           err = DB_GET_FIELD (pid, th->th_ta_p, th->th_unique,
                            pthread, tid, 0);
       }
      if (err == TD_OK && (pid_t) (uintptr_t) pid != match_pid)
       err = TD_NOTHR;
    }

  return err;
}

Here is the call graph for this function: