【问题标题】:Can a Perl system() call ever die?Perl system() 调用会死掉吗?
【发布时间】:2012-10-25 10:50:24
【问题描述】:

system() 调用是否可以在 Perl 5 中使用 die

(换句话说,为了使执行system() 调用的程序100% 防崩溃,是否需要将其包装到eval 块中,或者完全完全没必要?)


我在perldoc system 中没有发现任何关于这种可能性的提及,但也没有找到确切的“这个电话永远不会消亡”。

注意:这里的问题是关于基本 CORE Perl,没有autodie 或任何其他具有类似效果的自定义模块。此外,假设没有设置 ALRM 信号,或任何其他自定义信号处理程序。

我假设 Perl 5.* 的所有版本的行为都相同,但如果不是,将不胜感激与 5.8 有关的答案。

【问题讨论】:

  • 我还没有去查看源代码,所以我没有发布这个作为答案,但如果system 没有办法耗尽内存,我会感到惊讶.
  • @Gilles - “内存不足”会导致 Perl 发出“死”而不是核心转储/崩溃?我会假设后者,但也不确定
  • @Gilles - if only we had a place where we can ask programming questions...。让我们看看 SO 智慧发现了什么。

标签: perl system eval die


【解决方案1】:

除非我对来源的解释不正确,否则这似乎是一种可能性:

来源:Perl 5.16.2(也检查了 5.8.8),文件:pp_sys.c,行:PP(pp_system) 代码块内的 4224:

if (n != sizeof(int))
  DIE(aTHX_ "panic: kid popen errno read, n=%u", n);

DIE 是在util.c 中声明的Perl_die(pTHX_ const* pat, ...)

根据文档,“panic: child popen errno read”的意思是“forked child 返回了一个关于其 errno 的难以理解的消息”。

Explanation of panic messages in Perl:

约定是当解释器死于内部 错误,消息开始“恐慌:”。从历史上看,许多恐慌信息 已经是简洁的固定字符串,这意味着超出范围的值 引发恐慌的人都丢失了。现在我们尝试报告这些值, 因为这样的恐慌可能无法重复,并且原始错误消息 当我们试图找到原因时,这可能是我们得到的唯一诊断。

【讨论】:

  • 从我对源代码的阅读来看,这只会发生在 1) 子进程执行的 exec() 失败和 2) 子进程无法通过管道。
【解决方案2】:

您可以调用system() 并期望它不会抛出异常。无需将其包装在 eval 块中。

【讨论】:

  • “满怀期待”——这有技术依据吗?如果您查看 j.w.r. 的回答,您的陈述似乎完全错误。
  • 我很想看看有多少 CPAN 模块试图捕获 system 抛出的异常。关键不是它不会发生,而是您通常可以使用system() 并期望它不会引发异常。
【解决方案3】:

system 返回程序的退出状态。这意味着,如果程序崩溃,调用 Perl 脚本会继续(参见system)。

尽管如此,程序本身仍然可以杀死调用脚本甚至使计算机崩溃。例如,在 Linux 中:

system 'killall', 'perl';
print "Alive\n";

【讨论】:

  • 请参阅我对 Brian Agnew 的评论。这不是我要问的。
【解决方案4】:

我假设您正在谈论 system 函数本身的实现,而不是通过调用调用的任何内容。 (显然,子进程不能在父进程的上下文中调用die,即使这样也假定调用的是 Perl 代码。)

明确的答案需要了解内部知识,但鉴于尝试调用不存在的程序不会死,我也无法想象其他任何事情:

system('abcd');      # 'abcd' is not recognized... [Win32 message]
say "I'm not dead."; # always prints

【讨论】:

  • “我假设您正在谈论系统函数本身的实现,而不是通过调用调用的任何内容。” - 正确
猜你喜欢
  • 2012-11-29
  • 1970-01-01
  • 1970-01-01
  • 2020-04-22
  • 2011-05-12
  • 1970-01-01
  • 1970-01-01
  • 2015-06-22
  • 1970-01-01
相关资源
最近更新 更多