Perl这个语言没有现成的运行时调试工具,网上罗列的办法有:
- strace只能看系统调用的函数,而且是perl解释器执行的流程。
- gdb,只能调试perl解释器。
- gdbperl,bulkdbg,没有用过。
- perl-stacktrace,inspect-perl-proc两款在我们的虚拟化平台都没能正确运行。
13年的时候,写过一个运行时给Perl注入Enbugger库,使其能调试的脚本,为运行时调试而生。今天想查看某些阻塞进程究竟在做啥,于是加一个新技能,打印运行时的Perl脚本堆栈,是Perl脚本堆栈,不是Perl解释器堆栈。
注意:如果Perl处于阻塞状态,是无法interrupt的,例如下面进程处于等待锁状态,无法插入代码:
|
|
处于加锁等待,不返回无法注入代码。
具体效果
此工具支持两个功能,先看帮助:
功能1:运行时attach Perl进程进行调试
调试时,需要先执行perld –l命令监听一个端口,例如:
然后执行perl -c 将需要attach的进程attach到监听端口。
再切换到刚才的监听界面,已经可以调试了:
这个调试界面和Perl -d类似,唯一的差距是不能识别退格键,上下键。
功能2:打印Perl脚本堆栈
这个功能是新加入的,例如执行:
会将所有vtpdaemon进程的堆栈打印到日志文件。
你也可以用PID方式:
上图可以看出,vptdaemon在调用accept。
比用strace跟踪好太多,用于定位性能问题非常有效。
源码
perld
|
|
rtinject
perld里面调用了rtinject,这个脚本是很早以前写的,用于运行时注入代码。
rtinject也可以单独运行,我之前写的clog日志库,就提供了运行时调整level的功能,主要就是用这个原理:
|
|