-
Notifications
You must be signed in to change notification settings - Fork 577
Caller inside BEGIN block return wrong info #15109
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
Comments
From @KES777Created by @KES777$cat t.pl BEGIN { use Mod2; $cat Mod2.pm use Mod1; 1; $cat Mod1.pm 1; The output is: main - Mod2.pm - 12 - Mod2::BEGIN main - Mod1.pm - 14 - Mod1::BEGIN It is not expected that the information about last frames is changed. Perl Info
|
From @iabynOn Wed, Dec 30, 2015 at 04:31:01AM -0800, KES wrote:
Here's a slightly simplified example that only requires a single module: Mod.pm: package Mod; /tmp/t: #return file and line of top-most level call site BEGIN { sub f { print "f(): ", ::top_call(), "\n"; } This code prints the outermost call-site at various places. It outputs: MAIN BEGIN: /tmp/t:16 I'd expect the middle two to be MOD BEGIN: /tmp/t:16 instead, since they're both called from the BEGIN in /tmp/t. Still present in blead. -- |
The RT System itself - Status changed from 'new' to 'open' |
GH #15109 The output of caller() (e.g. as produced by carp::Confess) produces multiple identical outputs when within a nested use/require. This is because at the time of calling the 'BEGIN { require ... }', PL_curcop is set to &PL_compiling, which is a fixed buffer within the interpreter, whose individual file and line fields are saved and restored when doing a new require/eval. This means that within the innermost require, PL_compiling has file:lineno of the innermost source file, and multiple saved PL_curcop values in the context stack frames all point to the same &PL_copmpiling. So all levels of the stack trace appear to come from the innermost file. This commit fixes this (after a fashion) by, at the start of calling a BEGIN, making PL_curcop point to a temporary copy of PL_compiling instead. This is all a bit of a hack.
Yes, this commit fixed the issue. |
This change broke my module Devel::CompileLevel. The module works by modifying |
On Thu, Jan 02, 2020 at 09:06:54AM -0800, Graham Knop wrote:
This change broke my module [Devel::CompileLevel]
(https://metacpan.org/pod/Devel::CompileLevel). The module works by
modifying `${^WARNING_BITS}`, then trying to detect those changes using
the warnings bitmask returned by `caller`. Although this is a bit
weird, it does seem like a reasonable thing to expect to work. The
module doesn't have any users that I know of though.
As far as I can see your module was exploiting a bug which my change
fixed. The caller() function is documented to return the hints "that the
caller was compiled with". Since the chain of BEGIN and/or import() subs
that you are scanning back over have all been compiled, it's actually a
bug if changing ${^WARNING_BITS} changes what caller() reports. In
addition, caller()'s docs say that "the $hints and $bitmask values are
subject to change between versions of Perl, and are not meant for external
use".
So all in all, I'm sanguine about this change.
…--
"You may not work around any technical limitations in the software"
-- Windows Vista license
|
The location it's detecting is not a I'm not particularly attached to the module though. |
GH #15109 The output of caller() (e.g. as produced by carp::Confess) produces multiple identical outputs when within a nested use/require. This is because at the time of calling the 'BEGIN { require ... }', PL_curcop is set to &PL_compiling, which is a fixed buffer within the interpreter, whose individual file and line fields are saved and restored when doing a new require/eval. This means that within the innermost require, PL_compiling has file:lineno of the innermost source file, and multiple saved PL_curcop values in the context stack frames all point to the same &PL_copmpiling. So all levels of the stack trace appear to come from the innermost file. This commit fixes this (after a fashion) by, at the start of calling a BEGIN, making PL_curcop point to a temporary copy of PL_compiling instead. This is all a bit of a hack. (cherry picked from commit f2f32cd)
GH #15109, #17567 My original fix for this issue, v5.31.6-141-gf2f32cd638 made a shallow copy of &PL_compiling. However, for non-default warning bits, this made two COPs share the malloced() cop_warnings, and bad things ensured. In particular this was flagged up in: GH #17567: "BBC: AYOUNG/OpenVZ-0.01.tar.gz" The fix in this commit is to do a deep copy of the COP using newSTATEOP().
GH #15109, #17567 [ this commit was originally applied as v5.31.9-121-gfb8188b84d, but was quickly reverted by v5.31.9-124-g6311900a66. I'm now -re-applying it, but with a 'SAVEFREEOP(PL_curcop)' added, which was missing from the original commit. ] My original fix for this issue, v5.31.6-141-gf2f32cd638 made a shallow copy of &PL_compiling. However, for non-default warning bits, this made two COPs share the malloced() cop_warnings, and bad things ensured. In particular this was flagged up in: GH #17567: "BBC: AYOUNG/OpenVZ-0.01.tar.gz" The fix in this commit is to do a deep copy of the COP using newSTATEOP().
This ticket should be reopened as f2f32cd was reverted.
Yves
…On Fri, 20 Dec 2019 at 22:04, Nicolas R. ***@***.***> wrote:
@iabyn <https://github.com/iabyn> was this fixed by f2f32cd
<f2f32cd>
and so we can close this case?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#15109?email_source=notifications&email_token=AAAZ5R5KLTYZJRK53SLQSYDQZUXPTA5CNFSM4J6CUVFKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHOFF5I#issuecomment-568087285>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAZ5RZYPO4KQKRC42XQS6TQZUXPTANCNFSM4J6CUVFA>
.
--
perl -Mre=debug -e "/just|another|perl|hacker/"
|
This reapplies two reverted patches as a single squashed commit. Revert "Revert "avoid identical stack traces"" This reverts commit 79f75ea which itself reverted f2f32cd Revert "Revert "fixup to "avoid identical stack traces" - try 2"" This reverts commit 2abf7ef which itself reverted ad89278 Original Author: David Mitchell <[email protected]> Original Date: Fri Dec 13 13:48:25 2019 +0000 avoid identical stack traces GH #15109 The output of caller() (e.g. as produced by carp::Confess) produces multiple identical outputs when within a nested use/require. This is because at the time of calling the 'BEGIN { require ... }', PL_curcop is set to &PL_compiling, which is a fixed buffer within the interpreter, whose individual file and line fields are saved and restored when doing a new require/eval. This means that within the innermost require, PL_compiling has file:lineno of the innermost source file, and multiple saved PL_curcop values in the context stack frames all point to the same &PL_copmpiling. So all levels of the stack trace appear to come from the innermost file. This commit fixes this (after a fashion) by, at the start of calling a BEGIN, making PL_curcop point to a temporary copy of PL_compiling instead. This is all a bit of a hack.
This reapplies two reverted patches as a single squashed commit. Revert "Revert "avoid identical stack traces"" This reverts commit 79f75ea which itself reverted f2f32cd Revert "Revert "fixup to "avoid identical stack traces" - try 2"" This reverts commit 2abf7ef which itself reverted ad89278 Original Author: David Mitchell <[email protected]> Original Date: Fri Dec 13 13:48:25 2019 +0000 avoid identical stack traces GH #15109 The output of caller() (e.g. as produced by carp::Confess) produces multiple identical outputs when within a nested use/require. This is because at the time of calling the 'BEGIN { require ... }', PL_curcop is set to &PL_compiling, which is a fixed buffer within the interpreter, whose individual file and line fields are saved and restored when doing a new require/eval. This means that within the innermost require, PL_compiling has file:lineno of the innermost source file, and multiple saved PL_curcop values in the context stack frames all point to the same &PL_copmpiling. So all levels of the stack trace appear to come from the innermost file. This commit fixes this (after a fashion) by, at the start of calling a BEGIN, making PL_curcop point to a temporary copy of PL_compiling instead. This is all a bit of a hack.
This reapplies two reverted patches as a single squashed commit. Revert "Revert "avoid identical stack traces"" This reverts commit 79f75ea which itself reverted f2f32cd Revert "Revert "fixup to "avoid identical stack traces" - try 2"" This reverts commit 2abf7ef which itself reverted ad89278 Original Author: David Mitchell <[email protected]> Original Date: Fri Dec 13 13:48:25 2019 +0000 avoid identical stack traces GH #15109 The output of caller() (e.g. as produced by carp::Confess) produces multiple identical outputs when within a nested use/require. This is because at the time of calling the 'BEGIN { require ... }', PL_curcop is set to &PL_compiling, which is a fixed buffer within the interpreter, whose individual file and line fields are saved and restored when doing a new require/eval. This means that within the innermost require, PL_compiling has file:lineno of the innermost source file, and multiple saved PL_curcop values in the context stack frames all point to the same &PL_copmpiling. So all levels of the stack trace appear to come from the innermost file. This commit fixes this (after a fashion) by, at the start of calling a BEGIN, making PL_curcop point to a temporary copy of PL_compiling instead. This is all a bit of a hack.
This reapplies two reverted patches as a single squashed commit. Revert "Revert "avoid identical stack traces"" This reverts commit 79f75ea which itself reverted f2f32cd Revert "Revert "fixup to "avoid identical stack traces" - try 2"" This reverts commit 2abf7ef which itself reverted ad89278 Original Author: David Mitchell <[email protected]> Original Date: Fri Dec 13 13:48:25 2019 +0000 avoid identical stack traces GH #15109 The output of caller() (e.g. as produced by carp::Confess) produces multiple identical outputs when within a nested use/require. This is because at the time of calling the 'BEGIN { require ... }', PL_curcop is set to &PL_compiling, which is a fixed buffer within the interpreter, whose individual file and line fields are saved and restored when doing a new require/eval. This means that within the innermost require, PL_compiling has file:lineno of the innermost source file, and multiple saved PL_curcop values in the context stack frames all point to the same &PL_copmpiling. So all levels of the stack trace appear to come from the innermost file. This commit fixes this (after a fashion) by, at the start of calling a BEGIN, making PL_curcop point to a temporary copy of PL_compiling instead. This is all a bit of a hack.
Perls are installed via perlbrew. 5.36.0 and 5.37.6 works as expected, but 5.34.1 does not. Here is result of @iabyn test:
Perl 5.36.0
Perl 5.37.6
Here is output from my test: Perl 5.34.1 (Not expected. Here is no info about Mod1 package. Also info about source file is broken)
Perl 5.36.0
Perl 5.37.6
|
Hi @KES777 this wasnt applied in 5.34.1 and it wasn't backported either. I will close this ticket as the fix was finally remerged. |
Migrated from rt.perl.org#127083 (status was 'open')
Searchable as RT127083$
The text was updated successfully, but these errors were encountered: