On Wed, Apr 21, 2004 at 01:25:17AM -0000, Mao Morimoto wrote: > Manipulating hash in signal handler (SIGCHLD) causes "Segmentation fault". > Run following script some times. "Segmentation fault" may happen at "POINT1" > or "POINT2". > > $speed = 0.001 ; # more fast more error > > $SIG{CHLD} = sub { > while ( (my $pid = waitpid( -1, WNOHANG )) > 0 ) { > if ( exists $children{$pid} ) { > delete $children{$pid} ; > } else { > print "no such pid in the hash! ($pid)\n" ; > } > } > } ; > > for ( my $i = 0 ; $i < 1000 ; $i++ ) { > my $pid = fork ; > if ( !defined $pid ) { > print "fork : error\n" ; > } elsif ( $pid ) { > $children{$pid} = time ; > } else { > my $delay = rand( $speed ) ; > select undef, undef, undef, $delay ; > exit 0 ; > } > while ( keys %children > 20 ) { ### SEGV here?? > sleep 1 ; > } > } > > 1 while wait > 0 ; > foreach my $pid ( keys %children ) { > print "still living?? ($pid)\n" ; > } Thanks for the report. The problem boils down to the following: The code $children{$pid} = time ; gets interrupted by the signal after $children{$pid} has been pushed on the stack (helem has executed), but before the assignment. Then in the signal handler, this value is freed by the delete. On return from the signal handler, the assignment is done to a freed value, and badness follows. Yet another side-effect of stuff on the stack not being ref-counted. I can't see a way of making this safe. -- "You're so sadly neglected, and often ignored. A poor second to Belgium, When going abroad." -- Monty Python - "Finland"Thread Previous | Thread Next