为什么Perl BEGIN块在调试器中的作用不同?

我有一些在调试器外运行良好的Perl代码
% 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)

解决方法

这是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

但是,在$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了.

相关文章

1. 如何去重 #!/usr/bin/perl use strict; my %hash; while(...
最近写了一个perl脚本,实现的功能是将表格中其中两列的数据...
表的数据字典格式如下:如果手动写MySQL建表语句,确认麻烦,...
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了...
在实际生产环境中,常常需要从后台日志中截取报文,报文的形...
最近写的一个perl程序,通过关键词匹配统计其出现的频率,让...