Charles Wilson wrote: > Dave Korn wrote: >> Umm, yes. Poking around directly inside a sigjmp_buf. Wonder if the >> layout >> is actually what that code expects it to be or not? That's where I'd start >> looking next, anyway, if I was wondering why maybe things were randomly >> jumping to unexpected places ... > > Oh gosh. I hope that code isn't actually "live" in the cygwin > build...yeah, messing around with jmp_bufs behind cygwin's -- or ANY > OS's -- back is just bound to screw up. Sigh.
Ok, it's pth's fault. As it happens, none of the tests in pth's test suite use fork(); that seems to be a serious oversight. Anyway, here are two dirt-simple apps. One using pthreads, the other using pth. 'Course, you need pth to build the latter. gcc -o pth-fork pth-fork.c -lpth gcc -o pthreads-fork pthreads-fork.c $ ./pthreads-fork FORKPARENT: mypid=7328 childpid=7724 FORKCHILD: mypid=7724 $ ./pth-fork FORKPARENT: mypid=7140 childpid=7840 It looks like this is a long-standing problem: http://www.cygwin.com/ml/cygwin/2001-05/threads.html#01131 Then, as now, suspicion falls on messing with jmp_buf and/or the stack in bad ways. (Note: using -DPTH_SYSCALL_SOFT=1 to force using pth_fork() as a wrapper around the system fork() doesn't help. Same bad behavior.) I wonder what's more difficult...fixing pth, or modifying libassuan and gnupg to use plain old pthreads instead of pth? Typically, there's a big performance impact between native threads (slow, but pre-emptive) and user-mode threads (fast, but non-pre-emptive). However, on windows, I believe you don't have nearly as much of a performance penalty using native threads (which cygwin's pthread implementation uses under the hood). So, modifying the code to use pthreads wouldn't be bad, from a performance standpoint...but the APIs are /just annoyingly different enough/ to be painful. Hmmm...or writing shim wrappers to translate pth calls to pthread? Ach, the purist in me just wants to get pth working... I've attached the two test progs, and the cygport for pth. (sans source. use 'cygport *.cygport get'). -- Chuck
pth-2.0.7-1.cygport.tar.bz2
Description: Binary data
#include <stdlib.h> #include <stdio.h> #include <pthread.h> #include <string.h> #include <sys/errno.h> void *test (void *arg); int main (int argc, char *argv[]) { int err; pthread_t thread; void *threadrv; if ((err = pthread_create (&thread, NULL, test, NULL)) != 0) { printf ("Error on pthread_create %d:%s\n", err, strerror (err)); exit (1); } if ((err = pthread_join (thread, &threadrv)) != 0) { printf ("Error on pthread_join %d:%s\n", err, strerror (err)); exit (1); } return 0; } void * test (void *arg) { int pid; pid = fork (); if (pid < 0) { printf ("FORKFAILED\n"); } else if (pid == 0) { printf ("FORKCHILD: mypid=%d\n", getpid ()); } else { printf ("FORKPARENT: mypid=%d childpid=%d\n", getpid (), pid); } }
#include <stdlib.h> #include <stdio.h> #include <pth.h> #include <string.h> #include <sys/errno.h> void *test (void *arg); int main (int argc, char *argv[]) { int err; pth_t thread; void *threadrv; if ((err = pth_init ()) != TRUE) { printf ("Error on pth_init: %d: %s\n", errno, strerror (errno)); exit (1); } if ((thread = pth_spawn (PTH_ATTR_DEFAULT, test, NULL)) == (pid_t) NULL) { printf ("Error on pth_spawn: %d: %s\n", errno, strerror (errno)); exit (1); } if ((err = pth_join (thread, &threadrv)) != TRUE) { printf ("Error on pthread_join %d: %s\n", errno, strerror (errno)); exit (1); } return 0; } void * test (void *arg) { int pid; pid = fork (); if (pid < 0) { printf ("FORKFAILED\n"); } else if (pid == 0) { printf ("FORKCHILD: mypid=%d\n", getpid ()); } else { printf ("FORKPARENT: mypid=%d childpid=%d\n", getpid (), pid); } }
-- 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