Front page | perl.perl5.porters |
Postings from April 2000
[ID 20000409.003] Disappearing constant values
Thread Next
From:
eric
Date:
April 9, 2000 21:21
Subject:
[ID 20000409.003] Disappearing constant values
Message ID:
E12eVhT-0007Lp-00@mail.xmission.com
This is a bug report for perl from eblood@xmission.com,
generated with the help of perlbug 1.28 running under perl v5.6.0.
-----------------------------------------------------------------
[Please enter your report here]
When useithreads is defined, the following code does not generate
a 'Modification of a read-only value attempted' error like it does
in perl5.005_03.
sub C () { 1 }
sub M { $_[0] = 2; }
eval "C";
M(C);
The following code shows a much more serious consequence of the
same bug.
sub C () { 1 }
sub M { M() if defined(C); }
eval "C";
M(C);
This code should go into infinite recursion. However in
perl5.6.0 using ithreads it drops out of recursion after
the second iteration because C becomes undefined.
This is caused by a number of interacting pieces of code as follows:
1. When the tokenizer encounters a bareword whose definition
is a constant sub, it gets the SV for the constant in the
sub and puts it in the op_sv field of the opcode
(after incrementing the SV's reference count).
As a result multiple opcodes may all point to the same SV.
2. Peep moves this SV to the pad. When it does so it sets the
SVs_PADTMP flag. At this point multiple pad slots may all
be pointing to the same SV.
3. Opcodes sometimes get cleared before the end of the program
(when they are were generated by eval or by the main body
of a module). When the opcode is cleared it calls pad_free
on it's op_targ value.
4. pad_free clears the SVs_PADTMP and SVs_READONLY flags on the
SV. Unfortunately this SV may also be used in other pads.
5. When a procedure recurses it copies the pad constants but
only if the associated SV is read-only. Since the read-only
flag was cleared by pad_free the constant doesn't get copied
and appears as undef in the recursive call.
I can see several possible solutions but I'm not sure which
approach to take. I'm willing to write a patch but I'd like
some advice on which way to go. Or if someone with more experience
in the perl core feels they should do this instead that's fine with
me.
These are the possibilities I see:
1. Have the tokenizer always create a new SV for constant subs.
2. Have peek copy the constant instead of using it directly when
it moves it to the pad.
3. Have pad_free never remove the flags when both SVs_PADTMP and
SVs_READONLY are set.
4. Have pad_free only remove the flags when the reference count
for the SV is 1.
I lean towards 4 or 2. I think that 4 would be safe but it might
not always free up a pad slot when it should. 2 should also be
safe but would cause additional memory usage.
[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
category=core
severity=high
---
Site configuration information for perl v5.6.0:
Configured by eblood at Fri Mar 24 12:36:06 2000.
Summary of my perl5 (revision 5 version 6 subversion 0) configuration:
Platform:
osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread
uname=''
config_args='undef'
hint=recommended, useposix=true, d_sigaction=undef
usethreads=undef use5005threads=undef useithreads=define usemultiplicity=define
useperlio=undef d_sfio=undef uselargefiles=undef
use64bitint=undef use64bitall=undef uselongdouble=undef usesocks=undef
Compiler:
cc='cl', optimize='-O1 -MD -DNDEBUG', gccversion=
cppflags='-DWIN32'
ccflags ='-O1 -MD -DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DPERL_MSVCRT_READFIX'
stdchar='char', d_stdstdio=define, usevfork=false
intsize=4, longsize=4, ptrsize=4, doublesize=8
d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=4
alignbytes=8, usemymalloc=n, prototype=define
Linker and Libraries:
ld='link', ldflags ='-nologo -nodefaultlib -release -libpath:"D:\apps\perl56\lib\CORE" -machine:x86'
libpth="g:\apps\msdevstd\lib" "g:\apps\msdevstd\mfc\lib" "%lib%" "D:\apps\perl56\lib\CORE"
libs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib
libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl56.lib
Dynamic Linking:
dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -release -libpath:"D:\apps\perl56\lib\CORE" -machine:x86'
Locally applied patches:
ACTIVEPERL_LOCAL_PATCHES_ENTRY
---
@INC for perl v5.6.0:
d:\apps\cmt\lib
D:/apps/perl56/lib
D:/apps/perl56/site/lib
.
---
Environment for perl v5.6.0:
HOME=d:\home
LANG (unset)
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=d:\apps\perl56\bin;D:\WINNT\system32;D:\WINNT;g:\apps\bor\Delphi5\Projects\Bpl;g:\apps\bor\Delphi5\Bin;d:\apps\perl\bin;d:\apps\cmt\nt;d:\bin\nt;d:\bin;;g:\apps\bor\delphi3\bin;g:\apps\bor\tasm\bin;g:\apps\bor\bp\bin;d:\apps\iqtools;g:\apps\msdevstd\bin\;g:\apps\bor\bcc55\bin;;d:\rnd;c:\APPS\PERL\BIN
PERLLIB=d:\apps\cmt\lib
PERL_BADLANG (unset)
PERL_MAILERS=smtp
SHELL (unset)
Thread Next
-
[ID 20000409.003] Disappearing constant values
by eric