8

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

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

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

当我编译并运行它(使用 gcc 4.5.2 的 RH4 机器)时,它可以预见地给出了分段错误:

%  ./a.out
Segmentation fault

%  echo $status
139

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

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

perlvar文档$?说_

因此,子进程的退出值是真的($?>> 8 ),并$? & 127给出进程死于哪个信号(如果有),并$? & 128 报告是否存在核心转储。

11 >> 80,并且11 & 12711

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

4

2 回答 2

14

阅读文档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;
}

输出:

child died with signal 11, without coredump

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

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

于 2013-08-20T10:42:46.707 回答
3

操作系统总是看到相同的东西...... wait(2) 系列函数返回的内容。系统(3)等。全部,调用wait(2)。它如何使您感到不安是造成差异的原因。shell 和程序做不同的事情并报告不同的方式。必须向右移动 8 才能获得最常见的退出状态,这在 shell 程序中会非常烦人,并且会让不太懂技术的用户感到困惑。

虽然我使用的第一个 UNIX 系统(正版 Unix)具有相同的返回,但我一直想知道预发布版本是否不同,返回信号和核心/转储是后来添加的。

我首选的退出状态报告往往让计算机为我分拆我的位。

   我的 $x = $?; #保存状态
   print("退出状态:%d.%d%s\n",
              $x>>8, $x​​&127, ($x&128)?"*":"");
于 2013-08-20T10:54:33.307 回答