/*********************************************************************** * 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 #include #include #include #include #include #include #include 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; }