Skip Menu |
Report information
Id: 78634
Status: resolved
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: voropaev.andrey [at] gmail.com
Cc:
AdminCc:

Operating System: Linux
PatchStatus: (no value)
Severity: low
Type: core
Perl Version: 5.12.2
Fixed In: (no value)



Subject: Conflict in defining constant INIT with INIT blocks results in weird errors
Date: Wed, 27 Oct 2010 10:21:10 +0200 (CEST)
To: perlbug [...] perl.org
From: av [...] simcon-mt.com
Download (untitled) / with headers
text/plain 5.1k
This is a bug report for perl from voropaev.andrey@gmail.com, generated with the help of perlbug 1.39 running under perl 5.12.2. ----------------------------------------------------------------- [Please describe your issue here] One of my modules was defining constant INIT. After switching to perl5.12 the module stopped working and the error was Undefined subroutine &main::Needed called. INIT failed--call queue aborted. This didn't make any sense because there's no such function Needed in my module. I could reduce the code to the following code ########################################################### use strict; MyPackage::close_cnx(); package MyPackage; use strict; use constant INIT => 4; sub close_cnx { my $self = shift; init_action($self); } sub init_action { my $self = shift; return if $self->{Needed} <= $self->{count}; callit($self->{ID}, INIT); } ##################################################### The funniest thing is, if you switch the positions of init_action and close_cnx functions, then no error is displayed and perl runs fine. [Please do not change anything below this line] ----------------------------------------------------------------- --- Flags: category=core severity=low --- Site configuration information for perl 5.12.2: Configured by Gentoo at Mon Oct 25 11:45:43 CEST 2010. Summary of my perl5 (revision 5 version 12 subversion 2) configuration: Platform: osname=linux, osvers=2.6.34-gentoo-r11, archname=x86_64-linux uname='linux vandal 2.6.34-gentoo-r11 #2 mon oct 11 16:13:47 cest 2010 x86_64 amd athlon(tm) 64 processor 3200+ authenticamd gnulinux ' config_args='-des -Duseshrplib -Darchname=x86_64-linux -Dcc=x86_64-pc-linux-gnu-gcc -Doptimize=-march=athlon64 -O2 -pipe -Dldflags=-Wl,-O1 -Wl,--as-needed -Dprefix=/usr -Dsiteprefix=/usr -Dvendorprefix=/usr -Dscriptdir=/usr/bin -Dprivlib=/usr/lib64/perl5/5.12.2 -Darchlib=/usr/lib64/perl5/5.12.2/x86_64-linux -Dsitelib=/usr/lib64/perl5/site_perl/5.12.2 -Dsitearch=/usr/lib64/perl5/site_perl/5.12.2/x86_64-linux -Dvendorlib=/usr/lib64/perl5/vendor_perl/5.12.2 -Dvendorarch=/usr/lib64/perl5/vendor_perl/5.12.2/x86_64-linux -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/share/man/man1 -Dsiteman3dir=/usr/share/man/man3 -Dvendorman1dir=/usr/share/man/man1 -Dvendorman3dir=/usr/share/man/man3 -Dman1ext=1 -Dman3ext=3pm -Dlibperl=libperl.so.5.12.2 -Dlocincpth= -Duselargefiles -Dd_semctl_semun -Dcf_by=Gentoo -Dmyhostname=localhost -Dperladmin=root@localhost -Dinstallusrbinperl=n -Ud_csh -Uusenm -Di_ndbm -Di_gdbm -Di_db -DDEBUGGING=none -Dinc_version_list= 5.12.1/x86_64-linux 5.12.1 5.12.0/x86_64-linux 5.12.0 -Dusrinc=/usr/include -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64' hint=recommended, useposix=true, d_sigaction=define useithreads=undef, usemultiplicity=undef useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='x86_64-pc-linux-gnu-gcc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-march=athlon64 -O2 -pipe', cppflags='-fno-strict-aliasing -pipe -fstack-protector' ccversion='', gccversion='4.4.4', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='x86_64-pc-linux-gnu-gcc', ldflags ='-Wl,-O1 -Wl,--as-needed -fstack-protector' libpth=/usr/local/lib64 /lib64 /usr/lib64 libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc libc=/lib/libc-2.11.2.so, so=so, useshrplib=true, libperl=libperl.so.5.12.2 gnulibc_version='2.11.2' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fPIC', lddlflags='-shared -march=athlon64 -O2 -pipe -fstack-protector -Wl,-O1 -Wl,--as-needed' Locally applied patches: 0001-gentoo_MakeMaker-RUNPATH.diff 0002-gentoo_config_over.diff 0003-gentoo_cpan_definstalldirs.diff 0004-gentoo_cpanplus_definstalldirs.diff 0005-gentoo_create-libperl-soname.diff 0006-gentoo_MakeMaker-delete_packlist.diff 0007-fixes_8d66b3f9_h2hp_fix.diff --- @INC for perl 5.12.2: /usr/lib64/perl5/site_perl/5.12.2/x86_64-linux /usr/lib64/perl5/site_perl/5.12.2 /usr/lib64/perl5/vendor_perl/5.12.2/x86_64-linux /usr/lib64/perl5/vendor_perl/5.12.2 /usr/lib64/perl5/5.12.2/x86_64-linux /usr/lib64/perl5/5.12.2 /usr/lib64/perl5/site_perl /usr/lib64/perl5/vendor_perl . --- Environment for perl 5.12.2: HOME=/home/andrei LANG (unset) LANGUAGE (unset) LC_CTYPE=en_US.UTF-8 LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/usr/local/bin:/usr/bin:/bin:/opt/bin:/usr/x86_64-pc-linux-gnu/gcc-bin/4.4.3:/usr/games/bin:/opt/Adobe/Reader8/bin:/opt/java/jdk1.6.0_03/bin:/opt/Adobe/Reader8/bin:/opt/java/jdk1.6.0_03/bin PERL_BADLANG (unset) SHELL=/bin/zsh
Download (untitled) / with headers
text/plain 308b
A simpler test case: $ perl -le'use constant INIT => 4; print(INIT);' Undefined subroutine &IO::File::AUTOLOAD called. INIT failed--call queue aborted. Surprisingly, no problems with BEGIN. $ perl -le'use constant BEGIN => 4; print(BEGIN);' 4 constant issues a warning for those if warnings are in use.
RT-Send-CC: perl5-porters [...] perl.org, zefram [...] fysh.org
Download (untitled) / with headers
text/plain 1.1k
On Wed Oct 27 01:21:39 2010, voropaev.andrey@gmail.com wrote: Show quoted text
> One of my modules was defining constant INIT. After switching to > perl5.12 the module > stopped working and the error was > > Undefined subroutine &main::Needed called. > INIT failed--call queue aborted. > > This didn't make any sense because there's no such function Needed in > my module. I could > reduce the code to the following code > > ########################################################### > use strict; > > > MyPackage::close_cnx(); > > package MyPackage; > use strict; > > use constant INIT => 4; > > > sub close_cnx > { > my $self = shift; > init_action($self); > } > > sub init_action > { > my $self = shift; > return if $self->{Needed} <= $self->{count}; > callit($self->{ID}, INIT); > } > ##################################################### > > The funniest thing is, if you switch the positions of init_action and > close_cnx functions, > then no error is displayed and perl runs fine.
This was caused by: commit f7461760003db2ce68155c97ea6c1658e96fcd27 Author: Zefram <zefram fysh.org> Date: Sun Nov 8 15:03:45 2009 +0100 Bareword sub lookups
Subject: Re: [perl #78634] Conflict in defining constant INIT with INIT blocks results in weird errors
Date: Tue, 16 Nov 2010 21:59:36 +0000
To: perl5-porters [...] perl.org
From: Zefram <zefram [...] fysh.org>
Download (untitled) / with headers
text/plain 1.5k
Father Chrysostomos via RT wrote: Show quoted text
>> use constant INIT => 4;
There's a problem with this line: INIT, as a subroutine name, is magic to Perl, and defining a constant in this way actually amounts to defining a subroutine. If you change the name to XNIT then nothing funny happens. With the name INIT, funny stuff happens. At some point the constant, represented specially in the stash, is liable to get upgraded to a full glob and subroutine. gv_init() invokes newCONSTSUB() to build the full subroutine, but building it triggers the magic behaviour of process_special_blocks(). Part of this magic behaviour is to remove the sub from the glob that it's just been attached to, which makes gv_init() fail its assertion (on a debugging build) that the sub was properly attached. I'm not clear on how &Needed gets involved. That part of the reported behaviour has all the hallmarks of an object address getting reused such that an uncounted reference ends up referring to something unexpected. I believe the fingering of the bareword sub lookup patch is a red herring. The reason why it's come up is that it added a new situation in which *INIT would be upgraded to a real glob. Now, the upgrading occurs as a temporary measure while the use of the INIT constant (in the callit expression) is being processed at compile time. Formerly, no upgrading would occur in the compilation of your script. You can also trigger upgrading by putting "our $INIT" somewhere in the script. However, in my tests, a non-debugging 5.10 did not visibly misbehave when "our $INIT" was included to trigger upgrading. -zefram
Fixed by 75bd28c.
Subject: Re: [perl #78634] Conflict in defining constant INIT with INIT blocks results in weird errors
Date: Fri, 24 Dec 2010 03:28:42 +0100
To: perl5-porters [...] perl.org
From: Aristotle Pagaltzis <pagaltzis [...] gmx.de>
Download (untitled) / with headers
text/plain 748b
* Zefram <zefram@fysh.org> [2010-11-16 23:00]: Show quoted text
> Father Chrysostomos via RT wrote:
> >> use constant INIT => 4;
> > There's a problem with this line: INIT, as a subroutine name, > is magic to Perl, and defining a constant in this way actually > amounts to defining a subroutine. If you change the name to > XNIT then nothing funny happens.
It seems to me that `constant` should warn about this (as well as all the other special names (`BEGIN`, `END`, `CHECK` etc.)). For some reason I even feel it should maybe die… but since const subs aren’t likely to have any side effects I can’t find any reason to back up my gut feeling and it seems to fall under “give them rope”. Regards, -- Aristotle Pagaltzis // <http://plasmasturm.org/>


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org