The libapr1 test cases starting failing with my 64-bit package and 1.7.19-6. They worked fine with 1.7.19-5. After a little investigation, I discovered that only the tests that involve fork() were failing and only if the "testdso" test case ran first. That test case checks loading and unloading DLLs.
I extracted the attached STC. It creates a simple DLL and uses dlopen() and dlclose() on it. Then it attempts a fork(). With the latest 32-bit snapshot (2013-05-24) this causes a segfault. The same thing happens with the 64-bit release. With 1.7.18, the test case hangs for quite a while, but eventually finishes, except that the fork() never really happens and I get a weird error code when I run it in gdb. If I skip the dlclose() call, the STC runs fine. It's weird, but the libapr1 test suite does not fail on 32-bit with the 2013-05-24 snapshot (or with 1.7.18). I don't know why the STC fails and the test suite does not. There's a pretty good chance that I'm doing something dumb in the STC since I don't do this type of programming. If so, please let me know and accept my apologies. To run the test, just run "make". To run it without the dlclose(), run "make test-nofail". Regards, David -- David Rothenberger ---- daver...@acm.org alimony, n: Having an ex you can bank on.
/*********************************************************************** * This is a STC to show that fork causes a SEGV after a DLL has been loaded * and unloaded. * * It loads and unloads a test DLL then does a simple fork. This causes a SEGV * with 1.7.19-6 (although not with 1.7.19-5). If the DLL is not unloaded then * no SEGV occurs. * * This test was extracted from the APR test suite. * * To compile and run, just run make. To run the test without unloading the * DLL, run "make test-nofail". ***********************************************************************/ #include <string.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <dlfcn.h> #include <errno.h> #include <sys/wait.h> int do_unload = 1; void load_dso () { char dll[PATH_MAX]; getcwd(dll, PATH_MAX); strcat(dll, "/mod_test.dll"); void *os_handle = dlopen(dll, RTLD_NOW | RTLD_GLOBAL); if (os_handle == NULL) { perror("Could not open DLL"); exit(1); } if (do_unload) { if (dlclose(os_handle) != 0) { perror("Could not close DLL"); exit(1); } } } void do_fork () { pid_t pid; printf("Calling fork()\n"); fflush(stdout); if ((pid = fork()) < 0) { perror("fork failed"); exit(1); } else if (pid == 0) { printf("In child\n"); fflush(stdout); exit(0); } else { printf("Awaiting child\n"); fflush(stdout); // await child int exit_int; pid_t pstatus; do { pstatus = waitpid(pid, &exit_int, WUNTRACED); } while (pstatus < 0 && errno == EINTR); printf("Child finished\n"); fflush(stdout); } } int main (int argc, const char * const * argv, const char * const *env) { if (argc > 1) { do_unload = 0; } load_dso(); do_fork(); return 0; }
int count_reps(int reps); int count_reps(int reps) { int i = 0; for (i = 0;i < reps; i++); return i; }
CC=gcc CFLAGS=-Wall STC=stc_dso_breaks_fork LIBS=-ldl .PHONY: test test-nofail test: $(STC) mod_test.dll ./$(STC) test-nofail: $(STC) mod_test.dll ./$(STC) no-fail $(STC): $(STC).c $(CC) $(CFLAGS) -o $@ $^ $(LIBS) mod_test.dll: mod_test.o $(CC) -shared -o $@ $^ mod_test.o: mod_test.c $(CC) $(CFLAGS) -c $^ .PHONY: clean clean: rm -f $(STC) mod_test.o mod_test.dll $(STC).exe.stackdump
-- 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