Open genuaboro opened 1 year ago
Reduced (v5.38.0):
$ perl -e '$x{a} ||= %x = ()'
panic: attempt to copy value 0 to a freed scalar 558ea0d9c408 at -e line 1.
There is an additional wrinkle in blead if you enable warnings:
$ ./perl -e '$x{a} ||= %x = ()'
panic: attempt to copy value 0 to a freed scalar 55d2e4a2b5e8 at -e line 1.
$ ./perl -we '$x{a} ||= %x = ()'
Useless assignment to a temporary at -e line 1.
$
The warning makes no sense in this context, so I suspect premature free / stack-not-refcounted shenanigans.
Can confirm that both the original code and my reduced form run through without errors on blead built with -Accflags='-DPERL_RC_STACK'
, so this is yet another manifestation of the "stack is not refcounted" bug.
And this has probably been present "forever":
$ perlbrew use perl-5.14.4
$ perl -e '$x{a} ||= %x = ()'
panic: attempt to copy value 0 to a freed scalar 558d31204078 at -e line 1.
Can confirm that both the original code and my reduced form run through without errors on blead built with
-Accflags='-DPERL_RC_STACK
, so this is yet another manifestation of the "stack is not refcounted" bug.
Observation confirmed (here, on FreeBSD-13):
$ ./perl -Ilib -v | head -2 | tail -1; ./perl -Ilib -V:config_args
This is perl 5, version 39, subversion 6 (v5.39.6 (v5.39.5-13-g7bb9a11330)) built for amd64-freebsd-thread-multi-ld
config_args='-des -Dusedevel -Duseithreads -Doptimize=-O2 -pipe -fstack-protector -fno-strict-aliasing -Dcc=gcc -Accflags=-DPERL_RC_STACK -Dusemorebits -DDEBUGGING';
$ ./perl -Ilib -e '$x{a} ||= %x = ()'
$ ./perl -Ilib -we '$x{a} ||= %x = ()'
Useless assignment to a temporary at -e line 1.
Description I found some code that clears a hash in an eval block while trying to assign a value to an element of the hash. This produces a panic.
Steps to Reproduce
panic: attempt to copy value x to a freed scalar 441d3381cc8
Variations of the code above that produce this panic: One liner:
perl -e '$x{a}||=do{%x=()}'
//= instead of ||=:perl -e '$x{a}//=do{%x=()}'
eval instead of do:perl -e '$x{a}||=eval{%x=()}'
map instead of do:perl -e '$x{a}||=map{%x=()}(0)'
array instead of hash:perl -e '$x[0]||=do{@x=()}'
The panic does not occur if "=" is used instead of "||=":
perl -e '$x{a}=do{%x=()}'
Expected behavior No panic.
Perl configuration
Found in perl 5.36.1 under OpenBSD. But also reproducable with Ubuntu 22.04 (perl 5.34.0), blead (5.39.6) and perl 5.8.9.