我在Windows XP上使用ActivePerl 5.8。
use strict;
use warnings;
use Data::Dumper;
我的脚本中使用了三个子程序。
要检测调用堆栈,我只能插入一些print "some location";
并从控制台窗口检查打印结果。
有什么好方法可以监控它吗?谢谢。
答案 0 :(得分:10)
如果是你的代码,你可能想要使用:
Carp::cluck( "And here's the stack:" );
见Carp::cluck
。它打印出带有堆栈跟踪的警告。它的工作方式类似于“printf”样式的调试输出。
答案 1 :(得分:9)
使用调试器的T
命令。
示例:
$ 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
答案 2 :(得分:5)
您没有具体说明为什么要监控调用堆栈并跟踪您的潜艇,因此答案必须广泛。
一种方法是caller
:
呼叫者
返回当前子例程调用的上下文。在标量上下文中,如果存在调用者,则返回调用者的包名称,即,如果我们处于子例程或eval或require中,则返回未定义的值。在列表上下文中,返回
# 0 1 2 ($package, $filename, $line) = caller;
使用EXPR,它返回调试器用于打印堆栈跟踪的一些额外信息。 EXPR的值表示在当前呼叫帧之前返回的呼叫帧数。
# 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);
您也可以使用Devel::Cover模块:
使用可插入的runops函数收集代码覆盖率数据,该函数计算每个op执行的次数。然后使用B编译器模块将这些数据映射回现实。还有一个语句分析工具,需要更好的后端才能真正有用。
您告诉我们您想要做的事情越多,我们的答案就越有帮助!
答案 3 :(得分:0)
您很少需要在Perl中直接管理调用堆栈。如果您caller
是您想要的工具。但是,它很少需要。
更常见的是,我想在调试时看到堆栈跟踪。好消息是,很容易获得堆栈跟踪,只需使用Carp的confess
和cluck
函数,而不是die
和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 );
}
这会让你:
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