You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Perl POSIX::SigSet/SigAction can cause Perl to hang or core dump with a memory fault.
I've reproduced this issue with 5.36 and 5.38 using RedHat Linux 7.9 and 9.0, but in both cases I compiled Perl, aka I was not using the OS Perl.
The issue occurs when handling a SIGHUP. It generally takes many attempts (sometimes thousands) of handled SIGHUPs before the issue occurs.
When it hangs, an strike shows it hanging on a FUTEX call:
strace -p 256070
strace: Process 256070 attached
futex(0x7f92c3c59760, FUTEX_WAIT_PRIVATE, 2, NULL
^C strace: Process 256070 detached
If I force a core dump of this, the stack trace shows:
(gdb) where
#0 0x00007fc1be1067fc in __lll_lock_wait_private () from /lib64/libc.so.6
#1 0x00007fc1be082ca7 in _L_lock_18166 () from /lib64/libc.so.6
#2 0x00007fc1be0801d9 in calloc () from /lib64/libc.so.6
#3 0x00000000004e58d6 in Perl_safesyscalloc ()
#4 0x0000000000506449 in Perl_hv_common ()
#5 0x000000000050739e in Perl_hv_common_key_len ()
#6 0x00000000004f3595 in Perl_perly_sighandler ()
#7 <signal handler called>
#8 0x00007fc1be07b013 in _int_free () from /lib64/libc.so.6
#9 0x000000000051c3c2 in Perl_sv_clear ()
#10 0x000000000051c631 in Perl_sv_free2 ()
#11 0x000000000054e8de in Perl_free_tmps ()
#12 0x000000000050c818 in Perl_pp_unstack ()
#13 0x000000000050bbd6 in Perl_runops_standard ()
#14 0x0000000000440586 in perl_run ()
#15 0x0000000000417b89 in main ()
Replacing POSIX::Sig* with a simple $SIG{HUP} handler does not behave this way.
If I really push the HUPs (no sleep between each HUP) I can trigger it to crash and core dump. The core file show the following stack trace:
warning: Signature not supported. Hash algorithm SHA1 not available.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `/usr/local/bin/perl ./sigtest.pl'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000000000052021c in Perl_sv_upgrade ()
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.34-60.el9.x86_64 libxcrypt-4.4.18-3.el9.x86_64
(gdb) where
#0 0x000000000052021c in Perl_sv_upgrade ()
#1 0x000000000051ef4b in Perl_sv_setsv_flags ()
#2 0x000000000052c79a in Perl_newSVsv_flags ()
#3 0x00000000004ee317 in Perl_perly_sighandler ()
#4 <signal handler called>
#5 0x00007efbffaaf922 in free () from /lib64/libc.so.6
#6 0x0000000000515ae4 in Perl_sv_clear ()
#7 0x0000000000515d6e in Perl_sv_free2 ()
#8 0x0000000000549477 in Perl_free_tmps ()
#9 0x0000000000507cf8 in Perl_pp_unstack ()
#10 0x00000000005064a6 in Perl_runops_standard ()
#11 0x000000000043f55c in perl_run ()
#12 0x0000000000416552 in main ()
Steps to Reproduce
This can be reproduced using this script, it can take few minutes to hang. I suspect it just depends on where in the code it is when the HUP arrives.
#!/usr/local/bin/perl
use strict;
use Time::HiRes;
use POSIX;
print "PPID : $$\n";
my $ppid = $$;
for my $i ((0..2))
{
my $pid = fork();
unless ($pid)
{
sleep 1;
while (1)
{
kill 'HUP',$ppid;
Time::HiRes::sleep(.001);
}
exit;
}
print "child $pid\n";
}
my $sh = POSIX::SigSet->new();
my $old = {};
$sh->addset(SIGHUP);
my $cnt = 0;
$|=1;
my $action = POSIX::SigAction->new(sub {
my ($signal,$source) = @_;
$cnt++;
my $back = "\b" x length($cnt);
print $back.$cnt;
},$sh,&SA_SIGINFO);
sigaction(SIGHUP,$action,$old);
while(1)
{
sleep 1;
}
Expected behavior
This code should never hang in this fashion.
sigaction sets an unsafe signal handler by default. This can segfault under certain circumstances, that's why they're generally not recommended. This is not the fault of POSIX::SigSet or POSIX::SigAction. You may want to call $action->safe(1); to prevent this crash.
Module: POSIX
Perl POSIX::SigSet/SigAction can cause Perl to hang or core dump with a memory fault.
I've reproduced this issue with 5.36 and 5.38 using RedHat Linux 7.9 and 9.0, but in both cases I compiled Perl, aka I was not using the OS Perl.
The issue occurs when handling a SIGHUP. It generally takes many attempts (sometimes thousands) of handled SIGHUPs before the issue occurs.
When it hangs, an strike shows it hanging on a FUTEX call:
If I force a core dump of this, the stack trace shows:
Replacing POSIX::Sig* with a simple $SIG{HUP} handler does not behave this way.
If I really push the HUPs (no sleep between each HUP) I can trigger it to crash and core dump. The core file show the following stack trace:
Steps to Reproduce
This can be reproduced using this script, it can take few minutes to hang. I suspect it just depends on where in the code it is when the HUP arrives.
Expected behavior
This code should never hang in this fashion.
Perl configuration
FYI /home/dfreed/perl526/ doesn't exist, so it isn't anything there that is affecting this behavior.
The text was updated successfully, but these errors were encountered: