httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dean Gaudet <dgau...@arctic.org>
Subject [PATCH] Ouch! solved
Date Thu, 02 Oct 1997 07:37:46 GMT
unblock_alarms() would call destroy_pool() if exit_after_unblock was
non-zero.  destroy_pool() would eventually call unblock_alarms() again
and since exit_after_unblock was non-zero it would nest again ... and
this would result in free_blocks being called twice on the same block.
The fix to this is pretty easy, just set exit_after_unblock to 0
before recursing.

I no longer think this is related to the SEGV people are seeing.

While investigating this I discovered that Marc's CoreDumpDirectory
thing didn't handle the abort() function well.  So I made it handle
SIGABRT (or SIGABORT depending on what you have).  Then I noticed that
it can get into an infinite loop if another SIG{SEGV,BUS,ABRT,ABORT}
is received while dealing with the first... so I worked around that
too.

Oh and I didn't see CoreDumpDirectory mentioned in CHANGES.

Dean

Index: CHANGES
===================================================================
RCS file: /export/home/cvs/apachen/src/CHANGES,v
retrieving revision 1.454
diff -u -r1.454 CHANGES
--- CHANGES	1997/10/02 05:10:30	1.454
+++ CHANGES	1997/10/02 07:33:44
@@ -1,5 +1,9 @@
 Changes with Apache 1.3b1
 
+  *) CoreDumpDirectory directive directs where the core file is
+     written when a SIGSEGV, SIGBUS, SIGABORT or SIGABRT are
+     received.  [Marc Slemko, Dean Gaudet]
+
   *) When booting, apache will now detach itself from stdin, stdout,
      and stderr.  stderr will not be detached until after the config
      files have been read so you will be able to see initial error
Index: main/alloc.c
===================================================================
RCS file: /export/home/cvs/apachen/src/main/alloc.c,v
retrieving revision 1.48
diff -u -r1.48 alloc.c
--- alloc.c	1997/09/14 11:36:33	1.48
+++ alloc.c	1997/10/02 07:33:47
@@ -127,6 +127,7 @@
     while (free_blk) {
 	if (free_blk == blok) {
 	    fprintf(stderr, "Ouch!  Freeing free block\n");
+	    abort();
 	    exit(1);
 	}
 	free_blk = free_blk->h.next;
Index: main/http_main.c
===================================================================
RCS file: /export/home/cvs/apachen/src/main/http_main.c,v
retrieving revision 1.227
diff -u -r1.227 http_main.c
--- http_main.c	1997/10/02 05:10:33	1.227
+++ http_main.c	1997/10/02 07:33:54
@@ -765,6 +765,7 @@
     --alarms_blocked;
     if (alarms_blocked == 0) {
 	if (exit_after_unblock) {
+	    exit_after_unblock = 0;
 	    child_exit_modules(pconf, server_conf);
 	    destroy_pool(pconf);
 	    exit(0);
@@ -1907,26 +1908,46 @@
 }
 
 
-void bus_error(int sig)
+/* handle all varieties of core dumping signals */
+void sig_coredump(int sig)
 {
     char emsg[256];
+    const char *s;
 
-    ap_snprintf(emsg, sizeof(emsg),
-		"httpd: caught SIGBUS, attempting to dump core in %s",
-		coredump_dir);
-    aplog_error(APLOG_MARK, APLOG_INFO, server_conf, emsg);
-    chdir(coredump_dir);
-    abort();
-    exit(1);
-}
+    /* 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
 
-void seg_fault(int sig)
-{
-    char emsg[256];
+    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 SIGSEGV, attempting to dump core in %s",
-		coredump_dir);
+		"httpd: caught %s, attempting to dump core in %s",
+		s, coredump_dir);
     aplog_error(APLOG_MARK, APLOG_INFO, server_conf, emsg);
     chdir(coredump_dir);
     abort();
@@ -1993,12 +2014,21 @@
     sa.sa_flags = 0;
 
     if (!one_process) {
-	sa.sa_handler = seg_fault;
+	sa.sa_handler = sig_coredump;
 	if (sigaction(SIGSEGV, &sa, NULL) < 0)
 	    aplog_error(APLOG_MARK, APLOG_WARNING, server_conf, "sigaction(SIGSEGV)");
-	sa.sa_handler = bus_error;
+#ifdef SIGBUS
 	if (sigaction(SIGBUS, &sa, NULL) < 0)
 	    aplog_error(APLOG_MARK, APLOG_WARNING, server_conf, "sigaction(SIGBUS)");
+#endif
+#ifdef SIGABORT
+	if (sigaction(SIGABORT, &sa, NULL) < 0)
+	    aplog_error(APLOG_MARK, APLOG_WARNING, server_conf, "sigaction(SIGABORT)");
+#endif
+#ifdef SIGABRT
+	if (sigaction(SIGABRT, &sa, NULL) < 0)
+	    aplog_error(APLOG_MARK, APLOG_WARNING, server_conf, "sigaction(SIGABRT)");
+#endif
     }
     sa.sa_handler = sig_term;
     if (sigaction(SIGTERM, &sa, NULL) < 0)
@@ -2014,10 +2044,16 @@
 	aplog_error(APLOG_MARK, APLOG_WARNING, server_conf, "sigaction(SIGUSR1)");
 #else
     if (!one_process) {
-	signal(SIGSEGV, seg_fault);
+	signal(SIGSEGV, sig_coredump);
 #ifdef SIGBUS
-	signal(SIGBUS, bus_error);
+	signal(SIGBUS, sig_coredump);
 #endif /* SIGBUS */
+#ifdef SIGABORT
+	signal(SIGABORT, sig_coredump);
+#endif /* SIGABORT */
+#ifdef SIGABRT
+	signal(SIGABRT, sig_coredump);
+#endif /* SIGABRT */
     }
 
     signal(SIGTERM, sig_term);


Mime
View raw message