develooper Front page | perl.perl5.porters | Postings from March 2000

Re: Safe Signals? [Summary and Some Questions]

From:
Josh Wilmes
Date:
March 24, 2000 19:08
Subject:
Re: Safe Signals? [Summary and Some Questions]
Message ID:
200003250308.VAA15535@sky.net

I don't think that my question has really been answered yet, but since I feel that the issue of signals in perl is something of a FAQ  (at least among the other perl programmers I know), I would summarize what has been said so far in this thread regarding the problem of safely handling signals in perl.  It seems that this problem does still exist in 5.6.0, but perhaps we can decide upon a method to remedy this problem in a future release.

(Note that my understanding of perl internals is extremely limited, so this explanation is based upon info from a number of prior posts by more knowledgeable individuals.  Thanks to those who have contributed to this discussion thus far[1], as well several past discussions of this topic on p5p and c.l.p.m)



* The Problem:

  There are times when a signal may interrupt perl while it is in the middle
  of something such that certain global state becomes corrupted and perl
  segfaults.
 
  In my opinion, this is not a good situation.  If there is a language feature
  which may cause perl to segfault, it really needs to be fixed.  Perl scripts
  should not be able to segfault through something as simple as an alarm handler.

  This problem is caused by several base problems:

  1) If perl is interrupted while processing an opcode, certain internal state
     variables may become inconsistent the signal handler does any significant
     computation of its own.

  2) Memory allocation in perl is not reentrant.  If perl attempts to allocate
     any memory while it is in the middle of another allocation, it will very
     likely become corrupted.

* Workarounds:

  Careful Coding:

    It is possible to minimize, but not eliminate, core dumps by ensuring that
    a signal handler does nothing other than set a variable which has already
    been allocated.  For example:
   
      BEGIN {
          $foo_counter = 0;
      }
      sub $SIG{FOO} = sub { $foo_counter++; };

    is reasonably safe, as you can be reasonably sure that no additional
    memory allocation will take place, and incrementing a scalar is unlikely
    to require much global state.

    However, it is NOT 100% safe [6].

  Tk and Event Modules:
    These require restructuring a program to use an event loop.  While this is
    a good solution for programs which can benefit from an event loop, it does
    not address the fact that as it stands, %SIG (at least for real signals)
    is not safe to use.

  Thread::Signal:
    This module implements a separate signal handling thread which allows for
    safe signal delivery in perl.  However it requires a threaded perl, which
    as I understand it, is still not a good idea, mainly due to performance
    issues. 

* Fixing the perl core, and some questions.

  In the last thread on this topic, Larry proposed a model for deferred 
  signal handling[5], but others felt that immediate signal delivery
  (interruption of long-running opcodes) was essential.  It appears that
  safe immediate signal handlers in perl aren't terribly practical, however.[4]

  The SafeSignals patch[7] was proposed by Chip last year.  As I understand it,
  it provided a 'use' pragma for switching out the internal run-ops loop.  When
  the alternative safe-signals loop was used, there was a performance hit.

  Sarathy proposed[8] instead pushing this down into the individual opcodes,
  and leaving the loop intact.  I believe this was in order to some extent to
  deal intelligently with long-running opcodes.   This made it onto the
  "todo list" for 5.6.0, but so far as I know has not been implemented yet.
  Is it planned for 5.7.0?

  Will this proposal have a performance impact?  Can it become the default, or
  would it be controlled by a pragma?  Or would it autodetect if %SIG was used
  for a signal and turn itself on?

  How would this proposal deal with the issue of interrupting a long-running
  operation?  It seems to me that people will want alarm() to do the right 
  thing- would it?
  

Thanks, 

--Josh


* References:

[1] http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000-03/msg02211.html

[2] http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000-01/msg00010.html

[3] http://x45.deja.com/getdoc.xp?AN=600594057

[4] http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000-01/msg00411.html

[5] http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000-01/msg00309.html
    http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000-01/msg00344.html

[6] http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000-01/msg00073.html

[7] http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1999-04/msg01169.html

[8] http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1999-04/msg01195.html





nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About