c++ - 如果子进程发出信号,Perl 会检测到 fork/exec 的错误退出代码

标签 c++ linux perl

我从 perl fork /执行一个 C++ 程序,并希望检测子程序的退出状态(特别是当子程序由于段错误而退出时)

根据子进程是否调用 exit(),perl 行为会不一致。 ,从外部发出信号,或者实际上遇到了段错误。

从 shell 中,C++ 的退出代码始终是正确的。例如。 echo $?与程序的行为相符。

从 perl 中,仅当 exit() 时,perl 检测到的退出代码才是正确的。被称为。如果程序由于信号或段错误而退出,则 perl 检测到的退出代码始终为 0。

为什么?

我想在perl脚本中一致地获取C++程序的退出代码。

perl 5.10.1、Centos 6 32 位、g++ 4.8.2

测试结果

  • 实际段错误(boom已启用):Perl Complete: 27322 exited (exit 0, sig 11, core 0)
  • a.out 通过 kill -11 <pid> 被杀死:Perl Complete: 27248 exited (exit 0, sig 11, core 0)
  • a.out 完成,调用 exit(139) :Perl Complete: 27237 exited (exit 139, sig 0, core 0)

调用a.out在上述所有三种情况下,从 shell 始终显示正确的退出代码。

C++ A.OUT

(根据测试注释掉boom)

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>

int
main(int argc, char  **argv)
{
    printf("Started with PID %d\n", getpid());

    int d = 1;
    if (argc > 1)
        d = atoi(argv[1]);

    int loops = 10;
    while(loops-- > 0)
    {
        printf("Ping\n");
        sleep(1);
    }

    printf("MAKE SEGFAULT\n");
    int boom = *(int*)0x00;

    printf("exit with %d\n", d);
    exit(d);
}

PERL

#!/usr/bin/perl

use POSIX ":sys_wait_h";

my $fullprocname = "./a.out 139";
my $childPID = fork();

if ($childPID == 0)        # child
{
    open(STDERR, ">&SAVEERR");  # restore stderr
    $< = $>;                    # set real to effective uid, otherwise
                                # some env variables not passed in ??
    exec ($fullprocname) or die "exec $fullprocname failed: $!\n"; 
}
else                       # parent
{
    print("DVMon.pl: Forked $childPID for $fullprocname\n");
}

print("Waiting for child process\n");
my $child = wait();

my $exitStatus = $? >> 8;   # similar to WEXITSTATUS
my $termSig    = $? & 127;  # similar to WTERMSIG
my $coreDump   = $? & 128;  # similar to WCOREDUMP

my $msg = "$childPID exited (exit $exitStatus, sig $termSig, core $coreDump)";
print("Perl Complete: $msg\n");

最佳答案

这正在按设计工作。在 shell 中,有两种方法可以从命令中获取退出代码 139。

  1. 该命令使系统调用exit(139)
  2. 命令以信号 11 终止

但是 POSIX-y 系统可以区分这两个事件,并且 Perl Hook 这些方法以使其 $? 变量比 shell 提供的信息更丰富。

关于c++ - 如果子进程发出信号,Perl 会检测到 fork/exec 的错误退出代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45610409/

相关文章:

c++ - GNU 通用公共(public)许可证错误?

linux - 如何使用代理和 STUN 服务器设置 Asterisk SIP 注册?

c - Linux shell 不执行我的 c 程序

perl - 如何使用 mod_perl 导出只读变量?

Perl 函数/子最佳实践

java - 将 XML 或 HTML 转换为 Wiki 标记 - 您会选择什么方法?

c++ - 为命令行实用程序寻找任何好的(和免费的)跨平台 CLI 解析库

c++ - 使用 Qt 测试本地连接

c++ - QTextEdit中的 "selection"和 "cursor"有什么区别?

python - Linux下的流量整形