Skip to content

$SIG{__DIE__} does not get reliably triggered by compilation errors. #20296

Open
@demerphq

Description

@demerphq

Description
During compilation Perl "saves up errors", so that it can show as many errors as possible to the user as it can. When it reaches a threshold (in theory 1 for syntax errors and 10 for other errors but in practice sometimes 11 depending on the error), it will trigger a Perl_croak and stop compilation, this in turn will feed the list of errors encountered to the $SIG{__DIE__} handler, however if it runs off the end of the code without reaching the maximum it will not call Perl_croak when inside of an eval, and instead will stuff the error directly into $@, bypassing $SIG{__DIE__}. Thus $SIG{__DIE__} is inconsistently called by compilation errors.

Steps to Reproduce
This demonstrates code with two errors, neither of them syntax errors, which fail the compilation but do not trigger $SIG{__DIE__}:

$ perl -le'use strict; print $]; $SIG{__DIE__}= sub { print STDERR "in __DIE__"; $_[0] }; eval q($z+$y); print "\$@=",$@;'
5.037004
$@=Global symbol "$z" requires explicit package name (did you forget to declare "my $z"?) at (eval 1) line 1.
Global symbol "$y" requires explicit package name (did you forget to declare "my $y"?) at (eval 1) line 1.

This demonstrates code with one error, a syntax error, which fails compilation and does trigger $SIG{__DIE__}:

norole:yorton@oncidium:master:~/git_tree/HTML-Mason-1.59$ perl -le'use strict; print $]; $SIG{__DIE__}= sub { print STDERR "in __DIE__"; $_[0] }; eval q(1=); print "\$@=",$@;'
5.037004
in __DIE__
$@=syntax error at (eval 1) line 1, at EOF

And curiously die inside of a BEGIN triggers $SIG{__DIE__} twice:

perl -le'print $]; $SIG{__DIE__}= sub { print STDERR "in __DIE__"; $_[0] }; eval "BEGIN{die}"; print "\$@=",$@;'
5.037004
in __DIE__
in __DIE__
$@=Died at (eval 1) line 1.
BEGIN failed--compilation aborted at (eval 1) line 1.

Expected behavior
I think the ideal would be that each error triggers $SIG{__DIE__} once, regardless as to whether it stops compilation or not. Whether that means saving up a list of errors and calling it once per, or interleaving compilation after error and the call to $SIG{__DIE__} would be an implementation detail. It certainly should call $SIG{__DIE__} at least once before compilation terminates if it encounters an error, it shouldn't be random based on how many preceding errors there were.

Perl configuration

$ perl -V
Summary of my perl5 (revision 5 version 37 subversion 4) configuration:
  Commit id: 1b6686b25071fafd79b9bae431ef8190f3e29d0f
  Platform:
    osname=linux
    osvers=5.14.0-1051-oem
    archname=x86_64-linux-thread-multi
    uname='linux oncidium 5.14.0-1051-oem #58-ubuntu smp fri aug 26 05:50:00 utc 2022 x86_64 x86_64 x86_64 gnulinux '
    config_args='-de -Dcc=ccache gcc -Dld=gcc -Dprefix=/home/yorton/perl5/perlbrew/perls/stop_first_error -Dusethreads -Dusemultiplicity -DDEBUGGING -Dusedevel -Aeval:scriptdir=/home/yorton/perl5/perlbrew/perls/stop_first_error/bin'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=define
    usemultiplicity=define
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
  Compiler:
    cc='gcc'
    ccflags ='-D_REENTRANT -D_GNU_SOURCE -fwrapv -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
    optimize='-O2 -g'
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fwrapv -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
    ccversion=''
    gccversion='9.4.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='gcc'
    ldflags =' -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib/x86_64-linux-gnu /usr/lib /usr/lib64
    libs=-lpthread -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.31.so
    so=so
    useshrplib=false
    libperl=libperl.a
    gnulibc_version='2.31'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,-E'
    cccdlflags='-fPIC'
    lddlflags='-shared -O2 -g -L/usr/local/lib -fstack-protector-strong'


Characteristics of this binary (from libperl): 
  Compile-time options:
    DEBUGGING
    HAS_TIMES
    MULTIPLICITY
    PERLIO_LAYERS
    PERL_COPY_ON_WRITE
    PERL_DONT_CREATE_GVSV
    PERL_HASH_FUNC_SIPHASH13
    PERL_HASH_USE_SBOX32
    PERL_MALLOC_WRAP
    PERL_OP_PARENT
    PERL_PRESERVE_IVUV
    PERL_TRACK_MEMPOOL
    PERL_USE_DEVEL
    PERL_USE_SAFE_PUTENV
    USE_64_BIT_ALL
    USE_64_BIT_INT
    USE_ITHREADS
    USE_LARGE_FILES
    USE_LOCALE
    USE_LOCALE_COLLATE
    USE_LOCALE_CTYPE
    USE_LOCALE_NUMERIC
    USE_LOCALE_TIME
    USE_PERLIO
    USE_PERL_ATOF
    USE_REENTRANT_API
    USE_THREAD_SAFE_LOCALE
  Built under linux
  Compiled at Sep 13 2022 09:49:21
  %ENV:
    PERLBREW_CONFIGURE_FLAGS="-de -Dcc=ccache\ gcc -Dld=gcc"
    PERLBREW_HOME="/home/yorton/.perlbrew"
    PERLBREW_MANPATH="/home/yorton/perl5/perlbrew/perls/stop_first_error/man"
    PERLBREW_PATH="/home/yorton/perl5/perlbrew/bin:/home/yorton/perl5/perlbrew/perls/stop_first_error/bin"
    PERLBREW_PERL="stop_first_error"
    PERLBREW_ROOT="/home/yorton/perl5/perlbrew"
    PERLBREW_SHELLRC_VERSION="0.88"
    PERLBREW_VERSION="0.88"
  @INC:
    /home/yorton/perl5/perlbrew/perls/stop_first_error/lib/site_perl/5.37.4/x86_64-linux-thread-multi
    /home/yorton/perl5/perlbrew/perls/stop_first_error/lib/site_perl/5.37.4
    /home/yorton/perl5/perlbrew/perls/stop_first_error/lib/5.37.4/x86_64-linux-thread-multi
    /home/yorton/perl5/perlbrew/perls/stop_first_error/lib/5.37.4

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions