handle_threadlist_exception: handle_threadlist_exception called with threadlist_ix -1

Pavel Tsekov ptsekov@gmx.net
Tue Oct 11 14:49:00 GMT 2005


On Thu, 6 Oct 2005, Pavel Tsekov wrote:

> On Thu, 6 Oct 2005, Christopher Faylor wrote:
>
> > >It might be a different problem but the message is the same.
> >
> > It *is* a different problem.
>
> Ok.
>
> > Some thread is sending a signal 31 (SIGUSR1).  Which thread is doing this?
>
> An application thread signaling another thread to stop its execution. I am
> on it - I'll report back if I manage to find something.

While tracking this problem I found what I suspect is a small bug in
the way sigsuspend() works when it is used to retrieve the list of pending
signals for a thread other than the main one. I think this is related to
the crash I am seeing in some way though this has to be determined yet.

As I read the code, when retrieving the list of pending signals
sigpending() inspects only the list of blocked signals for the main
thread - it doesn't look in the thread specific list of blocked signals
of the calling thread.

The code which I refer to is the following block from wait_sig():

        case __SIGPENDING:
          *pack.mask = 0;
          unsigned bit;
          sigq.reset ();
          while ((q = sigq.next ()))
            if (myself->getsigmask () & (bit = SIGTOMASK (q->si.si_signo)))
              *pack.mask |= bit;
          break;

On the other hand the code in sigpacket::process() does the right thing
when it delivers a signal i.e. it looks the list of blocked signals in
both the main thread and the target thread.

Attached is a simple test case which demonstrates the problem.

On Linux:

pending_set = 00000000
pending_set = 00000000
pending_set = 00000000
pending_set = 00000000
pending_set = 00000000
pending_set = 00000800
exiting thread_loop()

On Cygwin:

pending_set = 00000000
pending_set = 00000000
pending_set = 00000000
pending_set = 00000000
pending_set = 00000000
pending_set = 00000000
pending_set = 00000000
pending_set = 00000000
pending_set = 00000000
pending_set = 00000000
pending_set = 00000000
pending_set = 00000000
pending_set = 00000000

[ keeps looping forever ]
-------------- next part --------------
#include <signal.h>
#include <stdio.h>
#include <pthread.h>

static void *thread_loop (void *unused)
{
  sigset_t block_set, pending_set;

  sigemptyset (&block_set);
  sigaddset (&block_set, SIGUSR2);
  if (pthread_sigmask (SIG_BLOCK, &block_set, NULL) != 0)
    {
      printf ("failed to set the list of blocked signals\n");
    }

  while (1)
    {
      sigpending (&pending_set);

      printf ("pending_set = %08X\n", pending_set);

      if (sigismember (&pending_set, SIGUSR2) != 0)
	break;

      sleep (1);
    }

  printf ("exiting thread_loop()\n");

  return NULL;
}

int main (int argc, char **argv)
{
  int rv;
  pthread_t thr_id;

  rv = pthread_create (&thr_id, NULL, thread_loop, NULL);
  if (rv != 0)
    {
      printf ("failed to create thread.\n");
      exit (1);
    }

  /* give the second thread a chance to run */
  sleep (5);

  while (1)
    {
      if (pthread_kill (thr_id, SIGUSR2) != 0)
        break;
    }

  exit (0);
}
-------------- next part --------------
--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


More information about the Cygwin mailing list