在perl中,我们如何检测外部命令中的分段错误

Uno*_*nos 7 perl

以下是注定要崩溃的C代码:

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

int main() {
    char *p = NULL;
    printf("Value at P: %c\n", *p);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我编译并运行它(RH4机器与gcc 4.5.2)时,它可预测地给出了一个分段错误:

%  ./a.out
Segmentation fault

%  echo $status
139
Run Code Online (Sandbox Code Playgroud)

如果我使用Perl v5.8.5运行它,会发生这种情况:

%  perl -e 'system("./a.out") and die "Status: $?"'
Status: 11 at -e line 1.
Run Code Online (Sandbox Code Playgroud)

perlvar的文件$?说,

因此,子进程的退出值确实是($?>> 8 ),并$? & 127提供进程死亡的信号(如果有的话),并$? & 128 报告是否存在核心转储.

11 >> 8是的0,11 & 127是的11.

为什么不同的退出状态?如果我们不能依赖退出状态,那么在外部命令中检测分段错误的方法应该是什么?

cho*_*oba 13

阅读文档system可能会回答您的问题:

system('a.out');

if ($? == -1) {
    print "failed to execute: $!\n";
}
elsif ($? & 127) {
    printf "child died with signal %d, %s coredump\n",
        ($? & 127),  ($? & 128) ? 'with' : 'without';
}
else {
    printf "child exited with value %d\n", $? >> 8;
}
Run Code Online (Sandbox Code Playgroud)

输出:

child died with signal 11, without coredump
Run Code Online (Sandbox Code Playgroud)

shell只是以不同的方式对状态中的信号进行编码:139 - 128 = 11.例如,man bash说:

简单命令的返回值是其退出状态,如果命令由信号n终止,则返回128 + n.