segmentation faultした際の出力

今日遭遇して「あれ?」と思ったんだけど、プログラムがsegmentation fault起こした際、シェルのリダイレクトがどう振る舞うのかというお話。

まず、以下のように標準出力(以下stdout)と標準エラー出力(以下stderr)に文字列を出力するCプログラムがある。

/* seg.c */
#include <stdio.h>
int main (int argc, char *argv[]) {
  fprintf(stdout, "std\n");
  fprintf(stderr, "err\n");
  return 0;
}

これを実行してみる。

$ gcc -std=c99 seg.c
$ ./a.out
std
err
$

なんてことはない。次にこのプログラムの実行結果を/dev/nullにリダイレクトしてみる。

$ ./a.out > /dev/null 
err
$

stdoutに出力していた方だけ表示されなくなる。stderrに出力していた方も表示されなくするには以下のようにしてstderrをstdoutにリダイレクトする。

$ ./a.out > /dev/null 2>&1
$

で、次にわざとsegmentation faultを起こすようなプログラムを書いてみる。

/* seg.c */
#include <stdio.h>
int main (int argc, char *argv[]) {
  fprintf(stdout, "std\n");
  fprintf(stderr, "err\n");
  int *n;
  *n = 5;
  return 0;
}

これを実行すると、

$ gcc -std=c99 seg.c
$ ./a.out
std
err
zsh: segmentation fault  ./a.out
$

当然、segmentation faultを引き起こす。これを/dev/nullにリダイレクトしてみる。

$ ./a.out > /dev/null
err
zsh: segmentation fault  ./a.out > /dev/null
$

さっきと同じようにstdoutに出力していた方だけ表示されなくなる。続いてstderrをstdoutにリダイレクトすると、

$ ./a.out > /dev/null 2>&1
zsh: segmentation fault  ./a.out > /dev/null 2>&1
$ 

という具合にsegmentation faultの表示だけ残ることになる。

この場合、「zsh: segmentation fault ./a.out > /dev/null 2>&1」っていうのはどこに出力されているんだろう?(もしくはシェル的にどういう処理しているんだろう?。それともなんか壮大な勘違いをしている?)