Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

localizing $? causes exit() to ignore the argument passed to it #14681

Open
p5pRT opened this issue Apr 28, 2015 · 1 comment
Open

localizing $? causes exit() to ignore the argument passed to it #14681

p5pRT opened this issue Apr 28, 2015 · 1 comment

Comments

@p5pRT
Copy link

p5pRT commented Apr 28, 2015

Migrated from rt.perl.org#124415 (status was 'new')

Searchable as RT124415$

@p5pRT
Copy link
Author

p5pRT commented Apr 28, 2015

From @avar

Created by @avar

This is a bug report is against a documented feature of perl, I know
it's mostly supposed to work like this, but but regardless of that I
think there's specific edge case that's buggy.

The "feature" is that you can write code that does this​:

  $ ~/perl5/installed/bin/perl5.21.12 -wE 'exit 1; END { $? = 2 }'; echo $?
  2

I.e. to quote "perldoc -f exit"​:

  [...] END routines and destructors can change the exit status by
  modifying $?.> for details.

Okey, so be that is it may, but I think this is a bug​:

  $ ~/perl5/installed/bin/perl5.21.12 -wE '{ local $?; exit 1 }'; echo $?
  0

The documentation says that if you change the value of $? in an END
routine we'll use the new value, but here we're not in an END routine
(just tearing down a scope), and nothing explicitly modified $?.

Admittedly we're splitting hairs here from an implementation level
because end of scope teardown here is a bit like END routines, and
"local" modifies $?, but this is very surprising from a language
user's perspective.

The reason I ran into this was because I was writing code that could
be simplified as​:

  $ ~/perl5/installed/bin/perl5.21.12 -wE '
  {
  local $?;
  system "false";
  my $ret = $? >> 8;
  say "Exiting with status <$ret>";
  exit $ret;
  }
  END {
  say "Our \$? in END is <$?>";
  }
  '; echo $?
  Exiting with status <1>
  Our $? in END is <0>
  0

I.e. I'm calling an external program and localizing $? first, if that
external program fails I'd like to exit, but because I localized $?
the exit status is clobbered.

The "exit" documentation suggests using POSIX​::_exit() if this is an
issue, but that's going to cause more issues for most programs,
i.e. DESTROY won't run anywhere etc.

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl 5.21.12:

Configured by avar at Tue Apr 28 15:40:55 UTC 2015.

Summary of my perl5 (revision 5 version 21 subversion 12) configuration:
  Commit id: b77ebf74c6d61f12ef717fd4bd6f765479481ca1
  Platform:
    osname=linux, osvers=3.14-2-amd64, archname=x86_64-linux-thread-multi
    uname='linux u.nix.is 3.14-2-amd64 #1 smp debian 3.14.13-2 (2014-07-24) x86_64 gnulinux '
    config_args='-DDEBUGGING=both -Doptimize=-ggdb3 -Dusethreads -Dprefix=/home/avar/perl5/installed -Dusedevel -des'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-ggdb3',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
    ccversion='', gccversion='4.2.1 Compatible Debian Clang 3.5.0 (tags/RELEASE_350/final)', 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 =' -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib
    libs=-lpthread -lnsl -ldb -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.19.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.19'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -ggdb3 -L/usr/local/lib -fstack-protector-strong'



@INC for perl 5.21.12:
    /home/avar/perl5/installed/lib/site_perl/5.21.12/x86_64-linux-thread-multi
    /home/avar/perl5/installed/lib/site_perl/5.21.12
    /home/avar/perl5/installed/lib/5.21.12/x86_64-linux-thread-multi
    /home/avar/perl5/installed/lib/5.21.12
    /home/avar/perl5/installed/lib/site_perl
    .


Environment for perl 5.21.12:
    HOME=/home/avar
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/avar/local/bin:/home/avar/perl5/installed/bin:/home/v-perlbrew/perl5/perlbrew/bin:/home/v-perlbrew/perl5/perlbrew/perls/current/bin:/home/avar/local/bin:/home/avar/g/misc-scripts:/home/avar/bin:/usr/local/bin:/usr/bin:/bin:/usr/games
    PERLDOC=-MPod::Text::Ansi
    PERL_BADLANG (unset)
    SHELL=/bin/bash

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants