httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rob Hartill <hart...@hyperreal.com>
Subject apache 1.0.3 patch to diagnose CGI death (fwd)
Date Thu, 22 Feb 1996 17:15:55 GMT

I'll send an ack.

Forwarded message:
> From djm@va.pubnix.com  Wed Feb 21 23:04:58 1996
> Date: Thu, 22 Feb 1996 02:04:44 -0500
> Message-Id: <CAA09569.199602220704@catapult.va.pubnix.com>
> From: "David J. MacKenzie" <djm@va.pubnix.com>
> To: apache-bugs@apache.org
> cc: staff@va.pubnix.com
> Subject: apache 1.0.3 patch to diagnose CGI death
> 
> Ok, here goes.
> 
> From: David MacKenzie <djm@va.pubnix.com>
> Subject: record terminating signal of CGI programs in error_log
> Affects: alloc.c http_main.c http_protocol.c
> ChangeLog: alloc.c (free_proc_chain): Store child status in a global
> variable.  If an expected process doesn't exist, assume it died.
> http_main.c (reapchld): New SIGCHLD signal handler.
> (set_signals): Install it.
> http_protocol.c (strsig): New function.
> (send_error_response): Use it for SERVER_ERROR.
> Comments: I installed a similar patch in NCSA 1.5 which we've found very
> helpful in tracking down CGI programs that die abnormally.  That patch
> has been in use for several months.  This patch to Apache hasn't been
> tested long, and because I had to add a SIGCHLD handler I'm not
> certain whether Apache handles EINTR properly everywhere it needs to now.
> I couldn't find an appropriate structure to put the child_status in,
> one where all of the functions that need to could get at it,
> so I reluctantly made it a global.  I don't know which header file
> would be best to declare it in, so I didn't.  I only tried this on BSDI.
> SysV or NeXT might have portability problems with it, but I don't know
> what the right #ifdefs would be.  Nevertheless, this is a feature that
> has saved us support call time in isolating problems so I don't want
> to lose it as we switch users over to Apache.
> 
*** 1.2	1996/02/22 04:18:14
--- alloc.c	1996/02/22 06:23:56
***************
*** 857,862 ****
--- 857,865 ----
    return pid;
  }
  
+ /* Checked in send_error_response().  */
+ int child_status = 0;
+ 
  static void free_proc_chain (struct process_chain *procs)
  {
    /* Dispose of the subprocesses we've spawned off in the course of
***************
*** 866,872 ****
  
    struct process_chain *p;
    int need_timeout = 0;
-   int status;
  
    if (procs == NULL) return;	/* No work.  Whew! */
  
--- 869,874 ----
***************
*** 880,886 ****
  #ifndef NEED_WAITPID
    /* Pick up all defunct processes */
    for (p = procs; p; p = p->next) {
!     if (waitpid (p->pid, (int *) 0, WNOHANG) > 0) {
        p->kill_how = kill_never;
      }
    }
--- 882,889 ----
  #ifndef NEED_WAITPID
    /* Pick up all defunct processes */
    for (p = procs; p; p = p->next) {
!     /* If it's already gone, the SIGCHLD handler must have reaped it.  */
!     if (waitpid (p->pid, &child_status, WNOHANG) > 0 || kill(p->pid, 0) <
0) {
        p->kill_how = kill_never;
      }
    }
***************
*** 911,916 ****
        kill (p->pid, SIGKILL);
  
      if (p->kill_how != kill_never)
!       waitpid (p->pid, &status, 0);
    }
  }
--- 914,919 ----
        kill (p->pid, SIGKILL);
  
      if (p->kill_how != kill_never)
!       waitpid (p->pid, &child_status, 0);
    }
  }
*** 1.4	1996/02/22 04:50:14
--- http_main.c	1996/02/22 06:39:39
***************
*** 663,668 ****
--- 663,676 ----
  #endif
  }
  
+ void reapchld(void)
+ {
+     extern int child_status;
+ 
+     while (waitpid(-1, &child_status, WNOHANG) > 0)
+       ;
+ }
+ 
  void set_signals(void) {
  	if(!one_process)
  	{
***************
*** 671,676 ****
--- 679,685 ----
  	}
      signal(SIGTERM,(void (*)())sig_term);
      signal(SIGHUP,(void (*)())restart);
+     signal(SIGCHLD,(void (*)())reapchld);
  }
  
  /*****************************************************************
*** 1.1	1996/02/17 08:35:16
--- http_protocol.c	1996/02/22 06:44:16
***************
*** 588,593 ****
--- 588,602 ----
      return retval;
  }
  
+ const char *
+ strsig(int n)
+ {
+   if (n >= 0 && n < NSIG)
+     return sys_siglist[n];
+   else
+     return "Unknown signal";
+ }
+ 
  void send_error_response (request_rec *r, int recursive_error)
  {
      conn_rec *c = r->connection;
***************
*** 595,600 ****
--- 604,610 ----
      int status = r->status;
      int idx = index_of_response (status);
      char *location = table_get (r->headers_out, "Location");
+     extern int child_status;
  
      if (!r->assbackwards) {
  	int i;
***************
*** 672,677 ****
--- 682,698 ----
  	    fprintf(fd,"and inform them of the time the error occurred,%c",LF);
  	    fprintf(fd,"and anything you might have done that may have%c",LF);
  	    fprintf(fd,"caused the error.<P>%c",LF);
+ 
+ 	    if (WIFSIGNALED(child_status)) {
+ 	      log_printf(r->server, 
+ 			 "CGI or SSI script run from %s received signal %s.",
+ 			 r->filename, strsig(WTERMSIG(child_status)));
+ 	      fflush (r->server->error_log); /* Help debugging.  */
+ 	      fprintf(fd,
+ 		      "CGI or SSI script run from %s received signal %s.<P>%c",
+ 		      r->filename,
+ 		      strsig(WTERMSIG(child_status)),LF);
+ 	    }
  	    break;
  	case NOT_IMPLEMENTED:
  	    fprintf(fd,"%s to %s not supported.<P>\n",



Mime
View raw message