【问题标题】:Segmentation fault disappears when running command from Perl从 Perl 运行命令时分段错误消失
【发布时间】:2018-07-17 12:10:09
【问题描述】:

我有一个引发 SIGSEGV 的简单 c++ 程序:

#include <iostream>
#include <signal.h>

int main() {
    std::cout << "Raising seg fault..." << std::endl;
    raise(SIGSEGV);
    return 0;
}

运行此程序时,我得到以下输出

Raising seg fault...
Segmentation fault

但是当我使用管道在 perl 脚本中运行我的程序时,分段错误消失了。 这是我的 Perl 脚本:

use strict;
use warnings;


my $cmd ="./test";

open (OUTPUT, "$cmd 2>&1 |") || die();
while (<OUTPUT>) {
      print;
}
close (OUTPUT);
my $exit_status = $?>>8;
print "exit status: $exit_status\n";

我在运行脚本时得到以下输出:

Raising seg fault...
exit status: 0

这怎么可能?分段错误在哪里,为什么退出状态为0?

【问题讨论】:

  • $?的低字节是什么
  • 请注意,open 调用实际上执行了一个分叉,并在单独的进程中运行您的命令。根据perlipc"... 虚假命令的读者只返回一个快速 EOF" 所以这可能是没有明显迹象表明 SIGSEGV 信号的原因
  • @Håkon Hægland,嗯,不。命令有效。您引用的段落意味着执行命令的问题可能只有close才能揭示。
  • @ikegami 谢谢,我完全错过了!你当然是对的。

标签: perl segmentation-fault child-process exit-code


【解决方案1】:

您特别忽略了$? 中指示进程是否被信号终止的部分。

替换

my $exit_status = $?>>8;
print "exit status: $exit_status\n";

die("Killed by signal ".( $? & 0x7F )."\n") if $? & 0x7F;
die("Exited with error ".( $? >> 8 )."\n") if $? >> 8;
print("Completed successfully\n");

【讨论】:

  • 那么“Segmentation fault”消息呢……为什么我看不到它?
  • 因为该消息是由 shell 生成的
  • open -| 使用与系统相同的优化:如果您传递的 shell 命令不包含非特殊字符、空格和可选的2&gt;&amp;1,则不会调用 shell。外壳是该消息的来源。随意调整"Killed by signal ".( $? &amp; 0x7F )."\n" 以产生相同的消息。
  • $previous_comment =~ s/nothing that/nothing but/
  • 顺便说一句,绕过shell这一事实是您可以获得有关进程如何退出的准确信息的原因。
猜你喜欢
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 2018-08-15
  • 1970-01-01
  • 2012-07-03
  • 1970-01-01
  • 2013-07-18
  • 1970-01-01
相关资源
最近更新 更多