前書き:ログを残さないデーモンと出会った

DBにアクセスするデーモンプロセスが、稀にSegmentation  Faultでお亡くなりになる現象に遭遇しました。

このデーモンプロセスは、C言語で書かれており、デバッグ情報をログファイルに殆ど出力していませんでした。多くの情報は標準出力に出力されていたため、デバッグするにはデーモンプロセスの標準出力を確認する必要がありました(もしくは、GDBを使う)。

読者の皆さんは、ログ出力の設計に関して思う所があるかも知れません。

背景情報ですが、このデーモンは20年以上前から殆ど修正されていません。動作環境も古く、systemdが登場する前のOSです。設計見直し(リファクタリング)が行われない原因は、2020年現在でもそこそこ問題なく動いている事ではないかと考えています。

私は上記のような起動済みプロセスの標準出力を確認する方法を知らなかったため、その調査結果を本記事で示します。

[the_ad id=“598”]

PIDから標準出力を確認

Linuxは、/proc/$PID以下に実行中プロセスの情報を集めています。この中にはファイルディスクリプタの情報があるため、標準出力のファイルディスクリプタ(下表)を参照すれば、実行中プロセスの標準出力を確認できます。

ファイルディスクリプタ番号種別
0標準入力(stdin)
1標準出力(stdout)
2標準エラー(stderr)

プロセスのID(PID)は、psコマンドで確認できます。psコマンドの実行結果から「PID」と「COMMAND」欄を確認し、自分が調査したいプロセスのPIDを特定します。

$ ps -aux 
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.1  0.0 170476 11292 ?        Rs    7月01   6:01 /sbin/init
root         2  0.0  0.0      0     0 ?        S     7月01   0:00 [kthreadd]
(省略)

PIDが判明したら、以下のコマンドで実行中プロセスの標準出力を確認します。

$ cat /proc/$PID/fd/1    (注釈) $PIDは調査したいプロセスのPIDに置き換える。

(注釈) Ctrl+C(中断)しない限り、標準出力が表示され続ける。

標準出力をTerminalに表示させながら、ファイルに残したい場合は以下のコマンドを実行します。

$ cat /proc/$PID/fd/1 | tee stdin.log