给定一个函数名称,我想报告调用层次结构“一直到顶部”。
例如,
# ./find.pl functionName
functionName
caller
caller2
...
callerN
在上面的输出中,我了解到 callerN 是“顶级”函数,它最终调用了“最低级”functionName 函数。
我一直在努力做到这一点,但实施总是有缺陷。它不够可靠,我对此没有信心。
有什么东西可以做到这一点吗?
谢谢
给定一个函数名称,我想报告调用层次结构“一直到顶部”。
例如,
# ./find.pl functionName
functionName
caller
caller2
...
callerN
在上面的输出中,我了解到 callerN 是“顶级”函数,它最终调用了“最低级”functionName 函数。
我一直在努力做到这一点,但实施总是有缺陷。它不够可靠,我对此没有信心。
有什么东西可以做到这一点吗?
谢谢
NYTProf是一个调试包,允许对函数调用进行非常细粒度的检查。它可以输出到 HTML 以查看详细的(运行时)配置文件。根据您的要求,查看它也可以输出的调用图可能会有所帮助。
示例代码:
#!/usr/bin/perl
use strict;
use warnings;
&say_hi;
sub say_hi {
print &hello;
}
sub hello {
return "Hello world!\n";
}
调用:
$ perl -d:NYTProf hello.pl
生成一个nytprof.out
在当前目录中调用的文件,它nytprof
可以解析:
$ nytprof nytprof.out --open
这将创建一个名为nytprof
并自动在分析结果页面上为您打开浏览器的目录。有趣的部分可能是您可以下载的图表(但它们也位于nytprof
目录中)。这些调用图按层次组织,可以深入了解程序的哪些部分调用了哪些函数。这个简单程序的调用图如下所示:
PS:图表以点文件的形式提供。要创建一个 SVG graph.dot
,比如说
$ dot -Tsvg -o graph.svg graph.dot
更多在dot
手册中。
你可以use Carp
和它的cluck
函数,它打印调用堆栈。有关更多信息,请参阅他们的文档。
use strict;
use warnings;
use Carp qw(cluck);
⫕
sub callstack {
cluck "waaah";
}
sub subsub {
&callstack;
}
输出:
$ perl /tmp/test.pl
waaah at /tmp/test.pl line 10
main::callstack called at /tmp/test.pl line 14
main::subsub called at /tmp/test.pl line 7
如果实际运行代码可行,可以使用 caller() 函数,或者封装版本的Devel::Stacktrace。
如果您依赖代码分析... Lscharf 的 PPI 和 GraphViz 的组合可能会有用。但是,不知道它是否是最新的,或者它是否捕获了无数边缘情况中的任何一种,例如上面 ikegami 提到的。