Index: configure.in =================================================================== RCS file: /home/cvs/httpd-2.0/configure.in,v retrieving revision 1.232.2.12 diff -u -r1.232.2.12 configure.in --- configure.in 27 Dec 2003 12:00:42 -0000 1.232.2.12 +++ configure.in 19 Feb 2004 11:37:59 -0000 @@ -368,6 +368,12 @@ nonssl_listen_stmt_2="Listen [[::]]:@@Port@@" fi +AC_ARG_ENABLE(exception-hook,APACHE_HELP_STRING(--enable-exception-hook,Enable fatal exception hook), +[ + AC_DEFINE(AP_ENABLE_EXCEPTION_HOOK, 1, + [Allow modules to run hook after a fatal exception]) +])dnl + AC_ARG_ENABLE(maintainer-mode,APACHE_HELP_STRING(--enable-maintainer-mode,Turn on debugging and compile time warnings), [ APR_ADDTO(CPPFLAGS, -DAP_DEBUG) Index: include/ap_mpm.h =================================================================== RCS file: /home/cvs/httpd-2.0/include/ap_mpm.h,v retrieving revision 1.33.2.6 diff -u -r1.33.2.6 ap_mpm.h --- include/ap_mpm.h 9 Feb 2004 20:54:33 -0000 1.33.2.6 +++ include/ap_mpm.h 19 Feb 2004 11:38:03 -0000 @@ -163,4 +163,13 @@ #define AP_MONCONTROL(x) #endif +#if AP_ENABLE_EXCEPTION_HOOK +typedef struct ap_exception_info_t { + int sig; + pid_t pid; +} ap_exception_info_t; + +AP_DECLARE_HOOK(int,fatal_exception,(ap_exception_info_t *ei)) +#endif /*AP_ENABLE_EXCEPTION_HOOK*/ + #endif Index: include/mpm_common.h =================================================================== RCS file: /home/cvs/httpd-2.0/include/mpm_common.h,v retrieving revision 1.39.2.7 diff -u -r1.39.2.7 mpm_common.h --- include/mpm_common.h 9 Feb 2004 20:54:34 -0000 1.39.2.7 +++ include/mpm_common.h 19 Feb 2004 11:38:04 -0000 @@ -249,6 +249,16 @@ const char *arg); #endif +#ifdef AP_MPM_WANT_FATAL_SIGNAL_HANDLER +extern apr_status_t ap_fatal_signal_setup(server_rec *s, apr_pool_t *pconf); +extern apr_status_t ap_fatal_signal_child_setup(server_rec *s); +#endif + +#if AP_ENABLE_EXCEPTION_HOOK +extern const char *ap_mpm_set_exception_hook(cmd_parms *cmd, void *dummy, + const char *arg); +#endif + #ifdef __cplusplus } #endif Index: server/core.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/core.c,v retrieving revision 1.225.2.14 diff -u -r1.225.2.14 core.c --- server/core.c 9 Feb 2004 20:59:45 -0000 1.225.2.14 +++ server/core.c 19 Feb 2004 11:38:08 -0000 @@ -3242,6 +3242,10 @@ AP_INIT_TAKE1("MaxMemFree", ap_mpm_set_max_mem_free, NULL, RSRC_CONF, "Maximum number of 1k blocks a particular childs allocator may hold."), #endif +#if AP_ENABLE_EXCEPTION_HOOK +AP_INIT_TAKE1("EnableExceptionHook", ap_mpm_set_exception_hook, NULL, RSRC_CONF, + "Controls whether exception hook may be called after a crash"), +#endif { NULL } }; Index: server/mpm_common.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm_common.c,v retrieving revision 1.102.2.7 diff -u -r1.102.2.7 mpm_common.c --- server/mpm_common.c 9 Feb 2004 20:59:46 -0000 1.102.2.7 +++ server/mpm_common.c 19 Feb 2004 11:38:08 -0000 @@ -54,6 +54,9 @@ #ifdef HAVE_GRP_H #include #endif +#if APR_HAVE_UNISTD_H +#include +#endif #ifdef AP_MPM_WANT_RECLAIM_CHILD_PROCESSES void ap_reclaim_child_processes(int terminate) @@ -867,3 +870,161 @@ } #endif /* AP_MPM_WANT_SET_MAX_MEM_FREE */ + +#ifdef AP_MPM_WANT_FATAL_SIGNAL_HANDLER + +static pid_t parent_pid, my_pid; +apr_pool_t *pconf; + +#if AP_ENABLE_EXCEPTION_HOOK + +static int exception_hook_enabled; + +const char *ap_mpm_set_exception_hook(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + if (cmd->server->is_virtual) { + return "EnableExceptionHook directive not allowed in "; + } + + if (strcasecmp(arg, "on") == 0) { + exception_hook_enabled = 1; + } + else if (strcasecmp(arg, "off") == 0) { + exception_hook_enabled = 0; + } + else { + return "parameter must be 'on' or 'off'"; + } + + return NULL; +} + +APR_HOOK_STRUCT( + APR_HOOK_LINK(fatal_exception) +) + +AP_IMPLEMENT_HOOK_RUN_ALL(int, fatal_exception, + (ap_exception_info_t *ei), (ei), OK, DECLINED) + +static void run_fatal_exception_hook(int sig) +{ + ap_exception_info_t ei = {0}; + + if (exception_hook_enabled && + geteuid() != 0 && + my_pid != parent_pid) { + ei.sig = sig; + ei.pid = my_pid; + ap_run_fatal_exception(&ei); + } +} +#endif /* AP_ENABLE_EXCEPTION_HOOK */ + +/* handle all varieties of core dumping signals */ +static void sig_coredump(int sig) +{ + apr_filepath_set(ap_coredump_dir, pconf); + apr_signal(sig, SIG_DFL); +#if AP_ENABLE_EXCEPTION_HOOK + run_fatal_exception_hook(sig); +#endif + /* linuxthreads issue calling getpid() here: + * This comparison won't match if the crashing thread is + * some module's thread that runs in the parent process. + * The fallout, which is limited to linuxthreads: + * The special log message won't be written when such a + * thread in the parent causes the parent to crash. + */ + if (getpid() == parent_pid) { + ap_log_error(APLOG_MARK, APLOG_NOTICE, + 0, ap_server_conf, + "seg fault or similar nasty error detected " + "in the parent process"); + /* XXX we can probably add some rudimentary cleanup code here, + * like getting rid of the pid file. If any additional bad stuff + * happens, we are protected from recursive errors taking down the + * system since this function is no longer the signal handler GLA + */ + } + kill(getpid(), sig); + /* At this point we've got sig blocked, because we're still inside + * the signal handler. When we leave the signal handler it will + * be unblocked, and we'll take the signal... and coredump or whatever + * is appropriate for this particular Unix. In addition the parent + * will see the real signal we received -- whereas if we called + * abort() here, the parent would only see SIGABRT. + */ +} + +apr_status_t ap_fatal_signal_child_setup(server_rec *s) +{ + my_pid = getpid(); + return APR_SUCCESS; +} + +apr_status_t ap_fatal_signal_setup(server_rec *s, apr_pool_t *in_pconf) +{ +#ifndef NO_USE_SIGACTION + struct sigaction sa; + + sigemptyset(&sa.sa_mask); + +#if defined(SA_ONESHOT) + sa.sa_flags = SA_ONESHOT; +#elif defined(SA_RESETHAND) + sa.sa_flags = SA_RESETHAND; +#else + sa.sa_flags = 0; +#endif + + sa.sa_handler = sig_coredump; + if (sigaction(SIGSEGV, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGSEGV)"); +#ifdef SIGBUS + if (sigaction(SIGBUS, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGBUS)"); +#endif +#ifdef SIGABORT + if (sigaction(SIGABORT, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGABORT)"); +#endif +#ifdef SIGABRT + if (sigaction(SIGABRT, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGABRT)"); +#endif +#ifdef SIGILL + if (sigaction(SIGILL, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGILL)"); +#endif + +#else /* NO_USE_SIGACTION */ + + apr_signal(SIGSEGV, sig_coredump); +#ifdef SIGBUS + apr_signal(SIGBUS, sig_coredump); +#endif /* SIGBUS */ +#ifdef SIGABORT + apr_signal(SIGABORT, sig_coredump); +#endif /* SIGABORT */ +#ifdef SIGABRT + apr_signal(SIGABRT, sig_coredump); +#endif /* SIGABRT */ +#ifdef SIGILL + apr_signal(SIGILL, sig_coredump); +#endif /* SIGILL */ + +#endif /* NO_USE_SIGACTION */ + + pconf = in_pconf; + parent_pid = my_pid = getpid(); + + return APR_SUCCESS; +} + +#endif /* AP_MPM_WANT_FATAL_SIGNAL_HANDLER */ Index: server/mpm/experimental/leader/leader.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/experimental/leader/leader.c,v retrieving revision 1.26.2.8 diff -u -r1.26.2.8 leader.c --- server/mpm/experimental/leader/leader.c 10 Feb 2004 14:53:28 -0000 1.26.2.8 +++ server/mpm/experimental/leader/leader.c 19 Feb 2004 11:38:10 -0000 @@ -422,40 +422,6 @@ exit(code); } -/* handle all varieties of core dumping signals */ -static void sig_coredump(int sig) -{ - apr_filepath_set(ap_coredump_dir, pconf); - apr_signal(sig, SIG_DFL); - /* linuxthreads issue calling getpid() here: - * This comparison won't match if the crashing thread is - * some module's thread that runs in the parent process. - * The fallout, which is limited to linuxthreads: - * The special log message won't be written when such a - * thread in the parent causes the parent to crash. - */ - if (getpid() == parent_pid) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, - 0, ap_server_conf, - "seg fault or similar nasty error detected " - "in the parent process"); - - /* XXX we can probably add some rudimentary cleanup code here, - * like getting rid of the pid file. If any additional bad stuff - * happens, we are protected from recursive errors taking down the - * system since this function is no longer the signal handler GLA - */ - } - kill(ap_my_pid, sig); - /* At this point we've got sig blocked, because we're still inside - * the signal handler. When we leave the signal handler it will - * be unblocked, and we'll take the signal... and coredump or whatever - * is appropriate for this particular Unix. In addition the parent - * will see the real signal we received -- whereas if we called - * abort() here, the parent would only see SIGABRT. - */ -} - static void just_die(int sig) { clean_child_exit(0); @@ -535,42 +501,16 @@ { #ifndef NO_USE_SIGACTION struct sigaction sa; +#endif + + if (!one_process) { + ap_fatal_signal_setup(ap_server_conf, pconf); + } +#ifndef NO_USE_SIGACTION sigemptyset(&sa.sa_mask); sa.sa_flags = 0; - if (!one_process) { - sa.sa_handler = sig_coredump; -#if defined(SA_ONESHOT) - sa.sa_flags = SA_ONESHOT; -#elif defined(SA_RESETHAND) - sa.sa_flags = SA_RESETHAND; -#endif - if (sigaction(SIGSEGV, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGSEGV)"); -#ifdef SIGBUS - if (sigaction(SIGBUS, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGBUS)"); -#endif -#ifdef SIGABORT - if (sigaction(SIGABORT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGABORT)"); -#endif -#ifdef SIGABRT - if (sigaction(SIGABRT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGABRT)"); -#endif -#ifdef SIGILL - if (sigaction(SIGILL, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGILL)"); -#endif - sa.sa_flags = 0; - } sa.sa_handler = sig_term; if (sigaction(SIGTERM, &sa, NULL) < 0) ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, @@ -612,19 +552,6 @@ "sigaction(" AP_SIG_GRACEFUL_STRING ")"); #else if (!one_process) { - apr_signal(SIGSEGV, sig_coredump); -#ifdef SIGBUS - apr_signal(SIGBUS, sig_coredump); -#endif /* SIGBUS */ -#ifdef SIGABORT - apr_signal(SIGABORT, sig_coredump); -#endif /* SIGABORT */ -#ifdef SIGABRT - apr_signal(SIGABRT, sig_coredump); -#endif /* SIGABRT */ -#ifdef SIGILL - apr_signal(SIGILL, sig_coredump); -#endif /* SIGILL */ #ifdef SIGXCPU apr_signal(SIGXCPU, SIG_DFL); #endif /* SIGXCPU */ @@ -1080,6 +1007,7 @@ */ ap_my_pid = getpid(); + ap_fatal_signal_child_setup(ap_server_conf); apr_pool_create(&pchild, pconf); /*stuff to do before we switch id's, so we have permissions.*/ Index: server/mpm/experimental/leader/mpm.h =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/experimental/leader/mpm.h,v retrieving revision 1.6.2.4 diff -u -r1.6.2.4 mpm.h --- server/mpm/experimental/leader/mpm.h 9 Feb 2004 20:59:47 -0000 1.6.2.4 +++ server/mpm/experimental/leader/mpm.h 19 Feb 2004 11:38:10 -0000 @@ -34,6 +34,7 @@ #define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH #define AP_MPM_WANT_SIGNAL_SERVER #define AP_MPM_WANT_SET_MAX_MEM_FREE +#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER #define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK #define AP_MPM_USES_POD 1 Index: server/mpm/experimental/perchild/mpm.h =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/experimental/perchild/mpm.h,v retrieving revision 1.17.2.4 diff -u -r1.17.2.4 mpm.h --- server/mpm/experimental/perchild/mpm.h 9 Feb 2004 20:59:47 -0000 1.17.2.4 +++ server/mpm/experimental/perchild/mpm.h 19 Feb 2004 11:38:10 -0000 @@ -34,6 +34,7 @@ #define AP_MPM_WANT_SET_COREDUMPDIR #define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH #define AP_MPM_WANT_SIGNAL_SERVER +#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER #define AP_MPM_USES_POD #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) Index: server/mpm/experimental/perchild/perchild.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/experimental/perchild/perchild.c,v retrieving revision 1.136.2.5 diff -u -r1.136.2.5 perchild.c --- server/mpm/experimental/perchild/perchild.c 9 Feb 2004 20:59:47 -0000 1.136.2.5 +++ server/mpm/experimental/perchild/perchild.c 19 Feb 2004 11:38:12 -0000 @@ -281,21 +281,6 @@ exit(code); } -/* handle all varieties of core dumping signals */ -static void sig_coredump(int sig) -{ - chdir(ap_coredump_dir); - apr_signal(sig, SIG_DFL); - kill(getpid(), sig); - /* At this point we've got sig blocked, because we're still inside - * the signal handler. When we leave the signal handler it will - * be unblocked, and we'll take the signal... and coredump or whatever - * is appropriate for this particular Unix. In addition the parent - * will see the real signal we received -- whereas if we called - * abort() here, the parent would only see SIGABRT. - */ -} - static void just_die(int sig) { clean_child_exit(0); @@ -375,42 +360,16 @@ { #ifndef NO_USE_SIGACTION struct sigaction sa; +#endif + if (!one_process) { + ap_fatal_signal_setup(ap_server_conf, pconf); + } + +#ifndef NO_USE_SIGACTION sigemptyset(&sa.sa_mask); sa.sa_flags = 0; - if (!one_process) { - sa.sa_handler = sig_coredump; -#if defined(SA_ONESHOT) - sa.sa_flags = SA_ONESHOT; -#elif defined(SA_RESETHAND) - sa.sa_flags = SA_RESETHAND; -#endif - if (sigaction(SIGSEGV, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGSEGV)"); -#ifdef SIGBUS - if (sigaction(SIGBUS, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGBUS)"); -#endif -#ifdef SIGABORT - if (sigaction(SIGABORT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGABORT)"); -#endif -#ifdef SIGABRT - if (sigaction(SIGABRT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGABRT)"); -#endif -#ifdef SIGILL - if (sigaction(SIGILL, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGILL)"); -#endif - sa.sa_flags = 0; - } sa.sa_handler = sig_term; if (sigaction(SIGTERM, &sa, NULL) < 0) ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, @@ -452,19 +411,6 @@ "sigaction(" AP_SIG_GRACEFUL_STRING ")"); #else if (!one_process) { - apr_signal(SIGSEGV, sig_coredump); -#ifdef SIGBUS - apr_signal(SIGBUS, sig_coredump); -#endif /* SIGBUS */ -#ifdef SIGABORT - apr_signal(SIGABORT, sig_coredump); -#endif /* SIGABORT */ -#ifdef SIGABRT - apr_signal(SIGABRT, sig_coredump); -#endif /* SIGABRT */ -#ifdef SIGILL - apr_signal(SIGILL, sig_coredump); -#endif /* SIGILL */ #ifdef SIGXCPU apr_signal(SIGXCPU, SIG_DFL); #endif /* SIGXCPU */ @@ -982,6 +928,7 @@ ap_listen_rec *lr; my_pid = getpid(); + ap_fatal_signal_child_setup(ap_server_conf); child_num = child_num_arg; apr_pool_create(&pchild, pconf); Index: server/mpm/experimental/threadpool/mpm.h =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/experimental/threadpool/mpm.h,v retrieving revision 1.3.2.4 diff -u -r1.3.2.4 mpm.h --- server/mpm/experimental/threadpool/mpm.h 9 Feb 2004 20:59:47 -0000 1.3.2.4 +++ server/mpm/experimental/threadpool/mpm.h 19 Feb 2004 11:38:12 -0000 @@ -34,6 +34,7 @@ #define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH #define AP_MPM_WANT_SIGNAL_SERVER #define AP_MPM_WANT_SET_MAX_MEM_FREE +#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER #define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) Index: server/mpm/experimental/threadpool/threadpool.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/experimental/threadpool/threadpool.c,v retrieving revision 1.14.2.9 diff -u -r1.14.2.9 threadpool.c --- server/mpm/experimental/threadpool/threadpool.c 10 Feb 2004 14:53:28 -0000 1.14.2.9 +++ server/mpm/experimental/threadpool/threadpool.c 19 Feb 2004 11:38:13 -0000 @@ -498,40 +498,6 @@ exit(code); } -/* handle all varieties of core dumping signals */ -static void sig_coredump(int sig) -{ - apr_filepath_set(ap_coredump_dir, pconf); - apr_signal(sig, SIG_DFL); - /* linuxthreads issue calling getpid() here: - * This comparison won't match if the crashing thread is - * some module's thread that runs in the parent process. - * The fallout, which is limited to linuxthreads: - * The special log message won't be written when such a - * thread in the parent causes the parent to crash. - */ - if (getpid() == parent_pid) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, - 0, ap_server_conf, - "seg fault or similar nasty error detected " - "in the parent process"); - - /* XXX we can probably add some rudimentary cleanup code here, - * like getting rid of the pid file. If any additional bad stuff - * happens, we are protected from recursive errors taking down the - * system since this function is no longer the signal handler GLA - */ - } - kill(ap_my_pid, sig); - /* At this point we've got sig blocked, because we're still inside - * the signal handler. When we leave the signal handler it will - * be unblocked, and we'll take the signal... and coredump or whatever - * is appropriate for this particular Unix. In addition the parent - * will see the real signal we received -- whereas if we called - * abort() here, the parent would only see SIGABRT. - */ -} - static void just_die(int sig) { clean_child_exit(0); @@ -606,42 +572,16 @@ { #ifndef NO_USE_SIGACTION struct sigaction sa; +#endif + + if (!one_process) { + ap_fatal_signal_setup(ap_server_conf, pconf); + } +#ifndef NO_USE_SIGACTION sigemptyset(&sa.sa_mask); sa.sa_flags = 0; - if (!one_process) { - sa.sa_handler = sig_coredump; -#if defined(SA_ONESHOT) - sa.sa_flags = SA_ONESHOT; -#elif defined(SA_RESETHAND) - sa.sa_flags = SA_RESETHAND; -#endif - if (sigaction(SIGSEGV, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGSEGV)"); -#ifdef SIGBUS - if (sigaction(SIGBUS, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGBUS)"); -#endif -#ifdef SIGABORT - if (sigaction(SIGABORT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGABORT)"); -#endif -#ifdef SIGABRT - if (sigaction(SIGABRT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGABRT)"); -#endif -#ifdef SIGILL - if (sigaction(SIGILL, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGILL)"); -#endif - sa.sa_flags = 0; - } sa.sa_handler = sig_term; if (sigaction(SIGTERM, &sa, NULL) < 0) ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, @@ -683,19 +623,6 @@ "sigaction(" AP_SIG_GRACEFUL_STRING ")"); #else if (!one_process) { - apr_signal(SIGSEGV, sig_coredump); -#ifdef SIGBUS - apr_signal(SIGBUS, sig_coredump); -#endif /* SIGBUS */ -#ifdef SIGABORT - apr_signal(SIGABORT, sig_coredump); -#endif /* SIGABORT */ -#ifdef SIGABRT - apr_signal(SIGABRT, sig_coredump); -#endif /* SIGABRT */ -#ifdef SIGILL - apr_signal(SIGILL, sig_coredump); -#endif /* SIGILL */ #ifdef SIGXCPU apr_signal(SIGXCPU, SIG_DFL); #endif /* SIGXCPU */ @@ -1294,6 +1221,7 @@ * child initializes */ ap_my_pid = getpid(); + ap_fatal_signal_child_setup(ap_server_conf); apr_pool_create(&pchild, pconf); /*stuff to do before we switch id's, so we have permissions.*/ Index: server/mpm/prefork/mpm.h =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/prefork/mpm.h,v retrieving revision 1.21.2.4 diff -u -r1.21.2.4 mpm.h --- server/mpm/prefork/mpm.h 9 Feb 2004 20:59:48 -0000 1.21.2.4 +++ server/mpm/prefork/mpm.h 19 Feb 2004 11:38:13 -0000 @@ -36,6 +36,7 @@ #define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH #define AP_MPM_WANT_SIGNAL_SERVER #define AP_MPM_WANT_SET_MAX_MEM_FREE +#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER #define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK #define AP_MPM_USES_POD 1 Index: server/mpm/prefork/prefork.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/prefork/prefork.c,v retrieving revision 1.272.2.9 diff -u -r1.272.2.9 prefork.c --- server/mpm/prefork/prefork.c 10 Feb 2004 14:53:28 -0000 1.272.2.9 +++ server/mpm/prefork/prefork.c 19 Feb 2004 11:38:15 -0000 @@ -315,34 +315,6 @@ } #endif -/* handle all varieties of core dumping signals */ -static void sig_coredump(int sig) -{ - chdir(ap_coredump_dir); - apr_signal(sig, SIG_DFL); - /* linuxthreads issue calling getpid() here: - * This comparison won't match if the crashing thread is - * some module's thread that runs in the parent process. - * The fallout, which is limited to linuxthreads: - * The special log message won't be written when such a - * thread in the parent causes the parent to crash. - */ - if (getpid() == parent_pid) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, - 0, ap_server_conf, - "seg fault or similar nasty error detected " - "in the parent process"); - } - kill(getpid(), sig); - /* At this point we've got sig blocked, because we're still inside - * the signal handler. When we leave the signal handler it will - * be unblocked, and we'll take the signal... and coredump or whatever - * is appropriate for this particular Unix. In addition the parent - * will see the real signal we received -- whereas if we called - * abort() here, the parent would only see SIGABRT. - */ -} - /***************************************************************** * Connection structures and accounting... */ @@ -386,37 +358,16 @@ { #ifndef NO_USE_SIGACTION struct sigaction sa; +#endif + if (!one_process) { + ap_fatal_signal_setup(ap_server_conf, pconf); + } + +#ifndef NO_USE_SIGACTION sigemptyset(&sa.sa_mask); sa.sa_flags = 0; - if (!one_process) { - sa.sa_handler = sig_coredump; -#if defined(SA_ONESHOT) - sa.sa_flags = SA_ONESHOT; -#elif defined(SA_RESETHAND) - sa.sa_flags = SA_RESETHAND; -#endif - if (sigaction(SIGSEGV, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGSEGV)"); -#ifdef SIGBUS - if (sigaction(SIGBUS, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGBUS)"); -#endif -#ifdef SIGABORT - if (sigaction(SIGABORT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGABORT)"); -#endif -#ifdef SIGABRT - if (sigaction(SIGABRT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGABRT)"); -#endif -#ifdef SIGILL - if (sigaction(SIGILL, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGILL)"); -#endif - sa.sa_flags = 0; - } sa.sa_handler = sig_term; if (sigaction(SIGTERM, &sa, NULL) < 0) ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)"); @@ -451,19 +402,6 @@ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(" AP_SIG_GRACEFUL_STRING ")"); #else if (!one_process) { - apr_signal(SIGSEGV, sig_coredump); -#ifdef SIGBUS - apr_signal(SIGBUS, sig_coredump); -#endif /* SIGBUS */ -#ifdef SIGABORT - apr_signal(SIGABORT, sig_coredump); -#endif /* SIGABORT */ -#ifdef SIGABRT - apr_signal(SIGABRT, sig_coredump); -#endif /* SIGABRT */ -#ifdef SIGILL - apr_signal(SIGILL, sig_coredump); -#endif /* SIGILL */ #ifdef SIGXCPU apr_signal(SIGXCPU, SIG_DFL); #endif /* SIGXCPU */ @@ -527,6 +465,8 @@ ap_my_pid = getpid(); csd = NULL; requests_this_child = 0; + + ap_fatal_signal_child_setup(ap_server_conf); /* Get a sub context for global allocations in this child, so that * we can have cleanups occur when the child exits. Index: server/mpm/worker/mpm.h =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/worker/mpm.h,v retrieving revision 1.14.2.4 diff -u -r1.14.2.4 mpm.h --- server/mpm/worker/mpm.h 9 Feb 2004 20:59:48 -0000 1.14.2.4 +++ server/mpm/worker/mpm.h 19 Feb 2004 11:38:15 -0000 @@ -34,6 +34,7 @@ #define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH #define AP_MPM_WANT_SIGNAL_SERVER #define AP_MPM_WANT_SET_MAX_MEM_FREE +#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER #define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) Index: server/mpm/worker/worker.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/worker/worker.c,v retrieving revision 1.133.2.10 diff -u -r1.133.2.10 worker.c --- server/mpm/worker/worker.c 10 Feb 2004 14:53:28 -0000 1.133.2.10 +++ server/mpm/worker/worker.c 19 Feb 2004 11:38:16 -0000 @@ -337,40 +337,6 @@ exit(code); } -/* handle all varieties of core dumping signals */ -static void sig_coredump(int sig) -{ - apr_filepath_set(ap_coredump_dir, pconf); - apr_signal(sig, SIG_DFL); - /* linuxthreads issue calling getpid() here: - * This comparison won't match if the crashing thread is - * some module's thread that runs in the parent process. - * The fallout, which is limited to linuxthreads: - * The special log message won't be written when such a - * thread in the parent causes the parent to crash. - */ - if (getpid() == parent_pid) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, - 0, ap_server_conf, - "seg fault or similar nasty error detected " - "in the parent process"); - - /* XXX we can probably add some rudimentary cleanup code here, - * like getting rid of the pid file. If any additional bad stuff - * happens, we are protected from recursive errors taking down the - * system since this function is no longer the signal handler GLA - */ - } - kill(ap_my_pid, sig); - /* At this point we've got sig blocked, because we're still inside - * the signal handler. When we leave the signal handler it will - * be unblocked, and we'll take the signal... and coredump or whatever - * is appropriate for this particular Unix. In addition the parent - * will see the real signal we received -- whereas if we called - * abort() here, the parent would only see SIGABRT. - */ -} - static void just_die(int sig) { clean_child_exit(0); @@ -445,42 +411,16 @@ { #ifndef NO_USE_SIGACTION struct sigaction sa; +#endif + + if (!one_process) { + ap_fatal_signal_setup(ap_server_conf, pconf); + } +#ifndef NO_USE_SIGACTION sigemptyset(&sa.sa_mask); sa.sa_flags = 0; - if (!one_process) { - sa.sa_handler = sig_coredump; -#if defined(SA_ONESHOT) - sa.sa_flags = SA_ONESHOT; -#elif defined(SA_RESETHAND) - sa.sa_flags = SA_RESETHAND; -#endif - if (sigaction(SIGSEGV, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGSEGV)"); -#ifdef SIGBUS - if (sigaction(SIGBUS, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGBUS)"); -#endif -#ifdef SIGABORT - if (sigaction(SIGABORT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGABORT)"); -#endif -#ifdef SIGABRT - if (sigaction(SIGABRT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGABRT)"); -#endif -#ifdef SIGILL - if (sigaction(SIGILL, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGILL)"); -#endif - sa.sa_flags = 0; - } sa.sa_handler = sig_term; if (sigaction(SIGTERM, &sa, NULL) < 0) ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, @@ -522,19 +462,6 @@ "sigaction(" AP_SIG_GRACEFUL_STRING ")"); #else if (!one_process) { - apr_signal(SIGSEGV, sig_coredump); -#ifdef SIGBUS - apr_signal(SIGBUS, sig_coredump); -#endif /* SIGBUS */ -#ifdef SIGABORT - apr_signal(SIGABORT, sig_coredump); -#endif /* SIGABORT */ -#ifdef SIGABRT - apr_signal(SIGABRT, sig_coredump); -#endif /* SIGABRT */ -#ifdef SIGILL - apr_signal(SIGILL, sig_coredump); -#endif /* SIGILL */ #ifdef SIGXCPU apr_signal(SIGXCPU, SIG_DFL); #endif /* SIGXCPU */ @@ -1165,6 +1092,7 @@ * child initializes */ ap_my_pid = getpid(); + ap_fatal_signal_child_setup(ap_server_conf); apr_pool_create(&pchild, pconf); /*stuff to do before we switch id's, so we have permissions.*/