[Adding the bug address back to the CC so that this gets archived.]
On 6/15/2013 9:54 AM, Angelo Graziosi wrote:
Christopher Faylor wrote
On 06/14/2013 11:03 AM, Christopher Faylor wrote:
You pointed to an archived mail messages which implies that was fixed
more than a year ago. What makes you think it is still a problem?
The message I pointed to
<http://cygwin.com/ml/cygwin/2012-05/msg00472.html> says this:
Testcase signal/kill: Signals may or may not reach the correct thread
with 1.7.12-1 and newer.
Confirmed. I think the reason is that we only have a single event to
signal that a POSIX signal arrived instead of a per-thread event, but
I'm not sure. This is cgf's domain so I leave it at that for now.
I interpreted this to mean "the existence of the bug is confirmed,
here's why the bug occurs, and I'll let cgf deal with it". I didn't
see any followup message where cgf (is that you?) dealt with it. My
apologies if I misinterpreted the email.
Oops. I didn't read Corinna's message as thoroughly as I should have.
Sorry.
That particular issue was supposed to have been fixed in Cygwin 1.7.17,
released in October 2012.
Out of curiosity, I tried the test cases I found in that thread, more
precisely here:
http://cygwin.com/ml/cygwin/2012-05/msg00434.html
and the results are:
$ gcc otto_test1.c -o otto_test1
$ ./otto_test1
Testing deferred pthread_cancel()
Thread 0 starting (0x200102c0)
Thread 1 starting (0x20010360)
Thread 2 starting (0x20010400)
Cancelling thread 2 (0x20010400)
Thread 2 exiting (0x20010400)
Cancelling thread 1 (0x20010360)
Thread 1 exiting (0x20010360)
Cancelling thread 0 (0x200102c0)
Thread 0 exiting (0x200102c0)
Thread 0 is gone (0x200102c0)
Thread 1 is gone (0x20010360)
Thread 2 is gone (0x20010400)
$ gcc otto_test2.c -o otto_test2
$ ./otto_test2
Testing asynchronous pthread_cancel()
Thread 0 starting (0x200102c0)
Changing canceltype from 0 to 1
Thread 1 starting (0x20010360)
Changing canceltype from 0 to 1
Thread 2 starting (0x20010400)
Changing canceltype from 0 to 1
Cancelling thread 2 (0x20010400)
Thread 2 exiting (0x20010400)
Cancelling thread 1 (0x20010360)
Thread 1 exiting (0x20010360)
Cancelling thread 0 (0x200102c0)
Thread 0 exiting (0x200102c0)
Thread 0 is gone (0x200102c0)
Thread 1 is gone (0x20010360)
Thread 2 is gone (0x20010400)
$ gcc otto_test3.c -o otto_test3
$ ./otto_test3
Testing pthread_kill()
Thread 0 starting (0x200102c0)
Thread 1 starting (0x20010360)
Thread 2 starting (0x20010400)
Sending SIGUSR1 to thread 2 (0x20010400)
Thread 2 executes signal handler (0x20010400)
Thread 2 encountered an error: Interrupted system call (0x20010400)
Sending SIGUSR1 to thread 1 (0x20010360)
Thread 1 executes signal handler (0x20010360)
Thread 1 encountered an error: Interrupted system call (0x20010360)
Sending SIGUSR1 to thread 0 (0x200102c0)
Thread 0 executes signal handler (0x200102c0)
Thread 0 encountered an error: Interrupted system call (0x200102c0)
Are the errors in the last test case to be expected under the 20130612
snapshot (CYGWIN_NT-5.1, 1.7.21s 20130612 21:06:59, i686 Cygwin)?
I can replicate this on my system, consistently. There's clearly a
problem, but it's not the same as in the original Cygwin bug report. In
the present case, the signal is received by the right thread, but
something goes wrong afterwards.
I'm attaching the test case for ease of reference.
Ken
/* http://cygwin.com/ml/cygwin/2012-05/msg00434.html */
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
pthread_t tids[3];
sem_t semaphore;
static void cleanup_handler(void *arg) {
int *intptr = (int*)arg;
pthread_t self = pthread_self();
fprintf(stderr, "Thread %i exiting (%p)\n", *intptr, self);
}
static void* simplethread(void *arg) {
int *intptr = (int*)arg;
pthread_t self = pthread_self();
fprintf(stderr, "Thread %i starting (%p)\n", *intptr, self);
pthread_cleanup_push(&cleanup_handler, intptr);
while (1) {
if (sem_wait(&semaphore) != 0) {
fprintf(stderr, "Thread %i encountered an error: %s (%p)\n",
*intptr, strerror(errno), self);
} else {
fprintf(stderr, "Thread %i woke up just fine\n", *intptr);
}
}
pthread_cleanup_pop(1);
return NULL;
}
static void sigusr1_handler(int signal __attribute((unused))) {
pthread_t self = pthread_self();
int tnum = 0;
while (tnum < 3) {
if (tids[tnum] == self) {
break;
}
tnum++;
}
fprintf(stderr, "Thread %i executes signal handler (%p)\n", tnum, self);
}
static void install_handler(void) {
struct sigaction act;
act.sa_handler = &sigusr1_handler;
sigemptyset(&(act.sa_mask));
act.sa_flags = 0;
if (sigaction(SIGUSR1, &act, NULL) != 0) {
fprintf(stderr, "Can't set signal handler: %s\n", strerror(errno));
exit(1);
}
sigset_t sset;
sigemptyset(&sset);
sigaddset(&sset, SIGUSR1);
if (sigprocmask(SIG_UNBLOCK, &sset, NULL) != 0) {
fprintf(stderr, "Can't unblock SIGUSR1: %s\n", strerror(errno));
}
}
int main() {
fprintf(stderr, "Testing pthread_kill()\n\n");
int i;
int result;
sem_init(&semaphore, 0, 0);
install_handler();
for (i=0; i<3; i++) {
int *intptr = (int*)malloc(sizeof(int));
*intptr = i;
result = pthread_create(tids+i, NULL, &simplethread, intptr);
if (result != 0) {
fprintf(stderr, "Can't create thread: %s\n", strerror(result));
return 1;
}
}
sleep(1);
install_handler();
fprintf(stderr, "\n");
int mainint = 42;
pthread_cleanup_push(&cleanup_handler, &mainint);
for (i=2; i>=0; i--) {
fprintf(stderr, "Sending SIGUSR1 to thread %i (%p)\n", i, tids[i]);
result = pthread_kill(tids[i], SIGUSR1);
if (result != 0) {
fprintf(stderr, "Error during pthread_kill: %s\n", strerror(result));
}
sleep(1);
}
pthread_cleanup_pop(0);
return 0;
}
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple