dgaudet 98/05/08 20:25:44
Modified: src CHANGES PORTING src/include conf.h src/main http_main.c Log: The parent does the child signal reporting now. Adds SYS_SIGLIST. Revision Changes Path 1.837 +5 -0 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.836 retrieving revision 1.837 diff -u -r1.836 -r1.837 --- CHANGES 1998/05/09 02:28:28 1.836 +++ CHANGES 1998/05/09 03:25:40 1.837 @@ -1,5 +1,10 @@ Changes with Apache 1.3b7 + *) Apache will now log the reason its httpd children exit if they exit + due to an unexpected signal. (It requires a new porting define, + SYS_SIGLIST, which if defined should point to a list of text + descriptions of the signals available. See PORTING.) [Dean Gaudet] + *) chdir() doesn't make sense in a multithreaded environment like WIN32. Before, Win32 CGI's could have had sporadic failures if a chdir call from one thread was made between another chdir call and a spawn in 1.28 +7 -2 apache-1.3/src/PORTING Index: PORTING =================================================================== RCS file: /export/home/cvs/apache-1.3/src/PORTING,v retrieving revision 1.27 retrieving revision 1.28 diff -u -r1.27 -r1.28 --- PORTING 1998/04/21 21:00:43 1.27 +++ PORTING 1998/05/09 03:25:41 1.28 @@ -100,7 +100,7 @@ ./include/conf.h Configure: - ========== +========== Configure concerns itself with determining the OS-type for the build and setting up a few Makefile variables for the build. The most important are 'OS' and 'CFLAGS'. For example, when Configure @@ -130,7 +130,7 @@ supplied regex libraries are generally buggy, and should be avoided. conf.h: - ======= +======= The Apache code, specifically in conf.h, uses a variety of #defines to control how the code is compiled and what options are available for each supported OS. One of the hardest parts about the porting process is @@ -343,6 +343,11 @@ NEED_HASHBANG_EMUL: The execve()/etc. functions on this platform do not deal with #!, so it must be emulated by Apache. + + SYS_SIGLIST + Should be defined to point to a const char * const * array of + signal descriptions. This is frequently sys_siglist or + _sys_siglist, defined in <signals.h> ----------- Conclusion: 1.208 +10 -0 apache-1.3/src/include/conf.h Index: conf.h =================================================================== RCS file: /export/home/cvs/apache-1.3/src/include/conf.h,v retrieving revision 1.207 retrieving revision 1.208 diff -u -r1.207 -r1.208 --- conf.h 1998/05/03 17:31:07 1.207 +++ conf.h 1998/05/09 03:25:42 1.208 @@ -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 1.341 +61 -51 apache-1.3/src/main/http_main.c Index: http_main.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/main/http_main.c,v retrieving revision 1.340 retrieving revision 1.341 diff -u -r1.340 -r1.341 --- http_main.c 1998/05/09 01:21:47 1.340 +++ http_main.c 1998/05/09 03:25:43 1.341 @@ -2209,47 +2209,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. + */ } /***************************************************************** @@ -3792,6 +3761,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. */ @@ -3896,17 +3916,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);