exit code 137とは?解説
exit code 137は、プロセスがSIGKILLで終了させられたことを意味します。これは128 + 9であり、CIではその原因はほぼ常にout-of-memory killerです。
137で終わるstepは、その数値を返したのではありません。killされたのです。エンコーディングを理解すれば、何が起きたのか、そしてなぜ通常は読むべきスタックトレースがないのかが正確にわかり、当惑させる失敗が明快な診断に変わります。
128 + N のエンコーディング
Unixの慣例により、シグナルNで終了させられたプロセスはexit code 128 + Nを報告します。SIGKILLはシグナル9なので、128 + 9 = 137です。同じ仕組みで、SIGTERM(15)は143、SIGINT(2)は130になります。128を超えるコードはいずれも、プログラムのロジックではなくシグナルがプロセスを終わらせたことを意味します。
なぜ通常はOOMなのか
SIGKILLはキャッチ、ブロック、無視ができないため、カーネルはプロセスを即座に死なせるためにこれを予約しています。メモリに制限のあるrunnerでは、強制killの最も一般的な原因は、メモリを取り戻すout-of-memory killerです。だからこそ137は通常、「Killed」だけでトレースバックなしで届くのです。
原因を確認する
- 失敗前後のrunnerのメモリ使用量、またはoom-killの行がないかカーネルログを確認します。
- コンテナでは、終了したコンテナにOOMKilledステータスがないか探します。
- メモリが健全に見えるなら、外部のwatchdogや文字通りのkill -9を除外します。
一時的か決定論的か
buildが常にrunnerのメモリを超えるなら、137は決定論的であり、修正は機械的です。より多くのメモリか、ピーク使用量の低減です。負荷時やわずかにしか起こらないなら、新しいrunnerでのリトライがしばしばそれを解消し、一時的なものになります。
Latchkeyの視点
Latchkeyの自己修復managed runnerは、exit code 137のOOM killを機械的な失敗として扱い、自動的にリトライします。そのため一度きりのメモリの瞬断でbuildが失敗することはなく、一方で一貫して予算超過なbuildは依然としてサイズ調整のために表面化します。
重要なポイント
- exit code 137 = SIGKILLによるkill(128 + 9)。
- CIでは圧倒的にout-of-memory killerです。
- SIGKILLはトラップできないため、スタックトレースはめったにありません。
- わずかなスパイクは一時的でリトライ可能ですが、本当の不足にはより多くのメモリが必要です。