bootjpのメモ帳

https://bootjp.me で書くほどではないことを

Linuxで親プロセスが子プロセスが死んだことを知らずにpidが再利用されたら?

なぜ調べたか(どういう観点から調べる必要があったか)

知り合いに thread と process の違いを解説していた際に、親プロセスはどのようにして子プロセスを識別しているのかという話になった。 これは親プロセスが子プロセスを生成したあとに、子プロセスがクラッシュし、別のプロセスが当初の子プロセスのPIDを引き継いだ場合に識別できるのか? という質問があった PIDが短時間で重複するとは考えにくいが、デーモンとして長期間動くような場合に考えられない動作ではないため、どのようにして子プロセスと認識しているのかを調べる

どこを調べたか

調べた結果得られた答えはなんだったのか

  • 結論として、意図せず子プロセスの pid が再利用されることは通常の実装であればありえない
  • これを理解するためにはまず、親プロセスと子プロセスの挙動について知る必要がある
    • 親プロセスは通常、forkによって子プロセスを生成する場合 waitpid や wait で子プロセスの状況を待つ必要がある
    • ゾンビプロセスとして動き続けるため、pidが別のプロセスによってしようされることはない
  • waitpid したあと WIFEXITED や WIFSIGNALEDによって終了を検出することができ、子プロセスの終了を適切にハンドリングしていれば、pidが別のプロセスによって再利用される前にハンドリングできる
  • 親プロセスがwait, waitpid をする前死んだ場合は孤児プロセスとして、Systemd環境下ではsystemd --userの子プロセスとなる
    • 検証コード: https://github.com/bootjp/playground/blob/main/pid_test/orphan.c
    • webによくある記事としては init, systemdに回収されたあと子プロセスにkillをしても死なないとあるが、以下の環境ではkillで死ぬことが確認できた
    • uname -a
      • Linux manjaro 5.9.16-1-MANJARO #1 SMP PREEMPT Mon Dec 21 22:00:46 UTC 2020 x86_64 GNU/Linux
    • systemctl --version
      • systemd 247 (247.6-1.0-manjaro)
      • +PAM +AUDIT -SELINUX -IMA -APPARMOR +SMACK -SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +ZSTD +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid

関連する技術はどういうものか

  • fork(2)
  • waitpid
  • プロセス
  • プロセステーブル
  • プロセスグループ
  • systemd
  • init

他に読んだほうがいいものはなにか