読者です 読者をやめる 読者になる 読者になる

Perl - 子プロセスの終了ステータスの調べ方

# sample.pl

system @ARGV;

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;
}

perldoc の system をみていたら、子プロセスの終了ステータスが入っている $? はまず -1 がどうかチェックしないといけなかったらしい。

例えば、上記のプログラムを perl sample.pl aaaaa のようにして実行すると、コマンドaaaaaの実行そのものに失敗するので system は -1 を返し、$? にも -1 をセットする。 もしこれを $? >> 8 とかして exit value だと思うと、72057594037927935 とかいうわけのわからないものになる。

それと coredump は必ず何かしらの signal があったときにしか起きないので $? & 128 を $? & 127 と別に調べなくていいらしい。また $? & 128 が true のとき $? >> 8 に、もはや exit value の意味はない。

正直 coredump する状況にあまりなったことがないので、coredumpさせてみる。 segmentation fault する

int main() {
    char* a = 0;
    char  b = *a;
}

を作って、ulimit -c unlimited した後、perl sample.pl ./a.out すると

% perl sample.pl ./a.out
child died with signal 11, with coredump

のようになった。