You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by yu...@odyssee.net on 1996/09/21 15:46:52 UTC

WWW Form Bug Report: "standalone stops serving, after repeated reloads from browser" on UnixWare

Submitter: yulpgi@odyssee.net
Operating system: UnixWare, version: 2.01
Version of Apache Used: 1.1.1
Extra Modules used: see below Configuration
URL exhibiting problem: my site is only available when i logon to my isp

Symptoms:
--
I'm assuming that the way the program is compiled
and linked is enough to find out the configuration.
There is on the http_main.c shown here but all modules were compiled with the same switches.
cc -c -O2 -DSVR4 -DNEED_LINGER -DSTATUS http_main.c
cc -o httpd alloc.o http_main.o http_core.o http_config.o http_request
.o  http_log.o http_protocol.o rfc1413.o util.o util_script.o modules.o buff.o m
d5c.o util_md5.o explain.o http_bprintf.o mod_mime.o  mod_access.o  mod_auth.o
mod_negotiation.o  mod_include.o  mod_dir.o  mod_cgi.o  mod_userdir.o  mod_alias
.o  mod_env.o  mod_log_common.o  mod_asis.o  mod_imap.o  mod_actions.o  mod_stat
us.o  mod_info.o  mod_cookies.o  -lsocket -lnsl -lcrypt
#

I sent some e-mail to dan@dpcsys.com before I realised you
had a bug report form. This is the message I sent.

I just writing this to you to let you know that I've loaded 
the binaries that you so kindly furnished to apache.org. 
Unfortunenately there seems to be 2 real big problems.
Not your fault I've recompiled myself and these problems
are still evident.

My setup: Unixware 2.01 16mb memory
          Browser Netscape 2.01Gold, win95, 32bit

1. Server ceases to respond in Standalone Mode

   I ran across this problem because when testing a page, I would
   set the browser's mem and disk cache to zero. Then reload to see
   the results. 

   Try this on 
   your server, make sure no one is using the server.

   In Netscape (my version 2.01Gold) set the memory and disk
   cache to zero. Then start bringing up the same page by
   repeated click on RELOAD, not even waiting for the page to 
   completely load. It won't be long before the server will
   stop sending pages. I tried resetting the first occurance 
   of httpd (the one whose parent is pid 1) using HUP which
   forces the server to reload the configuration. This was confirmed
   in access-log or error-log cannot remember.
   That didn't help. Another side effect is that you cannot kill
   the server daemons either. Only recourse is to reboot the whole
   system.

   So I decided to try the other method of using the server,
   albeit creating more of a load on the system. The following
   is another problem that occurs.

  Core Dump for every invocation of httpd using inetd method.

   When the server is invoked by inetd, there will be a
   core dump for each invocation in /etc/saf/inetd directory.
   This happens when the server has finished sending a page
   and a timer to keep it alive has run out.

   I only noticed this after using the server for 3 months.
   I started running out of space in my root directory.

   So I started to look around in http_main.c and found out
   that the section of code causing the problem is in
   timeout() function which is called as a result of an alarm
   setup in the hard_timeout function which is called from 
   read_request.

   I don't know how to use a debugger, so I changed this statement
   in inetd.conf.
   http    stream  tcp     nowait  root /opt/lib/apache/httpd-debug httpd

   httpd-debug is simply a script redirecting stderror to a log file.
   #!/bin/sh
   /opt/lib/apache/httpd httpd 2>> /tmp/httpd-log

   
   timeout(sig) is called as a result of an alarm that is setup in
   hard_timeout. I placed printf statements
   in different parts of the code to see how far it would get.
   I've narrowed it down to one variable current_conn
   if the server is not being used in standalone. Based on which
   signal and which type read in this case, There is cleaning up
   that goes on. 


void timeout(sig)                       /* Also called on SIGPIPE */
int sig;
{
    char errstr[MAX_STRING_LEN];
    void *dirconf;

    fprintf(stderr, "In timeout routine\n");
    signal(SIGPIPE, SIG_IGN);           /* Block SIGPIPE */
    if (alarms_blocked) {
        alarm_pending = 1;
        return;
    }
    fprintf(stderr, "In timeout routine, before siglongjmp\n");
    if (!current_conn) {
        fprintf(stderr, "In timeout routine, in siglongjmp\n");
#ifdef NEXT
        longjmp(jmpbuffer,1);
#else
        siglongjmp(jmpbuffer,1);
#endif
    }
    fprintf(stderr, "In timeout routine, after siglongjmp\n");

    if (timeout_req != NULL) dirconf = timeout_req->per_dir_config;
    else dirconf = current_conn->server->lookup_defaults;

    fprintf(stderr, "In timeout routine, after if timeout_req != NULL\n");


    if (sig == SIGPIPE) {
        sprintf(errstr,"%s lost connection to client %s",
            timeout_name ? timeout_name : "request",
            get_remote_host(current_conn, dirconf, REMOTE_NAME));
    } else {
        sprintf(errstr,"%s timed out for %s",
            timeout_name ? timeout_name : "request",
            get_remote_host(current_conn, dirconf, REMOTE_NAME));
    }

    fprintf(stderr,"In timeout routine, after sig test for SIGPIPE\n");

    if (!current_conn->keptalive)
       log_error(errstr, current_conn->server);

    fprintf(stderr, "In timeout routine, after current_conn-keptalive\n");

    if (timeout_req) {
        /* Someone has asked for this transaction to just be aborted
         * if it times out...
         */

        request_rec *log_req = timeout_req;

        while (log_req->main || log_req->prev) {
            /* Get back to original request... */
            if (log_req->main) log_req = log_req->main;
            else log_req = log_req->prev;
        }

        if (!current_conn->keptalive)
            log_transaction(log_req);

        fprintf(stderr, "Just before bclose in timeout code\n");
        bclose(timeout_req->connection->client);
        fprintf(stderr, "Just after bclose in timeout code\n");

        if (!standalone) exit(0);
#ifdef NEXT
        longjmp(jmpbuffer,1);
#else
        siglongjmp(jmpbuffer,1);
#endif
    }
    else {
        abort_connection (current_conn);
    }
}

/* end of code segment for mail

Output from /tmp/httpd-log
# cat httpd-log
In timeout routine
In timeout routine, before siglongjmp
In timeout routine, in siglongjmp
In timeout routine, after siglongjmp
In timeout routine, after if timeout_req != NULL
#
as we can see it never gets past this code. I think
it because current_conn is undefined. 

    if (sig == SIGPIPE) {
        sprintf(errstr,"%s lost connection to client %s",
            timeout_name ? timeout_name : "request",
            get_remote_host(current_conn, dirconf, REMOTE_NAME));
    } else {
        sprintf(errstr,"%s timed out for %s",
            timeout_name ? timeout_name : "request",
            get_remote_host(current_conn, dirconf, REMOTE_NAME));
    }

I couldn't find a place were it is loaded if the server is running
using the inetd method of starting it. That loop is
confined to a small area of code in the main() part
of the program. 
   I don't program in C I was just wondering if you're having similar
   problems. I thought I would this to you before it becomes a big
   problem if your using the server in commercial setting.

In closing I hope that this info can be useful to
someone who is more qualified than I to fix the
problem. This code is also used for standalone mode, an I think that
repeated reloads are causing broken pipes at a high rate, are confusing
the timeout(sig) function.


--

Backtrace:
--
Don't gdb or dbx not part of UnixWare.
--

chuck
Chuck Murcko	N2K Inc.	Wayne PA	chuck@telebase.com
And now, on a lighter note:
Life would be so much easier if we could just look at the source code.