Skip Menu |
Report information
Id: 129239
Status: open
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: mauke- <l.mai [at] web.de>
Cc:
AdminCc:

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

Attachments
0001-t-op-caller.t-add-a-TODO-test-for-RT-129239.patch



Subject: BEGIN blocks have wrong caller package
Date: Sat, 10 Sep 2016 11:13:27 +0200
To: perlbug [...] perl.org
From: l.mai [...] web.de
Download (untitled) / with headers
text/plain 3.1k
This is a bug report for perl from l.mai@web.de, generated with the help of perlbug 1.40 running under perl 5.24.0. ----------------------------------------------------------------- [Please describe your issue here] #!perl use strict; use warnings; package Mtfnpy; #line 100 "ABCDE" BEGIN { printf "package=%s, file=%s, line=%d\n", caller; } __END__ Output: package=main, file=ABCDE, line=102 Expected output: package=Mtfnpy, file=ABCDE, line=102 [Please do not change anything below this line] ----------------------------------------------------------------- --- Flags: category=core severity=low --- Site configuration information for perl 5.24.0: Configured by mauke at Mon May 9 21:21:33 CEST 2016. Summary of my perl5 (revision 5 version 24 subversion 0) configuration: Platform: osname=linux, osvers=4.4.5-1-arch, archname=i686-linux uname='linux simplicio 4.4.5-1-arch #1 smp preempt thu mar 10 07:54:30 cet 2016 i686 gnulinux ' config_args='' hint=previous, useposix=true, d_sigaction=define useithreads=undef, usemultiplicity=undef use64bitint=undef, use64bitall=undef, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2 -flto', cppflags='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include' ccversion='', gccversion='6.1.1 20160501', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234, doublekind=3 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12, longdblkind=3 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='cc', ldflags ='-fstack-protector-strong -L/usr/local/lib -flto' libpth=/usr/local/lib /usr/lib/gcc/i686-pc-linux-gnu/6.1.1/include-fixed /usr/lib /lib /usr/local/lib /usr/lib/gcc/i686-pc-linux-gnu/6.1.1/include-fixed /usr/lib libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc libc=libc-2.23.so, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.23' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fPIC', lddlflags='-shared -O2 -flto -L/usr/local/lib -fstack-protector-strong' --- @INC for perl 5.24.0: /home/mauke/usr/lib/perl5/site_perl/5.24.0/i686-linux /home/mauke/usr/lib/perl5/site_perl/5.24.0 /home/mauke/usr/lib/perl5/5.24.0/i686-linux /home/mauke/usr/lib/perl5/5.24.0 . --- Environment for perl 5.24.0: HOME=/home/mauke LANG=en_US.UTF-8 LANGUAGE=en_US LC_COLLATE=C LC_MONETARY=de_DE.UTF-8 LC_TIME=de_DE.UTF-8 LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/mauke/perl5/perlbrew/bin:/home/mauke/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl PERLBREW_BASHRC_VERSION=0.73 PERLBREW_HOME=/home/mauke/.perlbrew PERLBREW_ROOT=/home/mauke/perl5/perlbrew PERL_BADLANG (unset) PERL_UNICODE=SAL SHELL=/bin/bash
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 730b
On Sat Sep 10 02:13:50 2016, mauke- wrote: Show quoted text
> > This is a bug report for perl from l.mai@web.de, > generated with the help of perlbug 1.40 running under perl 5.24.0. > > > ----------------------------------------------------------------- > [Please describe your issue here] > > #!perl > use strict; > use warnings; > > package Mtfnpy; > #line 100 "ABCDE" > BEGIN { > printf "package=%s, file=%s, line=%d\n", caller; > } > > __END__ > > Output: > package=main, file=ABCDE, line=102 > > Expected output: > package=Mtfnpy, file=ABCDE, line=102
I’m not entirely sure I would expect that. I’m not sure what to expect. After all, ‘calling’ BEGIN in this case has not started running yet. -- Father Chrysostomos
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 728b
On Sat Sep 10 07:31:47 2016, sprout wrote: Show quoted text
> On Sat Sep 10 02:13:50 2016, mauke- wrote:
> > #!perl > > use strict; > > use warnings; > > > > package Mtfnpy; > > #line 100 "ABCDE" > > BEGIN { > > printf "package=%s, file=%s, line=%d\n", caller; > > } > > > > __END__ > > > > Output: > > package=main, file=ABCDE, line=102 > > > > Expected output: > > package=Mtfnpy, file=ABCDE, line=102
> > I’m not entirely sure I would expect that. I’m not sure what to > expect. After all, ‘calling’ BEGIN in this case has not started > running yet.
I don't understand your last sentence but the reported location of the call (which is the "}" of the BEGIN block) is in package Mtfnpy, not main. At minimum it's inconsistent.
Date: Mon, 12 Sep 2016 11:57:06 +0100
To: "l.mai [...] web.de via RT" <perlbug-followup [...] perl.org>
From: Dave Mitchell <davem [...] iabyn.com>
CC: perl5-porters [...] perl.org
Subject: Re: [perl #129239] BEGIN blocks have wrong caller package
Download (untitled) / with headers
text/plain 1.7k
On Sat, Sep 10, 2016 at 07:47:42AM -0700, l.mai@web.de via RT wrote: Show quoted text
> On Sat Sep 10 07:31:47 2016, sprout wrote:
> > On Sat Sep 10 02:13:50 2016, mauke- wrote:
> > > #!perl > > > use strict; > > > use warnings; > > > > > > package Mtfnpy; > > > #line 100 "ABCDE" > > > BEGIN { > > > printf "package=%s, file=%s, line=%d\n", caller; > > > } > > > > > > __END__ > > > > > > Output: > > > package=main, file=ABCDE, line=102 > > > > > > Expected output: > > > package=Mtfnpy, file=ABCDE, line=102
> > > > I’m not entirely sure I would expect that. I’m not sure what to > > expect. After all, ‘calling’ BEGIN in this case has not started > > running yet.
> > I don't understand your last sentence but the reported location of the call (which is the "}" of the BEGIN block) is in package Mtfnpy, not main. At minimum it's inconsistent.
What's happening is as follows: At compile time, 'package Foo' sets PL_curstash to point to %Foo::. Then any subsequent COPs (i.e. OP_NEXTSTATE) after that have their CopSTASH(cop) value set to the current value of PL_curstash. At run time, each nextstate op that is executed, sets PL_curcop to point to the currently executing COP. When a scope (such as a sub) is entered, the current value of PL_curcop is pushed onto the context stack. caller() uses the saved PL_curcop's on the context stack to extract out the stash name, line number etc. When BEGIN is called we're not actually in runtime, so PL_curcop points to &PL_compiling, rather than the last executed cop. PL_compiling gets its cop_line etc fields updated every time the toker reads in a new line (or sees #line), but a 'package' declaration doesn't update CopSTASH(&PL_compiling), when perhaps it should?? -- In economics, the exam questions are the same every year. They just change the answers.
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 935b
On Mon Sep 12 03:57:32 2016, davem wrote: Show quoted text
> PL_compiling gets its cop_line etc fields updated every time the toker > reads in a new line (or sees #line), but a 'package' declaration > doesn't > update CopSTASH(&PL_compiling), when perhaps it should??
PL_curstash is used at compile time instead of CopSTASH(&PL_compiling). I have always assumed it was for efficiency’s sake. But, come to think of it, if PL_compiling is a fixed buffer in the interpreter struct, then #defining PL_curstash to CopSTASH(&PL_compiling) would make no speed difference on threaded builds, but I don’t know about non-threaded. Then again, I may be wrong about the reason why PL_curstash is separate and CopSTASH(&PL_compiling) is unused. Hmm, maybe it’s because cops do not contain stash pointers under threads. Maybe the solution is to have pp_caller check whether its cop == &PL_compiling and use PL_curstash instead. -- Father Chrysostomos
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 2.5k
On Mon Sep 12 03:57:32 2016, davem wrote: Show quoted text
> On Sat, Sep 10, 2016 at 07:47:42AM -0700, l.mai@web.de via RT wrote:
> > On Sat Sep 10 07:31:47 2016, sprout wrote:
> > > On Sat Sep 10 02:13:50 2016, mauke- wrote:
> > > > #!perl > > > > use strict; > > > > use warnings; > > > > > > > > package Mtfnpy; > > > > #line 100 "ABCDE" > > > > BEGIN { > > > > printf "package=%s, file=%s, line=%d\n", caller; > > > > } > > > > > > > > __END__ > > > > > > > > Output: > > > > package=main, file=ABCDE, line=102 > > > > > > > > Expected output: > > > > package=Mtfnpy, file=ABCDE, line=102
> > > > > > I’m not entirely sure I would expect that. I’m not sure what to > > > expect. After all, ‘calling’ BEGIN in this case has not started > > > running yet.
> > > > I don't understand your last sentence but the reported location of > > the call (which is the "}" of the BEGIN block) is in package Mtfnpy, > > not main. At minimum it's inconsistent.
> > What's happening is as follows: > > At compile time, 'package Foo' sets PL_curstash to point to %Foo::. > Then any subsequent COPs (i.e. OP_NEXTSTATE) after that have their > CopSTASH(cop) value set to the current value of PL_curstash. > > At run time, each nextstate op that is executed, sets PL_curcop to > point > to the currently executing COP. > > When a scope (such as a sub) is entered, the current value of > PL_curcop > is pushed onto the context stack. > > caller() uses the saved PL_curcop's on the context stack to extract > out > the stash name, line number etc. > > When BEGIN is called we're not actually in runtime, so PL_curcop > points to > &PL_compiling, rather than the last executed cop. > > PL_compiling gets its cop_line etc fields updated every time the toker > reads in a new line (or sees #line), but a 'package' declaration > doesn't > update CopSTASH(&PL_compiling), when perhaps it should??
Thanks for this detailed explanation! I discovered this issue because I have a C module that calls a Perl sub at parse time. That Perl sub always saw the wrong calling package and I didn't understand why. So I thought I'd check how perl itself handles that situation in BEGIN blocks (and maybe steal the code). As it turned out, BEGIN blocks have exactly the same issue. Based on your explanation I've come up with the following workaround: assert(PL_curcop == &PL_compiling); COP curcop_with_stash = PL_compiling; CopSTASH_set(&curcop_with_stash, PL_curstash); PL_curcop = &curcop_with_stash; n = call_sv(sv, G_SCALAR); PL_curcop = &PL_compiling; It seems to pass all tests. :-) (I don't know what the best way is to fix this in core.)
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 362b
On Sat Sep 10 02:13:50 2016, mauke- wrote: Show quoted text
> #!perl > use strict; > use warnings; > > package Mtfnpy; > #line 100 "ABCDE" > BEGIN { > printf "package=%s, file=%s, line=%d\n", caller; > } > > __END__ > > Output: > package=main, file=ABCDE, line=102 > > Expected output: > package=Mtfnpy, file=ABCDE, line=102
Here's a patch that adds a TODO test for now.
Subject: 0001-t-op-caller.t-add-a-TODO-test-for-RT-129239.patch
From bb3329a391fce27c00dd55aeaf5357337aa09192 Mon Sep 17 00:00:00 2001 From: Lukas Mai <l.mai@web.de> Date: Fri, 21 Oct 2016 15:18:38 +0200 Subject: [PATCH] t/op/caller.t: add a TODO test for RT #129239 --- t/op/caller.t | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/t/op/caller.t b/t/op/caller.t index 3017465..1ffb5b3 100644 --- a/t/op/caller.t +++ b/t/op/caller.t @@ -5,7 +5,7 @@ BEGIN { chdir 't' if -d 't'; require './test.pl'; set_up_inc('../lib'); - plan( tests => 97 ); # some tests are run in a BEGIN block + plan( tests => 100 ); # some tests are run in a BEGIN block } my @c; @@ -352,3 +352,17 @@ EOP $::testing_caller = 1; do './op/caller.pl' or die $@; + +{ + package RT129239; + BEGIN { + my ($pkg, $file, $line) = caller; + ::is $file, 'virtually/op/caller.t', "BEGIN block sees correct caller filename"; + ::is $line, 12345, "BEGIN block sees correct caller line"; + TODO: { + local $::TODO = "BEGIN blocks have wrong caller package [perl #129239]"; + ::is $pkg, 'RT129239', "BEGIN block sees correct caller package"; + } +#line 12345 "virtually/op/caller.t" + } +} -- 2.10.0
From: KES <kes-kes [...] yandex.ru>
Subject: Re: [perl #129239] BEGIN blocks have wrong caller package
To: "perlbug-followup [...] perl.org" <perlbug-followup [...] perl.org>
Date: Fri, 03 Mar 2017 00:59:02 +0200
Download (untitled) / with headers
text/plain 104b
This issue seems is related: https://rt.perl.org/Public/Bug/Display.html?id=127083 to the current one.


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