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

refaliasing kills value on stack #15457

Open
p5pRT opened this issue Jul 17, 2016 · 1 comment
Open

refaliasing kills value on stack #15457

p5pRT opened this issue Jul 17, 2016 · 1 comment

Comments

@p5pRT
Copy link

p5pRT commented Jul 17, 2016

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

Searchable as RT128649$

@p5pRT
Copy link
Author

p5pRT commented Jul 17, 2016

From zefram@fysh.org

Created by zefram@fysh.org

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.

Perl Info

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

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