]> granicus.if.org Git - apache/commitdiff
consolidate code related to sig_coredump
authorJeff Trawick <trawick@apache.org>
Wed, 9 Apr 2003 16:58:30 +0000 (16:58 +0000)
committerJeff Trawick <trawick@apache.org>
Wed, 9 Apr 2003 16:58:30 +0000 (16:58 +0000)
a note on perchild:
  perchild exception handling was busted before this and is still busted
  the problem I noticed was that a client that exposes a segfault never
  gets its connection dropped and the parent never notices that the
  child process that segfaulted hasexited

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@99312 13f79535-47bb-0310-9956-ffa450edef68

12 files changed:
include/mpm_common.h
server/mpm/experimental/leader/leader.c
server/mpm/experimental/leader/mpm.h
server/mpm/experimental/perchild/mpm.h
server/mpm/experimental/perchild/perchild.c
server/mpm/experimental/threadpool/mpm.h
server/mpm/experimental/threadpool/threadpool.c
server/mpm/prefork/mpm.h
server/mpm/prefork/prefork.c
server/mpm/worker/mpm.h
server/mpm/worker/worker.c
server/mpm_common.c

index 59616800897f73a2eae9e89f043b7a693e9eff0c..ce58cedfb3b704a7a64816112fb7dfad5789d0cb 100644 (file)
@@ -292,6 +292,11 @@ extern const char *ap_mpm_set_max_mem_free(cmd_parms *cmd, void *dummy,
                                            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
+
 #ifdef __cplusplus
 }
 #endif
index 6f942da5c6edee11132bc4efd19a28be8689609e..197e2cd005781d928e3d901cd1beff57ed8ad736 100644 (file)
@@ -459,33 +459,6 @@ static void clean_child_exit(int code)
     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);
-    if (ap_my_pid == 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);
@@ -564,42 +537,16 @@ static void set_signals(void)
 {
 #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, 
@@ -641,19 +588,6 @@ static void set_signals(void)
                      "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 */
@@ -1104,6 +1038,7 @@ static void child_main(int child_num_arg)
     apr_thread_t *start_thread_id;
 
     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 9f763b71118b5044b408bfaca4e4e2c09069a442..8bf78e5577cdf539ab201ace2e09cd3fcabd0d20 100644 (file)
@@ -76,6 +76,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 618298707f6bf20c28cef137704b47835004d316..d6c8ce41e3cf1a4ad68291a3a203404a3a59f73e 100644 (file)
@@ -77,6 +77,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 0978480226ceccb527d4dfa69032979bd4e1904c..04a0dba1973e10fe4da206274b0ee36729842ba5 100644 (file)
@@ -324,21 +324,6 @@ static void clean_child_exit(int code)
     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);
@@ -418,42 +403,16 @@ static void set_signals(void)
 {
 #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,
@@ -495,19 +454,6 @@ static void set_signals(void)
                      "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 */
@@ -1025,6 +971,7 @@ static void child_main(int child_num_arg)
     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 f28f666d7f9e93eb724b74eb397ebd796a139df3..ba1de13fa0c31c0cafd6c62db26391f44353e785 100644 (file)
@@ -76,6 +76,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 3f70345ac19e4dfa8f54b9792253a8cecdfa78d4..14388c103860dd30cef459585b914dbb47b58d82 100644 (file)
@@ -535,33 +535,6 @@ static void clean_child_exit(int code)
     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);
-    if (ap_my_pid == 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);
@@ -635,42 +608,16 @@ static void set_signals(void)
 {
 #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, 
@@ -712,19 +659,6 @@ static void set_signals(void)
                      "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 */
@@ -1322,6 +1256,7 @@ static void child_main(int child_num_arg)
     apr_thread_t *start_thread_id;
 
     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 7ebce7c54d1ebfd2f79c0e601f448a7e4a1e562b..8006f7ed2e69b416902778cd4a2e9cb40baf1311 100644 (file)
@@ -79,6 +79,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 64aea2036745239c9dcccfbe0745955aab088aa6..cab24ddb1a4c5493ff461d28bfd1b4c28890e4ba 100644 (file)
@@ -353,27 +353,6 @@ int reap_children(int *exitcode, apr_exit_why_e *status)
 }
 #endif
 
-/* handle all varieties of core dumping signals */
-static void sig_coredump(int sig)
-{
-    chdir(ap_coredump_dir);
-    apr_signal(sig, SIG_DFL);
-    if (ap_my_pid == 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...
  */
@@ -417,37 +396,16 @@ static void set_signals(void)
 {
 #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)");
@@ -482,19 +440,6 @@ static void set_signals(void)
         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 */
@@ -555,6 +500,8 @@ static void child_main(int child_num_arg)
     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 bf84e1d6b89696558552cb7a1820f44dd9f6edd8..9e6429ee5d8f431457e1682609fdcc828434ba1d 100644 (file)
@@ -76,6 +76,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 50f350381ba8698490bd41e251c8d0b06ce4fe70..1f35249120c90a4c07de0b422e285af2717fdd45 100644 (file)
@@ -374,33 +374,6 @@ static void clean_child_exit(int code)
     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);
-    if (ap_my_pid == 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);
@@ -474,42 +447,16 @@ static void set_signals(void)
 {
 #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, 
@@ -551,19 +498,6 @@ static void set_signals(void)
                      "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 */
@@ -1194,6 +1128,7 @@ static void child_main(int child_num_arg)
     apr_thread_t *start_thread_id;
 
     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 0632ed63ba0b75dac6fc9622a35bf12c8ad370fc..e55a8ee2b6f49b81a62c06e642bce61d1171fca7 100644 (file)
@@ -97,6 +97,9 @@
 #ifdef HAVE_GRP_H
 #include <grp.h>
 #endif
+#if APR_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 
 #ifdef AP_MPM_WANT_RECLAIM_CHILD_PROCESSES
 void ap_reclaim_child_processes(int terminate)
@@ -910,3 +913,101 @@ const char *ap_mpm_set_max_mem_free(cmd_parms *cmd, void *dummy,
 }
 
 #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;
+
+/* 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 (my_pid == 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 */