dgaudet     97/10/04 19:06:39

  Modified:    src/main alloc.c http_main.c
  Log:
  Fix "Ouch!  Freeing free block" error.  Beef up sigsegv/bus handler to also
  deal with sigabort/sigabrt and not get into an infinite loop.
  
  Reviewed by:  Rob Hartill
  
  Revision  Changes    Path
  1.49      +1 -0      apachen/src/main/alloc.c
  
  Index: alloc.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/main/alloc.c,v
  retrieving revision 1.48
  retrieving revision 1.49
  diff -u -r1.48 -r1.49
  --- alloc.c   1997/09/14 11:36:33     1.48
  +++ alloc.c   1997/10/05 02:06:36     1.49
  @@ -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;
  
  
  
  1.230     +54 -18    apachen/src/main/http_main.c
  
  Index: http_main.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/main/http_main.c,v
  retrieving revision 1.229
  retrieving revision 1.230
  diff -u -r1.229 -r1.230
  --- http_main.c       1997/10/05 02:02:38     1.229
  +++ http_main.c       1997/10/05 02:06:37     1.230
  @@ -769,6 +769,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);
  @@ -1911,26 +1912,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();
  @@ -1997,12 +2018,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)
  @@ -2018,10 +2048,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);
  
  
  

Reply via email to