Perl / Perl/perl5

END blocks not executed after SIGINT interrupts blocked `flush()`.

Open
#17,564 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Needs Triage
Dominant language
Perl
Stars
2.3k
Forks
646
Avg merge
2d 22h
Merged PRs (30d)
49

Description

To: perlbug@perl.org
Subject: END blocks not executed sometimes on SIGINT.
From: rxxrc@pm.me
Message-Id: 5.30.1_3453748_1581699110@sereia.localdomain
Reply-To: rxxrc@pm.me

This is a bug report for perl from rxxrc@pm.me,
generated with the help of perlbug 1.41 running under perl 5.30.1.


For some reason END blocks are not executed if

  1. the program is blocked in a flush() call because a pipe buffer is
    full
  2. the block is interrupted by a SIGINT (possibly other signals; I haven't
    tested)
  3. the SIGINT is caught with a $SIG{INT} handler which calls exit()

If the program is blocked in any other way the END block is run as expected.

Minimal(-ish) demonstration:

#!/usr/bin/env perl

use strict;
use warnings;

$SIG{INT} = sub {
    print "\nSIGINT received\n";
    exit 2;
};

END {
    print "END BLOCK\n";
}

my $child_pid = open my $child_handle, '|-', "sleep 9999"
    or die "fork failed: $!\n";

# As soon as this overflows the 16-bit mark, and hence our writes start
# blocking on the pipe buffer, perl no longer seems to run END blocks on
# SIGINT?
my $count = 65537;

for (1..$count) {
    print{$child_handle} "\n" or die "print failed: $!\n";
    # SIGINT while this is blocked (because the pipe buffer is full) triggers
    # the $SIG{INT} trap and exits the program, but does not execute the
    # END block.
    $child_handle->flush or die "flush failed: $!\n";
}
print "printing done\n";

# SIGINT while *this* is blocked (if we didn't fill the pipe buffer) triggers
# the SIGINT handler but also runs the END block.
waitpid $child_pid, 0;

Perl Info
[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
    category=core
    severity=low
---
Site configuration information for perl 5.30.1:

Configured by builduser at Mon Nov 11 19:16:46 CET 2019.

Summary of my perl5 (revision 5 version 30 subversion 1) configuration:

  Platform:
    osname=linux
    osvers=5.3.8-arch1-1
    archname=x86_64-linux-thread-multi
    uname='linux flo-64 5.3.8-arch1-1 #1 smp preempt @1572357769 x86_64 gnulinux '
    config_args='-des -Dusethreads -Duseshrplib -Doptimize=-march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -fno-plt -Dprefix=/usr -Dvendorprefix=/usr -Dprivlib=/usr/share/perl5/core_perl -Darchlib=/usr/lib/perl5/5.30/core_perl -Dsitelib=/usr/share/perl5/site_perl -Dsitearch=/usr/lib/perl5/5.30/site_perl -Dvendorlib=/usr/share/perl5/vendor_perl -Dvendorarch=/usr/lib/perl5/5.30/vendor_perl -Dscriptdir=/usr/bin/core_perl -Dsitescript=/usr/bin/site_perl -Dvendorscript=/usr/bin/vendor_perl -Dinc_version_list=none -Dman1ext=1perl -Dman3ext=3perl -Dcccdlflags='-fPIC' -Dlddlflags=-shared -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -Dldflags=-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=define
    usemultiplicity=define
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
    bincompat5005=undef
  Compiler:
    cc='cc'
    ccflags ='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
    optimize='-march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -fno-plt'
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
    ccversion=''
    gccversion='9.2.0'
    gccosandvers=''
    intsize=4
    longsize=8
    ptrsize=8
    doublesize=8
    byteorder=12345678
    doublekind=3
    d_longlong=define
    longlongsize=8
    d_longdbl=define
    longdblsize=16
    longdblkind=3
    ivtype='long'
    ivsize=8
    nvtype='double'
    nvsize=8
    Off_t='off_t'
    lseeksize=8
    alignbytes=8
    prototype=define
  Linker and Libraries:
    ld='cc'
    ldflags ='-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/include-fixed /usr/lib /lib/../lib /usr/lib/../lib /lib /lib64 /usr/lib64
    libs=-lpthread -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
    perllibs=-lpthread -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.30.so
    so=so
    useshrplib=true
    libperl=libperl.so
    gnulibc_version='2.30'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,-E -Wl,-rpath,/usr/lib/perl5/5.30/core_perl/CORE'
    cccdlflags='-fPIC'
    lddlflags='-shared -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -L/usr/local/lib -fstack-protector-strong'


---
@INC for perl 5.30.1:
    /usr/lib/perl5/5.30/site_perl
    /usr/share/perl5/site_perl
    /usr/lib/perl5/5.30/vendor_perl
    /usr/share/perl5/vendor_perl
    /usr/lib/perl5/5.30/core_perl
    /usr/share/perl5/core_perl

---
Environment for perl 5.30.1:
    HOME=/rxxrc
    LANG=en_AU.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/rxxrc/bin:/rxxrc/.cargo/bin:/rxxrc/bin:/rxxrc/.cargo/bin:/rxxrc/bin:/rxxrc/.cargo/bin
    PERL_BADLANG (unset)
    SHELL=/bin/bash

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the minimal Perl reproducer, focusing on the SIGINT handler, blocked child_handle->flush call, exit(), and END block. Compare interruption during flush() with interruption during waitpid, and verify completion by confirming that END BLOCK is printed after SIGINT.

Written by the indexing model from the issue text.

Assessment

Tech stack
perl
Domain
operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.