Joh*_*usa 12 debugging perl compilation
我有一些在调试器外运行良好的Perl代码:
% perl somefile.pl
Run Code Online (Sandbox Code Playgroud)
但是当我在调试器中运行它时:
% perl -d somefile.pl
Run Code Online (Sandbox Code Playgroud)
它的表现不同.
有问题的文件(有几个)是大型Perl模块的测试套件的一部分(~20K代码行).测试在编译时进行了大量的设置工作并使用BEGIN块.这是一些最小的复制代码:
BEGIN
{
package MyEx;
sub new { bless {}, shift }
package main;
eval { die MyEx->new };
if($@)
{
die "Really die" unless($@->isa('MyEx'));
}
}
print "OK\n";
Run Code Online (Sandbox Code Playgroud)
如果你把它放入somefile.pl并运行它,它按预期打印"OK".如果你在调试器中运行它perl -d somefile.pl,它就会因为这个错误而死掉:
Can't call method "isa" without a package or object reference ...
Run Code Online (Sandbox Code Playgroud)
结果是$@代码在调试器下运行时不是对象.相反,它是一个包含此字符串的未标记的标量:
" at somefile.pl line 9
eval {...} called at somefile.pl line 9
main::BEGIN() called at somefile.pl line 16
eval {...} called at somefile.pl line 16
"
Run Code Online (Sandbox Code Playgroud)
(保留内部换行符和间距.这是文字文本,甚至是"......".)
我需要这样的代码在调试器中运行.在测试套件中使用调试器是我工作流程的重要部分.该模块使用异常对象并在编译时执行大量操作,并期望在捕获时将对象抛出为对象.
我的问题(最后)是:我怎样才能使这个工作?有解决方法吗?这是perl调试器模块中的错误吗?解决问题的最佳方法是什么?(我知道这几个问题,但它们都是相关的.)
我在Mac OS X 10.5.5上使用perl 5.10.0.
Adam Bellaire建议的dieLevel看起来很有希望,而且确实有些东西(不知道是什么)让我为它设置为1.但我使用~/.perldb文件将其设置为0 ,问题仍然存在.实际上,我将所有三个相关设置都设置为0.我的~/.perldb文件:
parse_options('dieLevel=0 warnLevel=0 signalLevel=0');
Run Code Online (Sandbox Code Playgroud)
我通过o在调试器中运行命令确认设置有效.我看到它们在运行时perl -de 0以及运行实际somefile.pl文件时都设置为0 .
谢谢,布莱恩.我曾经perlbug提交过一个错误(RT 60890),我已经开始local $SIG{'__DIE__'}在代码中的所有适当位置撒上.(我也在bug中注意到,perldoc perldebug似乎仍暗示默认dieLevel值为0.)
bri*_*foy 14
这是perl5db.pl创建__DIE__处理程序的问题.如果我本地化$SIG{__DIE__},你的eval工作就像你期望的那样.
eval {
local $SIG{__DIE__};
die MyEx->new
};
如果你不这样做,你将从DB :: dbdie获得处理程序,它使用Carp :: longmess.如果dieLevel为0,则不会发生这种情况,但默认情况下为1,如果未定义,则设置为1.这是2001年perl5db.pl的补丁,之前的默认值为0.
你应该把它关掉:
PERLDB_OPT="dieLevel=0" perl5.10.0 -d program
Run Code Online (Sandbox Code Playgroud)
但是之后仍然有一个代码引用$SIG{__DIE__},它是对dbdie的引用.我认为这是处理$prevdieperl5db.pl中的全局变量的一个错误dieLevel.在该子程序结束时,有:
# perl5db.pl dieLevel, around line 7777
elsif ($prevdie) {
$SIG{__DIE__} = $prevdie;
print $OUT "Default die handler restored.\n";
}
但请注意,在恢复之后$SIG{__DIE__},它会保留之前的值$prevdie,这意味着其中的任何内容泄漏到另一个调用.当我运行该命令行时,在处理之前有两次调用dieLevel PERLDB_OPT,因此$prevdie可能很脏.
所以,就我所知,我不想再考虑perl5db.pl了.
我认为任何时候代码在调试器中的行为都不同,这是一个错误.
您的问题可能与此有关:调试程序破坏了符号表的重置.从本质上讲,调试器似乎可以起到一些作用local- 可能是作为沙盒事物的一部分来提供交互性.显然,弄乱符号表会产生意想不到的副作用.我猜测调试器是本地化的$@,因此模糊了你的对象.我无法想到一个解决方法.
| 归档时间: |
|
| 查看次数: |
1636 次 |
| 最近记录: |