物理サーバーでコアダンプを収集し、解析経路を検証する

物理サーバーでコアダンプを収集し、解析経路を検証する

物理サーバーでコアダンプを収集し、解析経路を検証する

業務プロセスが突然終了した場合、サービスを再起動すれば稼働は復旧できますが、クラッシュの原因はわかりません。ログにシグナル番号しか残っていなければ、原因の特定にはクラッシュ時のコールスタックと対応するビルドが必要です。本記事では Ubuntu Server 24.04 で制御されたコアダンプ収集経路を構築し、まず隔離したプロセスで動作を検証してから、業務サービスで有効にするかを判断します。

AMDSSH の物理サーバーでは 128GB または 256GB の ECC メモリを選択できますが、サーバー全体の容量を基準に、プロセスのダンプを無条件で保存すべきではありません。core ファイルにはパスワード、リクエスト本文、業務データが含まれる可能性があります。収集対象、容量制限、アクセス権限はまとめて設定する必要があります。

1. クラッシュの種類と既存の収集機構を確認する

支払い後、コントロールパネルで接続情報を確認し、SSH でログインします。以下の操作には管理者権限が必要です。テスト前に、システム、ディスクの空き容量、コアダンプの処理先を確認してください。

cat /etc/os-release
df -h /var/lib
sysctl kernel.core_pattern
sudo journalctl -b -p warning --no-pager

kernel.core_pattern がパイプ記号で始まっている場合、カーネルはダンプをカレントディレクトリに直接書き込まず、ユーザー空間の処理プログラムに渡します。すでに別のクラッシュ収集機構が導入されている可能性があるため、元の設定値と関連パッケージを記録してください。処理先を二重に設定して、両方が動作すると思い込んではいけません。

まず、自発的な終了、シグナルによる終了、メモリ不足によるプロセスの強制終了を区別します。通常、SIGSEGV と SIGABRT はコアダンプを生成しますが、SIGKILL は生成しません。サービスの状態に異常終了と表示されても、ダウンロード可能なファイルが生成されたとは限りません。

core dump はプロセスメモリの証拠であり、通常の実行ログではありません。公開ディレクトリに置いたり、内容を確認せずにサポートチケットやコードリポジトリへ添付したりしないでください。

本記事で使用するツールをインストールします。パッケージマネージャーが既存の収集機構の置き換えを通知した場合は、まず影響を確認し、どちらの仕組みを使うかを明確に選択してください。

sudo apt-get update
sudo apt-get install systemd-coredump gdb gcc
sysctl kernel.core_pattern
systemctl status systemd-coredump.socket --no-pager

インストール後は、処理先が systemd のダンプ処理プログラムを指していることを確認します。ソケットが受信を担当し、処理サービスは必要に応じて起動します。収集プロセスが常駐していなくても、機能が動作していないとは限りません。

2. 収集経路に容量制限を設定する

/etc/systemd/coredump.conf.d/60-controlled-capture.conf を作成し、次の設定を記述します。

[Coredump]
Storage=external
Compress=yes
ProcessSizeMax=256M
ExternalSizeMax=256M
MaxUse=512M
KeepFree=2G

これは小さなテストプロセスを検証するための容量設定であり、大量のメモリを使う業務向けの推奨値ではありません。ProcessSizeMax は処理対象となるダンプのサイズを、ExternalSizeMax は外部ファイルとして保存するサイズを制限します。上限を超えた場合、イベントのメタデータだけが残り、完全なメモリファイルは保存されないことがあります。

MaxUse と KeepFree は外部ダンプディレクトリの使用量を制御する設定です。ディスクの空き容量を予約・保証するものではなく、ログデータベースの容量も制御しません。複数のプロセスが同時にクラッシュすると空き容量が逼迫する可能性があるため、保存先ファイルシステムの空き容量も監視する必要があります。

設定は次に起動する処理プロセスが読み込みます。以下のコマンドで、設定を統合した結果を確認できます。

systemd-analyze cat-config systemd/coredump.conf

業務で有効にする前に、代表的なプロセスのメモリ使用量と実際のダンプサイズを測定し、上限を調整してください。テストプログラムで検証できたからといって、大量のメモリを使うデータベースのダンプも完全に保存できるとは限りません。

3. 隔離したサービスで実際のクラッシュを検証する

業務データを含まないテストプログラムをビルドする

/tmp/crash-lab.c に最小限のプログラムを記述します。

#include <stdlib.h>

int main(void)
{
    abort();
}

専用のシステムアカウントを作成し、コンパイルします。-g はデバッグ情報を保持し、-O0 はテスト時のコールスタックを確認しやすくします。

sudo useradd --system --no-create-home --shell /usr/sbin/nologin crashlab
sudo install -d -m 0755 /usr/local/libexec
sudo gcc -g -O0 -o /usr/local/libexec/crash-lab /tmp/crash-lab.c

アカウントがすでに存在する場合は、先にその用途を確認し、重複して作成しないでください。続いて /etc/systemd/system/crash-lab.service を作成します。

[Unit]
Description=Isolated core dump capture test

[Service]
Type=oneshot
User=crashlab
ExecStart=/usr/local/libexec/crash-lab
LimitCORE=infinity
Restart=no

ここでの infinity は、テストサービスのプロセス制限だけを解除するものです。収集機構には引き続き前節の容量制限が適用されます。すべてのサービスに適用するグローバルなデフォルト値にはしないでください。

sudo systemctl daemon-reload
sudo systemctl start crash-lab.service
sudo systemctl status crash-lab.service --no-pager
sudo coredumpctl --no-pager list /usr/local/libexec/crash-lab

起動コマンドが失敗を報告するのは想定どおりです。テスト用実行ファイルに対応するクラッシュ記録が表示されることを確認します。記録がなければ、処理先、サービスの制限、収集機構のログ、ディスクの空き容量の順に確認してください。本番プロセスにクラッシュを引き起こすシグナルを送って確認してはいけません。

4. ダンプファイルとデバッグ資料を検証する

一覧から今回のテストの PID を控え、同じ管理者シェル内で入力して、専用の非公開ディレクトリへエクスポートします。

sudo -i
read -r -p 'Crash PID: ' CRASH_PID
umask 077
install -d -m 0700 /root/crash-evidence
coredumpctl info "$CRASH_PID"
coredumpctl dump "$CRASH_PID" --output=/root/crash-evidence/test.core
gdb -q -batch \
  -ex 'set pagination off' \
  -ex 'thread apply all bt' \
  /usr/local/libexec/crash-lab /root/crash-evidence/test.core
exit

最初にイベントの時刻、実行ファイル、シグナル、保存状態を確認し、PID の再利用によって別の記録を取得しないようにします。検証結果では SIGABRT が表示され、コールスタックをテストプログラムの main に結び付けられることを確認してください。システムライブラリのスタックフレームにソースコードがなくても、テスト経路の検証には支障ありません。

メタデータしかない、ファイルをエクスポートできない、切り詰めを示すメッセージが出る、といった場合は、完全な収集に成功したとはいえません。coredumpctl でイベントを一覧表示できても、外部ファイルがまだ存在する保証はありません。

実際の業務では、クラッシュ時の実行ファイル、共有ライブラリ、対応するデバッグシンボルも保管する必要があります。更新後の同名バイナリは、元のビルドと同一ではありません。readelf -n で Build ID を確認し、パッケージのバージョンとビルド識別子を記録してください。

いきなり bt full を使ってローカル変数を出力しないでください。まず基本的なコールスタックを確認します。変数の確認が本当に必要な場合は、アクセスを制限した環境で操作し、エクスポートしたテキストを項目ごとに点検してください。バイナリをコピーする際もハッシュを保存し、解析中に資料が差し替えられていないことを確認できるようにします。

5. 業務への導入と設定撤回を確認する

業務サービスで有効にする場合は、そのサービス専用の drop-in で LimitCORE を設定し、daemon-reload を実行した後、管理された変更手順の中でサービスを再起動します。設定ファイルを変更しても、既存のプロセスに新しい制限が自動で適用されるわけではありません。実際のプロセスの /proc/PID/limits を確認してください。

導入時には、少なくとも次の四項目を確認します。

テスト終了後は、テスト用のサービスファイル、プログラム、ソースコードを削除し、daemon-reload と reset-failed を実行します。テストのダンプは coredumpctl info が示す実際のパスを基に個別に処理し、ワイルドカードでダンプディレクトリ全体を空にしないでください。

収集方針を撤回する場合は、本記事で追加した設定ファイルを削除します。元の収集機構に戻す必要がある場合は、パッケージの設定を使って復元し、kernel.core_pattern を再確認してください。記憶を頼りに処理先を組み立ててはいけません。最後に、クラッシュイベントを照会できる、ファイルをエクスポートできる、コールスタックが正しいビルドに対応している、資料へのアクセスが制限されている、という一連の検証結果を記録します。これによって残るのは、誰も検証していない設定スイッチではなく、再確認できる障害の証拠です。

よくある質問

異常終了したプロセスは必ずコアダンプを残しますか?

いいえ。通常の終了や SIGKILL では一般に生成されません。対象となるシグナルでも、プロセス制限、収集設定、サイズ制限、空き容量によって保存されない場合があります。

GDB で開ければ、そのダンプだけで解析できますか?

十分ではありません。障害時の実行ファイル、共有ライブラリ、デバッグシンボルを一致させ、ダンプが切り詰められていないことも確認する必要があります。

EPYC 7543P 専用物理サーバー月額 $450.2〜

リソースの検討からサーバー構成へ

サーバー本体とオプションは月額合計でのご請求です。構成ページで明細をご確認いただけます。接続情報は納品後、コントロールパネルで確認できます。