導入
現場で長年保守に携わっていると、「今動いているこのバイナリ、本当に最新のソースから生成されたものか?」と疑心暗鬼になることはありませんか?特に本番環境でのパッチ適用や、複雑なビルド手順を踏むシステムでは、ソースとロードモジュールの不一致が重大な障害を引き起こす原因となります。この課題を解決するために最もシンプルで強力なツールが、COBOLの組込関数「WHEN-COMPILED」です。
基礎知識
WHEN-COMPILEDは、その名の通り「コンパイルされた日時」を返す関数です。特筆すべきは、これが実行時の現在時刻ではなく、コンパイル時にバイナリへと固定的に埋め込まれたリテラルであるという点です。データ形式は「YYYYMMDDhhmmsscc」(ccは100分の1秒)の21文字の固定長文字列として取得できます。実行時に値を変動させないため、プログラムの「出自」を検証する指紋のような役割を果たします。
実装/解決策
実務での活用法として、プログラム起動時の初期処理において、ソース内で定義した定数バージョンと、WHEN-COMPILEDから取得した値を比較する方法を推奨します。もし不一致が発生した場合、エラーログを出力して異常終了させることで、意図しない古いバイナリの稼働を強制的に停止させることができます。
サンプルプログラム
以下のサンプルは、プログラム実行時にコンパイル日時をチェックし、一致しなければ異常終了させる実装例です。
IDENTIFICATION DIVISION.
PROGRAM-ID. VER-CHECK.
WORKING-STORAGE SECTION.
- 期待されるコンパイル日時(リリース時に更新する定数)
01 EXPECTED-COMPILE-DATE PIC X(21) VALUE “2023102710000000”.
01 CURRENT-COMPILE-DATE PIC X(21).
PROCEDURE DIVISION.
> 組込関数WHEN-COMPILEDからコンパイル日時を取得
COMPUTE CURRENT-COMPILE-DATE = FUNCTION WHEN-COMPILED.
> コンパイル日時が一致するか検証
IF CURRENT-COMPILE-DATE NOT = EXPECTED-COMPILE-DATE
DISPLAY “【重大エラー】バイナリの不整合を検知しました。”
DISPLAY “期待値: ” EXPECTED-COMPILE-DATE
DISPLAY “実際値: ” CURRENT-COMPILE-DATE
> 異常終了として処理を打ち切る
STOP RUN RETURNING 1
END-IF.
DISPLAY “バージョン検証完了:正常に稼働します。”
STOP RUN.
応用・注意点
現場での注意点として、コンパイル環境ごとのタイムゾーンや、微細なビルド時刻のズレには注意が必要です。自動ビルド環境(CI/CD)を導入している場合、ビルドのたびに日時が変わるため、この値をそのまま比較条件に使うと不一致エラーが頻発します。
その場合は、日付部分のみ(YYYYMMDD)を比較対象にするか、あるいはコンパイル日時を直接比較するのではなく、ログ出力専用として「いつコンパイルされたバイナリか」を明確にするために利用してください。障害発生時の調査において、「いつの時点のソースでビルドされたものか」が即座に判明するだけでも、復旧までのリードタイムは劇的に短縮されます。ぜひ、ログ出力機能の一部として組み込んでおくことをお勧めします。

コメント