This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

pthread_kill weirdness


My multi-threaded application is getting a `STATUS_ACCESS_VIOLATION' when
one thread issues a pthread_kill (tid, SIGHUP) call.  gdb bt for the
relevant thread shows:

(gdb) bt
#0  0x77f682db in ?? ()
#1  0x77f04f37 in ?? ()
#2  0x61048c66 in sig_send (p=0x0, sig=1, ebp=148566200, exception=false)
               at /src/winsup/cygwin/sigproc.cc:750
#3  0x6104685d in kill_worker (pid=479, sig=1)
               at /src/winsup/cygwin/signal.cc:158
#4  0x61046a06 in _kill (pid=479, sig=1)
               at /src/winsup/cygwin/signal.cc:195
#5  0x610590e1 in __pthread_kill (thread=0x1408b168, sig=1)
               at /src/winsup/cygwin/thread.cc:1735
#6  0x61038ca2 in pthread_kill (thread=0x1408b168, sig=1)
               at /src/winsup/cygwin/pthread.cc:208
#7  0x526074 in connect_client (csockp=0x0) at console.c:1153
#8  0xa28593a4 in ?? ()
#9  0xa28593a4 in ?? ()
#10 0xa010158 in ?? ()

I am having a hard time creating a testcase to duplicate the problem, tho.
However, I do see some weird results.  The testcase creates a thread
(child 1) that signals thread child 2 after 5 seconds.  Threads child 2,
child 3 and child 4 just wait 30 seconds.  Normally, I would expect results
similar to below:

$ ./testcase
child 2 sleeping     at Tue May  8 13:00:59 2001
child 3 sleeping     at Tue May  8 13:00:59 2001
child 4 sleeping     at Tue May  8 13:00:59 2001
child 1 signalling 2 at Tue May  8 13:01:04 2001
child 2 waking up    at Tue May  8 13:01:04 2001
child 3 waking up    at Tue May  8 13:01:29 2001
child 4 waking up    at Tue May  8 13:01:29 2001 

However, under Cygwin, I am seeing:

$ ./testcase
child 2 sleeping     at Tue May  8 12:58:31 2001
child 3 sleeping     at Tue May  8 12:58:31 2001
child 4 sleeping     at Tue May  8 12:58:31 2001
child 1 signalling 2 at Tue May  8 12:58:36 2001
child 2 waking up    at Tue May  8 12:58:36 2001
child 3 waking up    at Tue May  8 12:58:36 2001
child 4 waking up    at Tue May  8 12:58:36 2001

That is, all threads are dispatched by the pthread_kill.

I see that __pthread_kill in thread.cc sets `thread2signal' to the
target thread.  However, one of the first things kill_worker in signal.cc
does is set thread2signal back to NULL.  Also, sig_send in sigproc.cc
has a conditional `#if WHEN_MULTI_THREAD_SIGNALS_WORK', which isn't
defined.

The testcase is below.

Thanks, Greg

 
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>

void catcher(int);
void *child1();
void *child2();

pthread_attr_t  attr;
pthread_t       tid1,tid2,tid3,tid4;

int main ()
{ char *status;

   if (signal (SIGHUP, catcher) == SIG_ERR )
   { fprintf (stderr, "signal error: %s\n", strerror (errno));
     exit (1);
   }
   if (pthread_attr_init (&attr))
   { fprintf (stderr, "pthread_attr_init error: %s\n", strerror (errno));
     exit (1);
   }
   if (pthread_create (&tid1, &attr, child1, NULL))
   { fprintf (stderr, "pthread_create error: %s\n", strerror (errno));
     exit (1);
   }
   if (pthread_create (&tid2, &attr, child2, (void *)2))
   { fprintf (stderr, "pthread_create error: %s\n", strerror (errno));
     exit (1);
   }
   if (pthread_create (&tid3, &attr, child2, (void *)3))
   { fprintf (stderr, "pthread_create error: %s\n", strerror (errno));
     exit (1);
   }
   if (pthread_create (&tid4, &attr, child2, (void *)4))
   { fprintf (stderr, "pthread_create error: %s\n", strerror (errno));
     exit (1);
   }
   if (pthread_join (tid1, (void **)&status))
   { fprintf (stderr, "pthread_join error: %s\n", strerror (errno));
     exit (1);
   }
   if (pthread_join (tid2, (void **)&status))
   { fprintf (stderr, "pthread_join error: %s\n", strerror (errno));
     exit (1);
   }
   if (pthread_join (tid3, (void **)&status))
   { fprintf (stderr, "pthread_join error: %s\n", strerror (errno));
     exit (1);
   }
   if (pthread_join (tid4, (void **)&status))
   { fprintf (stderr, "pthread_join error: %s\n", strerror (errno));
     exit (1);
   }
}

void catcher (int signo)
{
   signal(signo, SIG_DFL);
}

void *child1 ()
{ time_t ltime;

   sleep (5);
   time (&ltime);
   printf ("child 1 signalling 2 at %s", ctime(&ltime));

   if (pthread_kill (tid2, SIGHUP))
   { fprintf (stderr, "pthread_kill error: %s\n", strerror (errno));
     exit (1);
   }
}

void *child2 (int n)
{ time_t ltime;

   time (&ltime);
   printf ("child %d sleeping     at %s", n, ctime(&ltime));

   sleep (30);

   time (&ltime);
   printf ("child %d waking up    at %s", n, ctime(&ltime));
}

--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]