httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paul Richards <p.richa...@elsevier.co.uk>
Subject Re: reentrant problem in log_error
Date Mon, 09 Dec 1996 18:19:23 GMT
Randy Terbush <randy@zyzzyva.com> writes:

> Here is a current patch. This does not seem to break anything.
> I'll need to give this to an affected site to see if it fixes
> anything. Can someone here comment on the changes?

Ok, I found time to take a look at this.

> ! void log_error(char *err, server_rec *s)
> ! {
> !     int len;
> !     char buf[512];
> !     sigset_t clrmask, oldmask;
> !     
> ! 
> !     sigemptyset(&clrmask);
> !     sigprocmask(SIG_SETMASK, &clrmask, &oldmask);
> ! 
> !     len = sprintf(buf, "[%s] %s\n", get_time(), err);
> !     write(fileno(s->error_log), buf, len + 1);
> ! 
> !     sigprocmask(SIG_SETMASK, &oldmask, NULL);
>   }

sigemptymask() will set a signal mask that unblocks all signals, a
further segv will now call the handler again. By default the current
signal type is blocked while in the handler, this will unblock it and
if you happen to trigger it again you'll get into a recursive loop of
re-calling the current signal handler until something more fatal (if
that's possible :-)) happens, like running out of stack space at which
point the kernel will kill the process no matter what.

The correct solution is to set the SA_RESETHAND flag. This resets the
handler to default when the signal is caught and unblocks it. i.e. if
we catch a SEGV then when that handler is caught SEGV is unblocked and
the default thing happens.

-- 
  Paul Richards. Originative Solutions Ltd.  (Netcraft Ltd. contractor)
  Elsevier Science TIS online journal project.
  Email: p.richards@elsevier.co.uk
  Phone: 0370 462071 (Mobile), +44 (0)1865 843155

Mime
View raw message