これは、子プロセスのクローンを作成した後、ブロック解除バイトを送信する前に、親プロセスがクラッシュした場合に発生しSendContinueSignalToChild()
ます。この場合、パイプ ファイル ハンドルは開いたままになり、子はread(...)
内で無限にブロックされたままになりますWaitForContinueSignal()
。クラッシュ後、child は init プロセスによって採用されます。
再現手順:
l. で親のクラッシュをシミュレートしgoogle_breakpad::ExceptionHandler::GenerateDump(CrashContext *context)
ます:
...
const pid_t child = sys_clone(
ThreadEntry, stack, CLONE_FILES | CLONE_FS | CLONE_UNTRACED, &thread_arg, NULL, NULL, NULL);
int r, status;
// Allow the child to ptrace us
sys_prctl(PR_SET_PTRACER, child, 0, 0, 0);
int *ptr = 0;
*ptr = 42; // <------- Crash here
SendContinueSignalToChild();
...
GenerateDump(...)
上記のメソッドが呼び出されるように、処理されたシグナルの 1 つを親 (SIGSEGV など) に送信します。- 親は終了しますが、子がまだ存在し、 でブロックされていることを確認し
WaitForContinueSignal()
ます。
上記の手順の出力:
dmytro@db:~$ ./test &
[1] 25050
dmytro@db:~$ Test: started
dmytro@db:~$ ps aflxw | grep test
0 1000 25050 18923 20 0 40712 2680 - R pts/37 0:13 | | \_ ./test
0 1000 25054 18923 20 0 6136 856 pipe_w S+ pts/37 0:00 | | \_ grep --color=auto test
dmytro@db:~$ kill -11 25050
[1]+ Segmentation fault (core dumped) ./test
dmytro@db:~$ ps aflxw | grep test
0 1000 25058 18923 20 0 6136 852 pipe_w S+ pts/37 0:00 | | \_ grep --color=auto test
1 1000 25055 1687 20 0 40732 356 pipe_w S pts/37 0:00 \_ ./test
1687 は初期 pid です。
現実の世界では、シグナルを処理するスレッドと並行してクラッシュが発生します。注: この問題は、通常のプログラムの終了 (つまりexit(0)
、並列スレッドで呼び出される) によっても発生する可能性があります。
Linux 3.3.8-2.2.、mips および i686 プラットフォームでテスト済み。
だから、私の2つの質問:
- ブレイクパッドライブラリが子を生かしておくのは予想される動作ですか? 私の期待は、親がクラッシュ/終了した直後に子が終了することです。
- 予期しない動作である場合、親のクラッシュ/終了後にクライアントを終了するための最良の解決策は何ですか?
前もって感謝します!