Exemplo n.º 1
0
td_err_e
td_ta_clear_event(const td_thragent_t *ta, td_thr_events_t *event)
{
  td_thr_events_t old_event;
  int i;

  LOG ("td_ta_clear_event");

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  /* Write the new value into the thread data structure.  */
  if (ps_pdread (ta->ph, ta->pthread_threads_eventsp,
		 &old_event, sizeof (td_thr_events_t)) != PS_OK)
    return TD_ERR;	/* XXX Other error value?  */

  /* Remove the set bits in.  */
  for (i = 0; i < TD_EVENTSIZE; ++i)
    old_event.event_bits[i] &= ~event->event_bits[i];

  /* Write the new value into the thread data structure.  */
  if (ps_pdwrite (ta->ph, ta->pthread_threads_eventsp,
		  &old_event, sizeof (td_thr_events_t)) != PS_OK)
    return TD_ERR;	/* XXX Other error value?  */

  return TD_OK;
}
Exemplo n.º 2
0
td_err_e
td_ta_tsd_iter (const td_thragent_t *ta, td_key_iter_f *callback,
		void *cbdata_p)
{
  struct pthread_key_struct *keys;
  int pthread_keys_max;
  int cnt;

  LOG ("td_ta_tsd_iter");

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  pthread_keys_max = ta->pthread_keys_max;
  keys = (struct pthread_key_struct *) alloca (sizeof (keys[0])
					       * pthread_keys_max);

  /* Read all the information about the keys.  */
  if (ps_pdread (ta->ph, ta->keys, keys,
		 sizeof (keys[0]) * pthread_keys_max) != PS_OK)
	return TD_ERR;	/* XXX Other error value?  */

  /* Now get all descriptors, one after the other.  */
  for (cnt = 0; cnt < pthread_keys_max; ++cnt)
    if (keys[cnt].in_use
	/* Return with an error if the callback returns a nonzero value.  */
	&& callback (cnt, keys[cnt].destr, cbdata_p) != 0)
      return TD_DBERR;

  return TD_OK;
}
Exemplo n.º 3
0
td_err_e
td_ta_tsd_iter (const td_thragent_t *ta_arg, td_key_iter_f *callback,
		void *cbdata_p)
{
  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
  td_err_e err;
  void *keys;
  size_t keys_nb, keys_elemsize;
  psaddr_t addr;
  uint32_t idx;

  LOG ("td_ta_tsd_iter");

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  /* This makes sure we have the size information on hand.  */
  addr = 0;
  err = _td_locate_field (ta,
			  ta->ta_var___pthread_keys, SYM_DESC___pthread_keys,
			  (psaddr_t) 0 + 1, &addr);
  if (err != TD_OK)
    return err;

  /* Now copy in the entire array of key descriptors.  */
  keys_elemsize = (addr - (psaddr_t) 0) / 8;
  keys_nb = keys_elemsize * DB_DESC_NELEM (ta->ta_var___pthread_keys);
  keys = __alloca (keys_nb);
  err = DB_GET_SYMBOL (addr, ta, __pthread_keys);
  if (err != TD_OK)
    return err;
  if (ps_pdread (ta->ph, addr, keys, keys_nb) != PS_OK)
    return TD_ERR;

  /* Now get all descriptors, one after the other.  */
  for (idx = 0; idx < DB_DESC_NELEM (ta->ta_var___pthread_keys); ++idx)
    {
      psaddr_t seq, destr;
      err = DB_GET_FIELD_LOCAL (seq, ta, keys, pthread_key_struct, seq, 0);
      if (err != TD_OK)
	return err;
      if (((uintptr_t) seq) & 1)
	{
	  err = DB_GET_FIELD_LOCAL (destr, ta, keys, pthread_key_struct,
				    destr, 0);
	  if (err != TD_OK)
	    return err;
	  /* Return with an error if the callback returns a nonzero value.  */
	  if (callback ((thread_key_t) idx, destr, cbdata_p) != 0)
	    return TD_DBERR;
	}
      /* Advance to the next element in the copied array.  */
      keys += keys_elemsize;
    }

  return TD_OK;
}
Exemplo n.º 4
0
td_err_e
td_ta_map_id2thr (const td_thragent_t *ta, pthread_t pt, td_thrhandle_t *th)
{
  struct pthread_handle_struct phc;
  struct _pthread_descr_struct pds;
  int pthread_threads_max;

  LOG ("td_ta_map_id2thr");

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  /* Make the following expression a bit smaller.  */
  pthread_threads_max = ta->pthread_threads_max;

  /* We can compute the entry in the handle array we want.  */
  if (ps_pdread (ta->ph, ta->handles + pt % pthread_threads_max, &phc,
		 sizeof (struct pthread_handle_struct)) != PS_OK)
    return TD_ERR;	/* XXX Other error value?  */

  /* Test whether this entry is in use.  */
  if (phc.h_descr == NULL)
    {
      if (pt % pthread_threads_max == 0)
	{
	  /* The initial thread always exists but the thread library
	     might not yet be initialized.  */
	  th->th_ta_p = (td_thragent_t *) ta;
	  th->th_unique = NULL;

	  return TD_OK;
	}

      return TD_BADTH;
    }

  /* Next test: get the descriptor to see whether this is not an old
     thread handle.  */
  if (ps_pdread (ta->ph, phc.h_descr, &pds,
		 sizeof (struct _pthread_descr_struct)) != PS_OK)
    return TD_ERR;	/* XXX Other error value?  */

  if (pds.p_tid != pt)
    return TD_BADTH;

  if (pds.p_terminated != 0)
    return TD_NOTHR;

  /* Create the `td_thrhandle_t' object.  */
  th->th_ta_p = (td_thragent_t *) ta;
  th->th_unique = phc.h_descr;

  return TD_OK;
}
Exemplo n.º 5
0
td_err_e
td_ta_clear_event (const td_thragent_t *ta_arg, td_thr_events_t *event)
{
  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
  td_err_e err;
  psaddr_t eventmask = 0;
  void *copy = NULL;

  LOG ("td_ta_clear_event");

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  /* Fetch the old event mask from the inferior and modify it in place.  */
  err = DB_GET_SYMBOL (eventmask, ta, __nptl_threads_events);
  if (err == TD_OK)
    err = DB_GET_STRUCT (copy, ta, eventmask, td_thr_events_t);
  if (err == TD_OK)
    {
      uint32_t idx;
      for (idx = 0; idx < TD_EVENTSIZE; ++idx)
	{
	  psaddr_t word;
	  uint32_t mask;
	  err = DB_GET_FIELD_LOCAL (word, ta, copy,
				    td_thr_events_t, event_bits, idx);
	  if (err != TD_OK)
	    break;
	  mask = (uintptr_t) word;
	  mask &= ~event->event_bits[idx];
	  word = (psaddr_t) (uintptr_t) mask;
	  err = DB_PUT_FIELD_LOCAL (ta, copy,
				    td_thr_events_t, event_bits, idx, word);
	  if (err != TD_OK)
	    break;
	}
      if (err == TD_NOAPLIC)
	{
	  err = TD_OK;
	  while (idx < TD_EVENTSIZE)
	    if (event->event_bits[idx++] != 0)
	      {
		err = TD_NOEVENT;
		break;
	      }
	}
      if (err == TD_OK)
	/* Now write it back to the inferior.  */
	err = DB_PUT_STRUCT (ta, eventmask, td_thr_events_t, copy);
    }

  return err;
}
td_err_e
td_ta_setconcurrency (const td_thragent_t *ta, int level)
{
  /* This is something LinuxThreads does not support.  */
  LOG ("td_ta_setconcurrency");

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  return TD_NOCAPAB;
}
td_err_e
td_ta_reset_stats (const td_thragent_t *ta)
{
  /* XXX We have to figure out what has to be done.  */
  LOG (__FUNCTION__);

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  return TD_OK;
}
td_err_e
td_ta_enable_stats (const td_thragent_t *ta, int enable)
{
  /* XXX We have to figure out what has to be done.  */
  LOG ("td_ta_enable_stats");

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  return TD_OK;
}
Exemplo n.º 9
0
td_err_e
td_ta_get_ph (const td_thragent_t *ta, struct ps_prochandle **ph)
{
  LOG ("td_ta_get_ph");

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  *ph = ta->ph;

  return TD_OK;
}
td_err_e
td_ta_map_id2thr (const td_thragent_t *ta, pthread_t pt, td_thrhandle_t *th)
{
  LOG ("td_ta_map_id2thr");

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  /* Create the `td_thrhandle_t' object.  */
  th->th_ta_p = (td_thragent_t *) ta;
  th->th_unique = (psaddr_t) pt;

  return TD_OK;
}
Exemplo n.º 11
0
td_err_e
td_ta_delete (td_thragent_t *ta)
{
  LOG ("td_ta_delete");

  /* Safety check.  Note that the test will also fail for TA == NULL.  */
  if (!ta_ok (ta))
    return TD_BADTA;

  /* Remove the handle from the list.  */
  list_del (&ta->list);

  /* The handle was allocated in `td_ta_new'.  */
  free (ta);

  return TD_OK;
}
Exemplo n.º 12
0
td_err_e
td_ta_get_nthreads (const td_thragent_t *ta, int *np)
{
  psaddr_t addr;

  LOG ("td_ta_get_nthreads");

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  /* Access the variable `__pthread_handles_num'.  */
  if (td_lookup (ta->ph, PTHREAD_HANDLES_NUM, &addr) != PS_OK)
     return TD_ERR;	/* XXX Other error value?  */

  if (ps_pdread (ta->ph, addr, np, sizeof (int)) != PS_OK)
     return TD_ERR;	/* XXX Other error value?  */

  return TD_OK;
}
Exemplo n.º 13
0
td_err_e
td_ta_get_nthreads (const td_thragent_t *ta_arg, int *np)
{
  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
  td_err_e err;
  psaddr_t n;

  LOG ("td_ta_get_nthreads");

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  /* Access the variable in the inferior that tells us.  */
  err = DB_GET_VALUE (n, ta, __nptl_nthreads, 0);
  if (err == TD_OK)
    *np = (uintptr_t) n;

  return err;
}
Exemplo n.º 14
0
td_err_e
td_ta_event_addr (const td_thragent_t *ta_arg,
		  td_event_e event, td_notify_t *addr)
{
  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
  td_err_e err;
  psaddr_t taddr = NULL;

  LOG ("td_ta_event_addr");

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  switch (event)
    {
    case TD_CREATE:
      err = DB_GET_SYMBOL (taddr, ta, __nptl_create_event);
      break;

    case TD_DEATH:
      err = DB_GET_SYMBOL (taddr, ta, __nptl_death_event);
      break;

    default:
      /* Event cannot be handled.  */
      return TD_NOEVENT;
    }

  if (err == TD_OK)
    {
      /* Success, we got the address.  */
      addr->type = NOTIFY_BPT;
      addr->u.bptaddr = taddr;
    }

  return err;
}
Exemplo n.º 15
0
td_err_e
td_ta_thr_iter (const td_thragent_t *ta_arg, td_thr_iter_f *callback,
		void *cbdata_p, td_thr_state_e state, int ti_pri,
		sigset_t *ti_sigmask_p, unsigned int ti_user_flags)
{
  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
  td_err_e err;
  psaddr_t list = 0;

  LOG ("td_ta_thr_iter");

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  /* The thread library keeps two lists for the running threads.  One
     list contains the thread which are using user-provided stacks
     (this includes the main thread) and the other includes the
     threads for which the thread library allocated the stacks.  We
     have to iterate over both lists separately.  We start with the
     list of threads with user-defined stacks.  */

  pid_t pid = ps_getpid (ta->ph);
  err = DB_GET_SYMBOL (list, ta, __stack_user);
  if (err == TD_OK)
    err = iterate_thread_list (ta, callback, cbdata_p, state, ti_pri,
			       list, true, pid);

  /* 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, false, pid);

  return err;
}
Exemplo n.º 16
0
td_err_e
td_ta_thr_iter (const td_thragent_t *ta, td_thr_iter_f *callback,
		void *cbdata_p, td_thr_state_e state, int ti_pri,
		sigset_t *ti_sigmask_p, unsigned int ti_user_flags)
{
  int pthread_threads_max;
  struct pthread_handle_struct *phc;
  td_err_e result = TD_OK;
  int cnt;
#ifdef ALL_THREADS_STOPPED
  int num;
#else
# define num 1
#endif

  LOG ("td_ta_thr_iter");

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  pthread_threads_max = ta->pthread_threads_max;
  phc = (struct pthread_handle_struct *) alloca (sizeof (phc[0])
						 * pthread_threads_max);

  /* First read only the main thread and manager thread information.  */
  if (ps_pdread (ta->ph, ta->handles, phc,
		 sizeof (struct pthread_handle_struct) * 2) != PS_OK)
    return TD_ERR;	/* XXX Other error value?  */

  /* Now handle these descriptors.  */
  result = handle_descr (ta, callback, cbdata_p, state, ti_pri, 0,
			 phc[0].h_descr);
  if (result != TD_OK)
    return result;
  result = handle_descr (ta, callback, cbdata_p, state, ti_pri, 1,
			 phc[1].h_descr);
  if (result != TD_OK)
    return result;

  /* Read all the descriptors.  */
  if (ps_pdread (ta->ph, ta->handles + 2, &phc[2],
		 (sizeof (struct pthread_handle_struct)
		  * (pthread_threads_max - 2))) != PS_OK)
    return TD_ERR;	/* XXX Other error value?  */

#ifdef ALL_THREADS_STOPPED
  /* Read the number of currently active threads.  */
  if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int)) != PS_OK)
    return TD_ERR;	/* XXX Other error value?  */
#endif

  /* Now get all descriptors, one after the other.  */
  for (cnt = 2; cnt < pthread_threads_max && num > 0; ++cnt)
    if (phc[cnt].h_descr != NULL)
      {
#ifdef ALL_THREADS_STOPPED
	/* First count this active thread.  */
	--num;
#endif

	result = handle_descr (ta, callback, cbdata_p, state, ti_pri, cnt,
			       phc[cnt].h_descr);
	if (result != TD_OK)
	  break;
      }

  return result;
}