[LA.pm] Problem with FastCGI under Apache 2

Kevin Scaldeferri kevin+lapm at scaldeferri.com
Thu Feb 9 15:47:29 PST 2006


On Feb 9, 2006, at 3:21 PM, Benjamin J. Tilly wrote:

> "Loren Osborn" <lsosborn at dis-sol-inc.com> wrote:
>>
>> We are having a serious problem with signals in FastCGI under Apache 2
>> and could use any assistance you could offer.  It appears that FastCGI
>> is attempting to shutdown a perl script that it's running by sending 
>> it
>> a SIGTERM, but the process is asleep and the signal is queued for when
>> the process is next awakened.  When FastCGI gets a request for a page 
>> of
>> the type that was sent the SIGTERM, it sees the process as still 
>> alive,
>> and sends it another request. The process is awakened, sees the 
>> SIGTERM,
>> and dies without providing a response to FastCGI.  FastCGI then 
>> produces
>> an error indicating that the script produced no output.
>
> Set the environment variable PERL_SIGNALS to unsafe for the script.
>
> Here is the issue.  Perl has 2 ways to handle signals.  One is safe, 
> which will interrupt and handle the error when the current opcode 
> finishes.  The other is unsafe, which uses setlongjmp to break out of 
> whatever Perl is doing right now.
>

This is mostly true, but has some caveats, since perl doesn't actually 
mask the signals during the execution of an opcode.


When you say that the process is "asleep", what do you mean exactly?

Normally, when a perl process is blocked in a system call and a signal 
comes in, the system call will be interrupted and the signal will be 
handled immediately.  If you are using safe signals, the internal 
signal handler just sets a flag and continues the opcode (immediately 
after the system call), then calls the Perl signal hander at the end of 
the opcode.  If you are using unsafe signals, the internal signal 
handler will immediately execute the Perl signal handler, then normal 
execution will resume with the next instruction after the system call.

So, if you are in a system sleep() call, or select(), or flock(), or 
anything like that, the SIGTERM should break you out essentially 
immediately, regardless of safe vs. unsafe signals.


The usual place that you see this is when you're calling something like 
a database client, which does some signal masking internally.  In that 
case, the signal will be blocked until the database call finishes.



I don't know exactly what's going on with your situation, but I would 
definitely recommend that you _NOT_ use unsafe signals.  The thing is, 
they're not safe.  There are really bizarro things that can happen to 
perl's internal state as a result of using them.  It's not as nice as 
perl just segfaulting if something bad happens.  You can end up with 
silently incorrect behavior after the delivery of an unsafe signal.  I 
hope this example will scare you away from ever using unsafe signals in 
an important application:

http://kevin.scaldeferri.com/blog/2004/03/04/unsafe.html


-kevin



More information about the Losangeles-pm mailing list