Bug 859257 - Defered signal handling doesn't work correctly when interrupted by another signal
Defered signal handling doesn't work correctly when interrupted by another si...
Status: CLOSED NOTABUG
Product: Red Hat Enterprise Linux 6
Classification: Red Hat
Component: perl (Show other bugs)
6.3
All Linux
unspecified Severity medium
: rc
: ---
Assigned To: perl-maint-list
BaseOS QE - Apps
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2012-09-20 19:05 EDT by Justin Washington
Modified: 2012-09-24 06:49 EDT (History)
2 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2012-09-24 06:49:34 EDT
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Justin Washington 2012-09-20 19:05:21 EDT
Description of problem:

Perl 5.7.3 and later use Deferred Signals. But it doesn't work correctly if another signal arrives when the signal handler is running.


Version-Release number of selected component (if applicable):

- Perl 5.10.1 on RHEL 6.3
- Perl 5.8.8 on RHEL 5.8

How reproducible:

Yes

Steps to Reproduce:

Run this testing script:

#!/usr/bin/perl

our $i = 0;

$SIG{CHLD} = \&sighandler;
kill CHLD => $$;

exit;

sub sighandler {
    exit if $i == 6;
    print ++$i, ": processing", "\n";
    kill CHLD => $$;
    print $i, ": done", "\n";
}

  
Actual results:

On RHEL 6.3 and RHEL 5.8, it outputs:

1: processing
1: done
2: processing
2: done

And then script exists. 

Expected results:

On Ubuntu 12.04 x86_64 with Perl 5.14.2, it runs correctly and outputs:

1: processing
1: done
2: processing
2: done
3: processing
3: done
4: processing
4: done
5: processing
5: done
6: processing
6: done

Additional info:

Probably Perl 5.14 fixed this bug. It would be great if this fix can be back ported to RHEL 5.8 and RHEL 6.3
Comment 2 Justin Washington 2012-09-20 19:39:10 EDT
Here are 3 some other tests:


1). Script t1.pl:

#!/usr/bin/perl

use POSIX;

our $i = 0;

if (1) {
    my $sigaction = POSIX::SigAction->new(\&sighandler, POSIX::SigSet->new());
    $sigaction->safe(1);
    POSIX::sigaction(&POSIX::SIGCHLD, $sigaction);
}

kill CHLD => $$;

exit;

sub sighandler {
    exit if $i == 6;
    print ++$i, ": processing", "\n";
    kill CHLD => $$;
    print $i, ": done", "\n";
}


Output:


1: processing
1: done
2: processing
2: done

2). Script t2.pl


#!/usr/bin/perl

use POSIX;

our $i = 0;

if (1) {
    my $sigaction = POSIX::SigAction->new(\&sighandler, POSIX::SigSet->new());
    #$sigaction->safe(1);
    POSIX::sigaction(&POSIX::SIGCHLD, $sigaction);
}

kill CHLD => $$;

exit;

sub sighandler {
    exit if $i == 6;
    print ++$i, ": processing", "\n";
    kill CHLD => $$;
    print $i, ": done", "\n";
}

Output:


1: processing
1: done
2: processing
2: done
3: processing
3: done
4: processing
4: done
5: processing
5: done
6: processing
6: done


3). Script t3.pl:


#!/usr/bin/perl

use POSIX;

our $i = 0;

my $sigaction = POSIX::SigAction->new(\&sighandler, POSIX::SigSet->new());
$sigaction->safe(1);
POSIX::sigaction(&POSIX::SIGCHLD, $sigaction);

kill CHLD => $$;

exit;

sub sighandler {
    exit if $i == 6;
    print ++$i, ": processing", "\n";
    kill CHLD => $$;
    print $i, ": done", "\n";
}


Output:


1: processing
1: done
2: processing
2: done
3: processing
3: done
4: processing
4: done
5: processing
5: done
6: processing
6: done


The output of script t1.pl is not correct.
Comment 3 Petr Pisar 2012-09-24 05:35:05 EDT
Where you get confidence that all 6 signals get processed or even emitted before the code reaches exit call in the main program?
Comment 4 Petr Pisar 2012-09-24 06:49:34 EDT
Adding 

while ($i < 6) {sleep 1;}

just before `exit' in the t1.pl as well as in the code from comment #1 does fix your problem. I'm really keen to say your code is missing a synchronization.

Note You need to log in before you can comment on or make changes to this bug.