develooper Front page | perl.perl5.porters | Postings from July 2016

[perl #128649] refaliasing kills value on stack

From:
Zefram
Date:
July 17, 2016 05:25
Subject:
[perl #128649] refaliasing kills value on stack
Message ID:
rt-4.0.18-27807-1468733124-1317.128649-75-0@perl.org
# New Ticket Created by  Zefram 
# Please include the string:  [perl #128649]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org/Ticket/Display.html?id=128649 >



This is a bug report for perl from zefram@fysh.org,
generated with the help of perlbug 1.40 running under perl 5.24.0.


-----------------------------------------------------------------
[Please describe your issue here]

Another form of stack-not-refcounted bug:

$ perl -Mexperimental=refaliasing -lwe 'my $x = 3; print +($x, (\$x = \5))[0] // "undef"'
undef
$ perl -Mexperimental=refaliasing -lwe 'my $x = 3; my $y = \$x; print +($x, (\$x = \5))[0] // "undef"'
3

In the former case, the original $x scalar has its refcount go to zero and
be destroyed due to the refaliasing operation, while the scalar is sitting
on the stack.  The latter case shows proper behaviour, which it achieves
by keeping an extra reference to the original $x scalar somewhere else.
That shows that the refaliasing per se doesn't alter the value in the
original $x.

This came about from me thinking about the proposal I made to just create
more mortal references to things being put on the stack.  The rule would
simply be that the code putting something onto the stack has to make
sure that the thing will live at least as long as it is on the stack.
(I have always followed this principle in my own modules, subject to
the qualification of assuming that all other code is following it too.)

Consider which operations would need to create new mortal refs and
which would not.  All versions of the array-in-list-context operation,
for example, obviously needs to create such refs, because the individual
element scalars can be undermined by clearing the array.  Observe another
stack-not-refcounted bug which arises from not creating the extra refs:

$ perl -lwe 'my @a = (22,33,44); print @a, (@a=()), "z"'
Use of uninitialized value in print at -e line 1.
Use of uninitialized value in print at -e line 1.
Use of uninitialized value in print at -e line 1.
z
$ perl -lwe 'my @a = (22,33,44); my @b = map { \$_ } @a; print @a, (@a=()), "z"'
223344z

At first glance it would appear that the padsv op is one of the ones
that doesn't need any extra refs, because the SV will live in the pad
for the entire duration of the sub call, encompassing the time it'll be
on the stack.  But refaliasing changes that, providing a way to evict
the scalar from the pad.  Hence the above bug.

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

Configured by zefram at Mon May  9 19:42:55 BST 2016.

Summary of my perl5 (revision 5 version 24 subversion 0) configuration:
   
  Platform:
    osname=linux, osvers=3.16.0-4-amd64, archname=x86_64-linux-thread-multi
    uname='linux barba.rous.org 3.16.0-4-amd64 #1 smp debian 3.16.7-ckt11-1+deb8u6 (2015-11-09) x86_64 gnulinux '
    config_args='-des -Dprefix=/home/zefram/usr/perl/perl_install/perl-5.24.0-i64-f52 -Duselargefiles -Dusethreads -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dusedevel -Uversiononly -Ui_db'
    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 -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='-O2',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
    ccversion='', gccversion='4.9.2', 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/lib/gcc/x86_64-linux-gnu/4.9/include-fixed /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=true, libperl=libperl.so
    gnulibc_version='2.19'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-rpath,/home/zefram/usr/perl/perl_install/perl-5.24.0-i64-f52/lib/5.24.0/x86_64-linux-thread-multi/CORE'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'


---
@INC for perl 5.24.0:
    /home/zefram/usr/perl/perl_install/perl-5.24.0-i64-f52/lib/site_perl/5.24.0/x86_64-linux-thread-multi
    /home/zefram/usr/perl/perl_install/perl-5.24.0-i64-f52/lib/site_perl/5.24.0
    /home/zefram/usr/perl/perl_install/perl-5.24.0-i64-f52/lib/5.24.0/x86_64-linux-thread-multi
    /home/zefram/usr/perl/perl_install/perl-5.24.0-i64-f52/lib/5.24.0
    .

---
Environment for perl 5.24.0:
    HOME=/home/zefram
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/zefram/usr/perl/perl_install/perl-5.24.0-i64-f52/bin:/home/zefram/usr/perl/util:/home/zefram/pub/x86_64-unknown-linux-gnu/bin:/home/zefram/pub/common/bin:/usr/bin:/bin:/usr/local/bin:/usr/games
    PERL_BADLANG (unset)
    SHELL=/usr/bin/zsh




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About