% perl somefile.pl
但是当我在调试器中运行它时:
% perl -d somefile.pl
它的行为有所不同.
所讨论的文件(有几个)是大型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";
如果你把它放在somefile.pl并运行它,它会按预期打印“OK”.如果使用perl -d somefile.pl在调试器中运行它,则会导致此错误:
Can't call method "isa" without a package or object reference ...
结果是,当代码在调试器下运行时,$@不是一个对象.相反,它是一个包含这个字符串的无耻标量:
" 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 "
(内部换行符和间距保留,这是字面文字,甚至是“…”).
我需要这样的代码在调试器中运行.在测试套件中使用调试器是我的工作流程的重要组成部分.该模块使用异常对象,并在编译时执行大量的内容,并期望被捕获时抛出的对象成为一个对象.
我的问题(最后)是这样的:我该如何让这个工作?有解决方法吗?这是perl调试器模块中的错误吗?什么是最好的方式来解决这个问题? (我知道这几个问题,但都是相关的.)
我在Mac OS X 10.5.5上使用perl 5.10.0.
Adam Bellaire建议的死亡事件看起来很有希望,事实上(找不到什么)将它设置为1.但是我使用〜/ .perldb文件将其设置为0,问题仍然存在.其实我把所有三个相关设置都设置为0.我的〜/ .perldb文件:
parse_options('dieLevel=0 warnLevel=0 signalLevel=0');
我通过在调试器中运行o命令来确认设置有效.当我运行perl -de 0和运行实际的somefile.pl文件时,我看到它们都设置为0.
谢谢你,布莱恩.我使用perlbug来提交一个错误(RT 60890),我已经开始在我的代码中的所有适当的地方洒上本地$SIG {‘__ DIE__’}. (我也注意到,perldoc perldebug的错误似乎暗示默认的dieLevel是0)
解决方法
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
但是,在$SIG {__ DIE__}之后还有一个代码引用,它是dbdie的引用.我认为这是处理perl5db.pl的dieLevel中全局变量$prevdie的错误.在子程序结束时,有:
# perl5db.pl dieLevel,around line 7777 elsif ($prevdie) { $SIG{__DIE__} = $prevdie; print $OUT "Default die handler restored.\n"; }
但是请注意,在恢复$SIG {__ DIE__}之后,它将先前的值保持在$prevdie中,这意味着泄漏到另一个调用中的任何内容.当我运行该命令行时,在处理PERLDB_OPT之前,有两次对dieLevel的调用,所以$prevdie可能很脏.
所以,就我以前我不想再考虑perl5db.pl了.