httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dean Gaudet <dgau...@arctic.org>
Subject [PATCH] report child signals in parent
Date Fri, 08 May 1998 09:46:41 GMT
This is way nice.  Now we'll know if children exit for other bogus
reasons.

I'm a little annoyed that there's no way to, iterate over all signals
and ask if a signal by default will cause a coredump.  ... because it's
annoying hardcoding some of the coredump causing signals, but not all
of them (they vary by platform).

Tested on linux (libc5, glibc2), solaris 2.6.

I'm guessing sys_siglist (or _sys_siglist) exists almost everywhere.
But other folks can add it to their sections of conf.h.

Dean

Index: include/conf.h
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/include/conf.h,v
retrieving revision 1.207
diff -u -r1.207 conf.h
--- conf.h	1998/05/03 17:31:07	1.207
+++ conf.h	1998/05/08 09:38:56
@@ -158,6 +158,7 @@
 #define HAVE_CRYPT_H 1
 int gethostname(char *name, int namelen);
 #define HAVE_SYSLOG 1
+#define SYS_SIGLIST _sys_siglist
 
 #elif defined(IRIX)
 #undef HAVE_GMTOFF
@@ -406,6 +407,8 @@
 /* flock is faster ... but hasn't been tested on 1.x systems */
 #define USE_FLOCK_SERIALIZED_ACCEPT
 
+#define SYS_SIGLIST	_sys_siglist
+
 #else
 #define USE_FCNTL_SERIALIZED_ACCEPT
 #endif
@@ -1062,6 +1065,13 @@
  */
 #ifndef NET_SIZE_T
 #define NET_SIZE_T int
+#endif
+
+/* Linux defines __WCOREDUMP, but doesn't define WCOREDUMP unless __USE_BSD
+ * is in use... we'd prefer to just use WCOREDUMP everywhere.
+ */
+#if defined(__WCOREDUMP) && !defined(WCOREDUMP)
+#define WCOREDUMP __WCOREDUMP
 #endif
 
 #ifdef SUNOS_LIB_PROTOTYPES
Index: main/http_main.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/main/http_main.c,v
retrieving revision 1.333
diff -u -r1.333 http_main.c
--- http_main.c	1998/05/08 03:17:01	1.333
+++ http_main.c	1998/05/08 09:38:57
@@ -2206,47 +2206,16 @@
 /* handle all varieties of core dumping signals */
 static void sig_coredump(int sig)
 {
-    char emsg[256];
-    const char *s;
-
-    /* Must protect against a nested signal, otherwise we could end up in
-     * an infinite loop.
-     */
-    signal(SIGSEGV, SIG_DFL);
-#ifdef SIGBUS
-    signal(SIGBUS, SIG_DFL);
-#endif
-#ifdef SIGABORT
-    signal(SIGABORT, SIG_DFL);
-#endif
-#ifdef SIGABRT
-    signal(SIGABRT, SIG_DFL);
-#endif
-
-    s = "SIGSEGV";
-#ifdef SIGBUS
-    if (sig == SIGBUS) {
-	s = "SIGBUS";
-    }
-#endif
-#ifdef SIGABORT
-    if (sig == SIGABORT) {
-	s = "SIGABORT";
-    }
-#endif
-#ifdef SIGABRT
-    if (sig == SIGABRT) {
-	s = "SIGABRT";
-    }
-#endif
-
-    ap_snprintf(emsg, sizeof(emsg),
-		"httpd: caught %s, attempting to dump core in %s",
-		s, ap_coredump_dir);
-    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, server_conf, emsg);
     chdir(ap_coredump_dir);
-    abort();
-    exit(1);
+    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.
+     */
 }
 
 /*****************************************************************
@@ -3791,6 +3760,57 @@
 }
 
 
+static void process_child_status(int pid, int status)
+{
+    /* Child died... if it died due to a fatal error,
+	* we should simply bail out.
+	*/
+    if ((WIFEXITED(status)) &&
+	WEXITSTATUS(status) == APEXIT_CHILDFATAL) {
+	ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
+			"Child %d returned a Fatal error... \n"
+			"Apache is exiting!",
+			pid);
+	exit(APEXIT_CHILDFATAL);
+    }
+    if (WIFSIGNALED(status)) {
+	switch (WTERMSIG(status)) {
+	case SIGTERM:
+	case SIGHUP:
+	case SIGUSR1:
+	case SIGKILL:
+	    break;
+	default:
+#ifdef SYS_SIGLIST
+#ifdef WCOREDUMP
+	    if (WCOREDUMP(status)) {
+		ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE,
+		    server_conf,
+		    "httpd: child pid %d exit signal %s (%d), "
+		    "possible coredump in %s",
+		    pid, SYS_SIGLIST[WTERMSIG(status)], WTERMSIG(status),
+		    ap_coredump_dir);
+	    }
+	    else {
+#endif
+		ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE,
+		    server_conf,
+		    "httpd: child pid %d exit signal %s (%d)",
+		    pid, SYS_SIGLIST[WTERMSIG(status)], WTERMSIG(status));
+#ifdef WCOREDUMP
+	    }
+#endif
+#else
+	    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE,
+		server_conf,
+		"httpd: child pid %d exit signal %d",
+		pid, WTERMSIG(status));
+#endif
+	}
+    }
+}
+
+
 /*****************************************************************
  * Executive routines.
  */
@@ -3891,17 +3911,7 @@
 	     * extra child
 	     */
 	    if (pid >= 0) {
-	        /* Child died... if it died due to a fatal error,
-		 * we should simply bail out.
-		 */
-		if ((WIFEXITED(status)) &&
-		   WEXITSTATUS(status) == APEXIT_CHILDFATAL) {
-		    ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
-				 "Child %d returned a Fatal error... \n"
-				 "Apache is exiting!",
-				 pid);
-		    exit(APEXIT_CHILDFATAL);
-		}
+		process_child_status(pid, status);
 		/* non-fatal death... note that it's gone in the scoreboard. */
 		ap_sync_scoreboard_image();
 		child_slot = find_child_by_pid(pid);


Mime
View raw message