Does Perl's Safe understand new features? - perl

I'm playing with the Safe module for inclusion in Mastering Perl. Versions before v5.16 (the earliest supported version) doesn't seem to understand new keywords. Am I missing something?
say works with v5.16 and later
use v5.10;
use Safe;
say "Running $0 under $^V with Safe ", Safe->VERSION;
my $compartment = Safe->new;
$compartment->permit( ':base_io', ':load' );
my $code =<<"CODE";
use v5.10;
say "Hello Safe!";
CODE
$compartment->reval( $code ) or do {
my $error = $#;
warn "Safe compartment error! $#";
};
This code runs as I expect under v5.18 and v5.16, the two officially supported versions of Perl:
% perl5.18.0 safe.pl
Running safe.pl under v5.18.0 with Safe 2.35
Hello Safe!
% perl5.16.3 safe.pl
Running safe.pl under v5.16.3 with Safe 2.35
Hello Safe!
It doesn't work prior to v5.16 since it doesn't think the say keyword is valid:
% perl5.14.4 safe.pl
Running safe.pl under v5.14.4 with Safe 2.35
String found where operator expected at (eval 5) line 2, near "say "Hello Safe!""
(Do you need to predeclare say?)
Safe compartment error! syntax error at (eval 5) line 2, near "say "Hello Safe!""
% perl5.12.3 safe.pl
Running safe.pl under v5.12.3 with Safe 2.35
String found where operator expected at (eval 5) line 2, near "say "Hello Safe!""
(Do you need to predeclare say?)
Safe compartment error! syntax error at (eval 5) line 2, near "say "Hello Safe!""
% perl5.10.1 safe.pl
Running safe.pl under v5.10.1 with Safe 2.35
String found where operator expected at (eval 5) line 2, near "say "Hello Safe!""
(Do you need to predeclare say?)
Safe compartment error! syntax error at (eval 5) line 2, near "say "Hello Safe!""
state doesn't work but breaks differently
With state it's different.
use v5.10;
use Safe;
say "Running $0 under $^V with Safe ", Safe->VERSION;
my $compartment = Safe->new;
$compartment->permit( ':base_io', ':load' );
my $code =<<'CODE';
use v5.10;
print "Hello Safe!\n";
foo();
sub foo {
state $n = 0;
print "n is $n\n";
}
CODE
$compartment->reval( $code ) or do {
my $error = $#;
warn "Safe compartment error! $#";
};
v5.18 and v5.16 think state is a syntax error:
% perl5.18.0 safe.pl
Running safe.pl under v5.18.0 with Safe 2.35
Hello Safe!
n is 0
% perl5.16.3 safe.pl
Running safe.pl under v5.16.3 with Safe 2.35
Hello Safe!
n is 0
Before those versions, I think it's treating state as an indirect method:
% perl5.14.4 safe.pl
Running safe.pl under v5.14.4 with Safe 2.35
Hello Safe!
Safe compartment error! Can't call method "state" on an undefined value at (eval 5) line 5.
given
given has the same problem:
use v5.10;
use Safe;
say "Running $0 under $^V with Safe ", Safe->VERSION;
my $compartment = Safe->new;
$compartment->permit( ':base_io', ':load' );
my $code =<<'CODE';
use v5.10;
print "Hello Safe!\n";
my $foo = 'Buster Bean';
given( $foo ) {
when( /Buster/ ) { print "Buster\n" }
}
CODE
$compartment->reval( $code ) or do {
my $error = $#;
warn "Safe compartment error! $#";
};
It works just fine in v5.16 and v5.18:
% perl5.18.0 safe.pl
Running safe.pl under v5.18.0 with Safe 2.35
given is experimental at (eval 5) line 4.
when is experimental at (eval 5) line 5.
Hello Safe!
Buster
But breaks in earlier versions:
% perl5.14.4 safe.pl
Running safe.pl under v5.14.4 with Safe 2.35
Safe compartment error! syntax error at (eval 5) line 4, near ") {"

It's possible to use bisecting tool to check when certain piece of code started working. One is included, if you clone entire Perl repository. This allows to check when it started to work.
~/perl> Porting/bisect.pl --expect-fail --start=v5.14.0 --end=v5.16.3 -e '
use v5.10;
use Safe;
say "Running $0 under $^V with Safe ", Safe->VERSION;
my $compartment = Safe->new;
$compartment->permit( ":base_io", ":load" );
my $code =<<"CODE";
use v5.10;
say "Hello Safe!";
CODE
$compartment->reval( $code ) or do {
my $error = $#;
warn "Safe compartment error! $#";
exit 1;
};
'
After doing that, you get the result.
7d69d4a61be1619f90910462eac42234c874712e is the first bad commit
commit 7d69d4a61be1619f90910462eac42234c874712e
Author: Father Chrysostomos <sprout#cpan.org>
Date: Thu Dec 15 16:26:16 2011 -0800
Disable $[ under 5.16
This adds the array_base feature to feature.pm
Perl_feature_is_enabled has been modified to use PL_curcop, rather
than PL_hintgv, so it can work with run-time hints as well.
(PL_curcop holds the current state op at run time, and &PL_compiling
at compile time, so it works for both.) The hints in $^H are not
stored in the same place at compile time and run time, so the FEATURE_IS_ENABLED macro has been modified to check first whether
PL_curop == &PL_compiling.
Since array_base is on by default with no hint for it in %^H, it is
a ‘negative’ feature, whose entry in %^H turns it off. feature.pm
has been modified to support such negative features. The new FEATURE_IS_ENABLED_d can check whether such default features
are enabled.
This does make things less efficient, as every version declaration
now loads feature.pm to disable all features (including turning off
array_base, which entails adding an entry to %^H) before loading the
new bundle. I have plans to make this more efficient.
:100644 100644 e96e6608641a33838158a54cb0ac2402c716e848 3b81d3fc286480be3512864b43f3c9230fd1c376 M embed.fnc
:040000 040000 7f9483dd9d2f290810866ad40810461398385515 e1d43bd8aa24bec1d6b5f80a1f36f6787fb70d32 M ext
:100644 100644 2af41a87c417a2afded5c9f55bd0a69bcf71db80 37a1bd9510eb5064d052fb00b68a0e7eec3df716 M gv.c
:040000 040000 9d82bf63a49734aec1e01c5da6362c3dec7e1a22 2b12bd8c206ae14fc819fbb781cdb2b09c1a9c95 M lib
:100644 100644 c55ca63a5819c32c747279ddcc698653dc8eca6f 3432dfe5c4c7b568712a9f0f31177695528892e4 M mg.c
:100644 100644 313087d34a4135e1854b4f00ab58b71d687a32e1 812ece2bb1757489865e36dec0ceeaa8d6c86168 M op.c
:100644 100644 e203dfe1941e7c3e13cdf6b68e509339258229bf ef3d4efec6604738d6beded3ff16d9a1ab73c465 M perl.h
:100644 100644 92befdac8afebe578740e84ca24ca46a091b072e eec052f413638d1efba00c81f423a68d1a4f984e M proto.h
:040000 040000 9deb7ece55f230bcf0e0bb83a5e1646e05770db2 d425283f05fb825181a2b3836ff3ce2570821500 M t
:100644 100644 2c29c582e2a1c2ba6aeefe56368a383785b27830 2f395d458da5941b49552d85bbf52b1070b5b32e M toke.c
bisect run success
That took 1921 seconds
The problem is that it was an accidentally fixed bug. If you take a look at diff for toke.c, you can notice that the old version took features from PL_hintgv, but the new version uses PL_curcop. The difference between these is that PL_hintgv contains compile time unit settings. PL_curcop however, contains current settings. While being in Safe, use feature saves to wrong place.
The problem is that PL_hintgv checks current compilation unit. When dealing with Safe, it's meaningless empty hash, because of the hacking the module does to work. PL_curcop however checks current scope - so it works well with Safe.
Now for workarounds. One exists, but it involves specifying settings by using eval. As eval sets compilation unit, you can use it to specify settings you want. It won't let user change the settings, but will let provide you some settings for evaluated code.
For example, if you change $compartment->reval( $code ) with eval '$compartment->reval( $code )' in your code, it will start working, as eval made a new compilation unit, and your code has use v5.10; in heading (eval copies use v5.10 from it). It's an awful hack nevertheless …

Related

Perl eval scope

According to perldoc, String Eval should be performed in the current scope. But the following simple test seems to contradict this.
We need the following two simple files to set up the test. Please put them under the same folder.
test_eval_scope.pm
package test_eval_scope;
use strict;
use warnings;
my %h = (a=>'b');
sub f1 {
eval 'print %h, "\n"';
# print %h, "\n"; # this would work
# my $dummy = \%h; # adding this would also work
}
1
test_eval_scope.pl
#!/usr/bin/perl
use File::Basename;
use lib dirname (__FILE__);
use test_eval_scope;
test_eval_scope::f1();
When I run the program, I got the following error
$ test_eval_scope.pl
Variable "%h" is not available at (eval 1) line 1.
My question is why the variable %h is out of scope.
I have done some modification, and found the following:
If I run without eval(), as in the above comment, it will work.
meaning that %h should be in the scope.
If I just add a seemingly useless mentioning in the code, as in the above
comment, eval() will work too.
If I combine pl and pm file into one file, eval() will work too.
If I declare %h with 'our' instead of 'my', eval() will work too.
I encountered this question when I was writing a big program which parsed user-provided code during run time. I don't need solutions as I have plenty workarounds above. But I cannot explain why the above code doesn't work. This affects my perl pride.
My perl version is v5.26.1 on linux.
Thank you for your help!
Subs only capture variables they use. Since f1 doesn't use %h, it doesn't capture it, and %h becomes inaccessible to f1 after it goes out of scope when the module finishes executing.
Any reference to the var, including one that's optimized away, causes the sub to capture the variable. As such, the following does work:
sub f1 {
%h if 0;
eval 'print %h, "\n"';
}
Demo:
$ perl -M5.010 -we'
{
my $x = "x";
sub f { eval q{$x} }
sub g { $x if 0; eval q{$x} }
}
say "f: ", f();
say "g: ", g();
'
Variable "$x" is not available at (eval 1) line 1.
Use of uninitialized value in say at -e line 8.
f:
g: x

Dot at the beginning of a "print" statement?

I've come across something odd while using a Perl script. It's about using a dot giving different results.
perlop didn't turn anything up, or perhaps I just blew past it. I was looking at Operator Precedence and Associativity
print "I'd expect to see 11x twice, but I only see it once.\n";
print (1 . 1) . "3";
print "\n";
print "" . (1 . 1) . "3\n";
print "Pluses: I expect to see 14 in both cases, and not 113, because plus works on numbers.\n";
print (1 . 1) + "3";
print "\n";
print "" + (1 . 1) + "3\n";
Putting quotes at the start is an acceptable workaround to get what I want, but what is happening here with the order of operations that I'm missing? What rules are there to be learned?
When you put the first argument to print in parentheses, Perl sees it as function call syntax.
So this:
print (1 . 1) . "3";
is parsed as this:
print(1 . 1) . "3";
or, equivalently:
(print 1 . 1) . "3";
Therefore, Perl prints "11", then takes the return value of that print call (which is 1 if it succeeded), concatenates 3 to it, and - since the whole expression is in void context - does absolutely nothing with the resulting 13.
If you run your code with warnings enabled (via -w on the command line or the use warnings; pragma), you will get these warnings identifying your error:
$ perl -w foo.pl
print (...) interpreted as function at foo.pl line 2.
print (...) interpreted as function at foo.pl line 6.
Useless use of concatenation (.) or string in void context at foo.pl line 2.
Useless use of addition (+) in void context at foo.pl line 6.
As Borodin points out in the comment below, you shouldn't rely on -w (or the in-code equivalent $^W); production code should always make use of the warnings pragma, preferably with use warnings qw(all);. While it wouldn't matter in this particular instance, you should also use strict;, although requesting modern features via useversion; for a Perl version of 5.11 or higher automatically turns on strict as well.
If a named operator (or a sub call) is followed by parens, those parens delimit the operands (or arguments).
print (1 . 1) . "3"; ≡ ( print(1 . 1) ) . "3";
print "" . (1 . 1) . "3"; ≡ print("" . (1 . 1) . "3");
Note that Perl would have alerted you of your problems had you been using (use strict; and) use warnings qw( all ); as you should.
print (...) interpreted as function at a.pl line 2.
print (...) interpreted as function at a.pl line 6.
Useless use of concatenation (.) or string in void context at a.pl line 2.
Useless use of addition (+) in void context at a.pl line 6.
I'd expect to see 11x twice, but I only see it once.
11
113
Pluses: I expect to see 14 in both cases, and not 113, because plus works on numbers.
11
Argument "" isn't numeric in addition (+) at a.pl line 8.
14

(4 + sub) not equals to (sub + 4)?

(edit) TL;DR: my problem was that I though the Win32 API defines were true integer constants (as in the platform SDK headers) while the Win32 Perl wrapper defines them as subs. Thus caused the one-liner parsing misunderstood.
While testing in a one-liner a call to Win32::MsgBox, I am puzzled by the following : giving that the possible arguments for MsgBox are the message, a sum of flags to chose the kind of buttons (value 0..5) and message box icon "constants" (MB_ICONSTOP, ...) and the title
calling perl -MWin32 -e"Win32::MsgBox world, 4+MB_ICONQUESTION, hello" gives the expected result
while the looking similar code perl -MWin32 -e"Win32::MsgBox world, MB_ICONQUESTION+4, hello" is wrong
I first though that it comes from my lack of parenthesis, but adding some perl -MWin32 -e"Win32::MsgBox (world, MB_ICONQUESTION+4, hello)" gives exactly the same wrong result.
I tried with a colleague to dig deeper and display the parameters that are passed to a function call (as the MB_xxx constants are actually subs) with the following code
>perl -Mstrict -w -e"sub T{print $/,'called T(#'.join(',',#_).'#)'; 42 }; print $/,'results:', join ' ,', T(1), T+1, 1+T"
that outputs
called T(#1#)
called T(##)
called T(#1,43#)
results:42 ,42
but I can't understand why in the list passed to join() the args T+1, 1+T are parsed as T(1, 43)...
B::Deparse to the rescue:
C:>perl -MO=Deparse -MWin32 -e"Win32::MsgBox world, MB_ICONQUETION+4, hello"
use Win32;
Win32::MsgBox('world', MB_ICONQUESTION(4, 'hello'));
-e syntax OK
C:>perl -MO=Deparse -MWin32 -e"Win32::MsgBox world, 4+MB_ICONQESTION, hello"
use Win32;
Win32::MsgBox('world', 4 + MB_ICONQUESTION(), 'hello');
-e syntax OK
The MB_ICONQUESTION call in the first case is considered a function call with the arguments +4, 'hello'. In the second case, it is considered as a function call with no arguments, and having 4 added to it. It is not a constant, it seems, but a function.
In the source code we get this verified:
sub MB_ICONQUESTION { 0x00000020 }
It is a function that returns 32 (00100000 in binary, indicating a bit being set). Also as Sobrique points out, this is a flag variable, so you should not use addition, but the bitwise logical and/or operators.
In your case, it just accepts any arguments and ignores them. This is a bit confusing if you are expecting a constant.
In your experiment case, the statement
print $/,'results:', join ' ,', T(1), T+1, 1+T
Is interpreted
print $/,'results:', join ' ,', T(1), T(+1, (1+T))
Because execution from right to left goes
1+T = 43
T +1, 43 = 42
T(1) = 42
Because plus + has higher precedence than comma ,, and unary + even higher.
To disambiguate, you need to do use parentheses to clarify precedence:
print $/,'results:', join ' ,', T(1), T()+1, 1+T
# ^^-- parentheses
As a general rule, one should always use parentheses with subroutine calls. In perldoc perlsub there are 4 calling notations:
NAME(LIST); # & is optional with parentheses.
NAME LIST; # Parentheses optional if predeclared/imported.
&NAME(LIST); # Circumvent prototypes.
&NAME; # Makes current #_ visible to called subroutine.
Of which in my opinion, only the first one is transparent, and the other ones a bit obscure.
This is all to do with how you're invoking T and how perl is interpreting the results.
If we deparse your example we get:
BEGIN { $^W = 1; }
sub T {
use strict;
print $/, 'called T(#' . join(',', #_) . '#)';
42;
}
use strict;
print $/, 'results:', join(' ,', T(1), T(1, 1 + T()));
This is clearly not what you've got in mind, but does explain why you get the result you do.
I would suggest in your original example - rather that + you may wish to consider using | as it looks very much like MB_ICONQUESTION is intended to be a flag.
So:
use strict;
use warnings;
use Win32 qw( MB_ICONQUESTION );
print MB_ICONQUESTION;
Win32::MsgBox( "world", 4 | MB_ICONQUESTION , "hello" );
Or
use strict;
use warnings;
use Win32 qw( MB_ICONQUESTION );
print MB_ICONQUESTION;
Win32::MsgBox( "world", MB_ICONQUESTION | 4 , "hello" );
Produce the same result.
This is because of precence when invoking subroutines without brackets - you can do:
print "one", "two";
And both are treated as arguments to print. Perl assumes that arguments after a sub are to be passed to it.
+4 is enumerated as an argument, and passed to T.
sub test { print #_,"\n";};
test 1;
test +1;
If we deparse this, we see perl treats it as:
test 1;
test 1;
So ultimately - there is a bug in Win32 that you have found, that would be fixable by:
sub MB_ICONQUESTION() {0x00000020}
Win32::MsgBox "world", 4 + MB_ICONQUESTION, "hello";
Win32::MsgBox "world", MB_ICONQUESTION + 4, "hello";
Or perhaps:
use constant MB_ICONQUESTION => 0x00000020;
Or as noted - the workaround in your code - don't use + and instead use | which is going to have the same result for bit flag operations, but because of operator precedence is never going to be passed into the subroutine. (Or of course, always specify the parenthesis for your constants)

What is the role of the BEGIN block in Perl?

I know that the BEGIN block is compiled and executed before the main body of a Perl program. If you're not sure of that just try running the command perl -cw over this:
#!/ms/dist/perl5/bin/perl5.8
use strict;
use warnings;
BEGIN {
print "Hello from the BEGIN block\n";
}
END {
print "Hello from the END block\n";
}
I have been taught that early compilation and execution of a BEGIN block lets a programmer ensure that any needed resources are available before the main program is executed.
And so I have been using BEGIN blocks to make sure that things like DB connections have been established and are available for use by the main program. Similarly, I use END blocks to ensure that all resources are closed, deleted, terminated, etc. before the program terminates.
After a discussion this morning, I am wondering if this the wrong way to look at BEGIN and END blocks.
What is the intended role of a BEGIN block in Perl?
Update 1: Just found out why the DBI connect didn't work. After being given this little Perl program:
use strict;
use warnings;
my $x = 12;
BEGIN {
$x = 14;
}
print "$x\n";
when executed it prints 12.
Update 2: Thanks to Eric Strom's comment below this new version makes it clearer:
use strict;
use warnings;
my $x = 12;
my $y;
BEGIN {
$x = 14;
print "x => $x\n";
$y = 16;
print "y => $y\n";
}
print "x => $x\n";
print "y => $y\n";
and the output is
x => 14
y => 16
x => 12
y => 16
Once again, thanks Eric!
While BEGIN and END blocks can be used as you describe, the typical usage is to make changes that affect the subsequent compilation.
For example, the use Module qw/a b c/; statement actually means:
BEGIN {
require Module;
Module->import(qw/a b c/);
}
similarly, the subroutine declaration sub name {...} is actually:
BEGIN {
*name = sub {...};
}
Since these blocks are run at compile time, all lines that are compiled after a block has run will use the new definitions that the BEGIN blocks made. This is how you can call subroutines without parenthesis, or how various modules "change the way the world works".
END blocks can be used to clean up changes that the BEGIN blocks have made but it is more common to use objects with a DESTROY method.
If the state that you are trying to clean up is a DBI connection, doing that in an END block is fine. I would not create the connection in a BEGIN block though for several reasons. Usually there is no need for the connection to be available at compile time. Performing actions like connecting to a database at compile time will drastically slow down any editor you use that has syntax checking (because that runs perl -c).
Have you tried swapping out the BEGIN{} block for an INIT{} block? That's the standard approach for things like modperl which use the "compile-once, run-many" model, as you need to initialize things anew on each separate run, not just once during the compile.
But I have to ask why it's all in special block anyway. Why don't you just make some sort of prepare_db_connection() function, and then call it as you need to when the program starts up?
Something that won't work in a BEGIN{} will also have the same problem if it's main-line code in a module file that gets used. That's another possible reason to use an INIT{} block.
I've also seen deadly-embrace problems of mutual recursion that have to be unravelled using something like an require instead of use, or an INIT{} instead of a BEGIN{}. But that's pretty rare.
Consider this program:
% cat sto-INIT-eg
#!/usr/bin/perl -l
print " PRINT: main running";
die " DIE: main dying\n";
die "DIE XXX /* NOTREACHED */";
END { print "1st END: done running" }
CHECK { print "1st CHECK: done compiling" }
INIT { print "1st INIT: started running" }
END { print "2nd END: done running" }
BEGIN { print "1st BEGIN: still compiling" }
INIT { print "2nd INIT: started running" }
BEGIN { print "2nd BEGIN: still compiling" }
CHECK { print "2nd CHECK: done compiling" }
END { print "3rd END: done running" }
When compiled only, it produces:
% perl -c sto-INIT-eg
1st BEGIN: still compiling
2nd BEGIN: still compiling
2nd CHECK: done compiling
1st CHECK: done compiling
sto-INIT-eg syntax OK
While when compiled and executed, it produces this:
% perl sto-INIT-eg
1st BEGIN: still compiling
2nd BEGIN: still compiling
2nd CHECK: done compiling
1st CHECK: done compiling
1st INIT: started running
2nd INIT: started running
PRINT: main running
DIE: main dying
3rd END: done running
2nd END: done running
1st END: done running
And the shell reports an exit of 255, per the die.
You should be able to arrange to have the connection happen when you need it to, even if a BEGIN{} proves too early.
Hm, just remembered. There's no chance you're doing something with DATA in a BEGIN{}, is there? That's not set up till the interpreter runs; it's not open to the compiler.
While the other answers are true, I find it also worth to mention the use of BEGIN and END blocks when using the -n or -p switches to Perl.
From http://perldoc.perl.org/perlmod.html
When you use the -n and -p switches to Perl, BEGIN and END work just as they do in awk, as a degenerate case.
For those unfamiliar with the -n switch, it tells Perl to wrap the program with:
while (<>) {
... # your program goes here
}
http://perldoc.perl.org/perlrun.html#Command-Switches if you're interested about more specific information about Perl switches.
As an example to demonstrate the use of BEGIN with the -n switch, this Perl one-liner enumerates the lines of the ls command:
ls | perl -ne 'BEGIN{$i = 1} print "$i: $_"; $i += 1;'
In this case, the BEGIN-block is used to initiate the variable $i by setting it to 1 before processing the lines of ls. This example will output something like:
1: foo.txt
2: bar.txt
3: program.pl
4: config.xml

How can I monitor the Perl call stack?

I'm using ActivePerl 5.8 on Windows XP.
use strict;
use warnings;
use Data::Dumper;
There are three subroutines used in my script.
To detect the call stack, I can only insert some print "some location"; and check the print result from console Window.
Is there any good method to monitor it? Thank you.
If it's your code, you might want to use:
Carp::cluck( "And here's the stack:" );
See Carp::cluck. It prints out a warning with a stack trace. It works like the "printf" style of debug output.
Use the debugger's T command.
Example:
$ perl -d -e'
sub foo {}
sub bar { foo; }
bar;
'
Loading DB routines from perl5db.pl version 1.32
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(-e:4): bar;
DB<1> s
main::bar(-e:3): sub bar { foo; }
DB<1> s
main::foo(-e:2): sub foo {}
DB<1> T
. = main::foo() called from -e line 3
. = main::bar() called from -e line 4
DB<1> s
Debugged program terminated. Use q to quit or R to restart,
use o inhibit_exit to avoid stopping after program termination,
h q, h R or h o to get additional info.
DB<1> q
You weren't specific about why you'd like to monitor the call stack and trace your subs, so answers will have to be broad.
One method is caller:
caller
Returns the context of the current subroutine call. In scalar context, returns the caller's package name if there is a caller, that is, if we're in a subroutine or eval or require, and the undefined value otherwise. In list context, returns
# 0 1 2
($package, $filename, $line) = caller;
With EXPR, it returns some extra information that the debugger uses to print a stack trace. The value of EXPR indicates how many call frames to go back before the current one.
# 0 1 2 3 4
($package, $filename, $line, $subroutine, $hasargs,
# 5 6 7 8 9 10
$wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash)
= caller($i);
You might also use the Devel::Cover module:
Code coverage data are collected using a pluggable runops function which counts how many times each op is executed. These data are then mapped back to reality using the B compiler modules. There is also a statement profiling facility which needs a better backend to be really useful.
The more you tell us about what you want to do, the more helpful to you our answers will be!
You rarely need to directly manage the call stack in Perl. If you do caller is the tool you want. However, it is only rarely needed.
More often, I want to see a stack trace when I am debugging. Good news, its easy to get a stack trace, simply use Carp's confess and cluck functions instead of die and warn.
use strict;
use warnings;
use Carp;
bar(6.1);
bar(1);
sub foo {
confess "Oh noes" unless #_ == 6; # confess is fatal
}
sub bar {
my $count = shift;
cluck "bar is in trouble" unless int $count == $count; # cluck is not fatal
foo( ('a')x $count );
}
This gets you:
dao:~ toad$ perl test.pl
bar is in trouble at test.pl line 14
main::bar(6.1) called at test.pl line 5
Oh noes at test.pl line 9
main::foo('a') called at test.pl line 15
main::bar(1) called at test.pl line 6