【问题标题】:Making perl process to dump core instead of directly exiting from the process使perl进程转储核心而不是直接退出进程
【发布时间】:2017-03-02 09:43:52
【问题描述】:

在我的 perl 脚本(实际上作为守护进程运行)中,我不小心尝试访问一个之前未定义的数组元素(也是一个数组)。我的脚本此时正在退出,但没有转储任何核心。在这种情况下是否可以转储核心?我尝试通过 kill -6 命令杀死我的 perl 进程,在这种情况下会生成核心但是当我们从脚本中意外退出时,我想在每个实例中生成核心。

my @array = ();
my @a;
@a = @{$array[1]};

【问题讨论】:

  • 访问未定义的数组元素不会在 Perl 中退出:perl -e 'print $arr[20]; print "still here"'
  • 对我来说仍然没有错误。
  • “dump core”通常不是调试 perl 脚本的步骤之一。
  • 总能得到一些东西的一种方法是将它放在END 块中。它在每个dieexit 运行。但可能不够具体。另一种方法是在编写代码时“防止”错误——使用仔细的错误检查。然后,您可以获得非常具体的信息。或者,覆盖die,但为$SIG{__DIE__}“信号”提供一个挂钩(子程序)。例如,请参阅 this answer 以获取在十几行代码中触发任何 die 的调试器。

标签: perl signals core


【解决方案1】:

我建议您在脚本中记录消息,并在您尝试访问不存在的内容时专门进行一些检查,而不是生成核心转储或类似内容。

Using a source level debugger 在 perldoc 中的建议适用于一些罕见的情况:

如果 -D 的调试输出对您没有帮助,是时候采取措施了 通过使用源级调试器执行 perl。

我们将在此处使用 gdb 作为示例;这些原则将适用于 任何调试器(许多供应商称他们的调试器为 dbx ),但检查 您正在使用的手册。

使用ifelse 可以避免尝试访问不存在的数组的位置,例如:

my $wanted_position = 2;

if ( $wanted_position >= @array )
{

    #log a possible error
    #Do something else
}

@a = @{$array[$wanted_position]};

您也可以在脚本中处理signals

Perl 使用简单的信号处理模型:%SIG 哈希包含名称 或用户安装的信号处理程序的引用。这些处理程序将 使用参数调用,该参数是信号的名称 触发了它。一个信号可能是故意从一个 发送给您的特定键盘序列,例如 control-C 或 control-Z 来自另一个进程,或者由内核自动触发 发生特殊事件,例如退出子进程,您自己的 进程耗尽堆栈空间,或达到进程文件大小 限制。

例子:

 $SIG{DIE} = sub { #dump code here };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 2017-03-04
    • 1970-01-01
    • 2012-04-06
    相关资源
    最近更新 更多