【実務・中級編】コンパイルオプションOFFSETによるダンプ解析の効率化 – PL/Iの基本構文とデータ制御実践ガイド

「OFFSET」を使いこなせ:PL/I障害解析の現場で生き残るためのダンプ読み解き術

現場の若手エンジニアから、「CEE3DMPが出たのですが、どこで落ちたのかさっぱり分かりません」という相談をよく受ける。画面にずらりと並ぶ16進数の羅列を見て眩暈がするのは誰しも同じだ。だが、メインフレームのトラブルシューティングにおいて、ダンプは「嘘をつかない唯一の証言者」である。

今日は、PL/I開発者が必ず習得すべき、コンパイルオプション `OFFSET` を活用した障害特定テクニックについて話をしよう。

なぜ「OFFSET」が必要なのか

PL/Iのコンパイルオプションで `LIST` や `MAP` も便利だが、本番環境のバッチ処理でいざ異常終了(ABEND)した際に、最も頼りになるのが `OFFSET` だ。

これを指定すると、コンパイルリストの最後に「Statement Table」が出力される。これにより、ロードモジュール上のオフセット値(メモリアドレス上の位置)と、ソースコード上の行番号が1対1で対応付けられるようになる。これがないと、ダンプから「落ちた場所」を特定するのに、機械語レベルの逆アセンブル解析を強いられることになる。時間は貴重だ。そんな無駄な苦労は今日で終わりにしよう。

実践的なコード例とデバッグの準備

まずは、VSAMファイルを読み込み、計算処理を行って結果を書き出すという、よくあるバッチ処理の構造を見てほしい。

TEST_PROG: PROC OPTIONS(MAIN);
/———————————————————–/
/ VSAMアクセスと演算処理を含む標準的なバッチ構造 /
/———————————————————–/

DCL INPUT_FILE FILE RECORD INPUT ENV(VSAM);
DCL OUTPUT_FILE FILE RECORD OUTPUT ENV(VSAM);

DCL 1 REC_IN,
5 KEY_ID CHAR(10),
5 VAL FIXED BIN(31);

DCL VAL_SUM FIXED BIN(31) INIT(0);

/ ONユニットによる例外制御 /
ON ENDFILE(INPUT_FILE) BEGIN;
PUT SKIP LIST(‘処理正常終了: 合計値は’, VAL_SUM);
STOP;
END;

ON ERROR BEGIN;
PUT SKIP LIST(‘予期せぬエラー発生’);
CALL CEE3DMP(‘ErrDump’, ‘BLOCKS’, ‘DEBUG’);
STOP;
END;

/ メイン処理ループ /
DO WHILE(‘1’B);
READ FILE(INPUT_FILE) INTO(REC_IN);

/ ここで仮に0除算等の例外が発生すると仮定 /
VAL_SUM = VAL_SUM + (100 / REC_IN.VAL); / 行番号を意識する箇所 /

WRITE FILE(OUTPUT_FILE) FROM(REC_IN);
END;

END TEST_PROG;

ダンプから発生箇所を特定するステップ

もし上記のプログラムが `VAL_SUM` の行でABENDしたとする。CEE3DMPを出力させると、ダンプの冒頭に `Exception occurred` という記述とともに、Instruction Address(命令アドレス)が記載されているはずだ。

手順1:オフセット値の抽出

ダンプ内の「Program Unit」セクションを確認し、発生時の `Instruction Address` から、ロードモジュールの開始アドレスを引く。これで「モジュール先頭からの相対オフセット」が出る。

手順2:コンパイルリストとの照合

ここで `OFFSET` オプションで出力されたコンパイルリストの出番だ。リストの最後にある `Statement Table` を開き、算出したオフセット値を探す。

  • OFFSET : 0000A4
  • STMT : 24

この表があれば、瞬時に「ソースコードの24行目で落ちた」と特定できる。

エンジニアとしてのアドバイス:ここが現場の知恵だ

1. コンパイルオプションはケチるな:
「コンパイルリストが大きくなるから」といって `OFFSET` を外す現場があるが、断固として反対する。障害発生時に調査に掛かる工数を考えれば、リストの数KBなど微々たるものだ。
2. ONユニットの過信は禁物:
`ON ERROR` で `CEE3DMP` を呼ぶのは定石だが、無限ループには注意しろ。エラー処理の中でエラーが起きると目も当てられない。`SIGNAL` を使ったテストコードで、ダンプが意図した通りに出るか事前に確認しておくのがプロの仕事だ。
3. BUILTIN関数の活用:
今回の例では `FIXED BIN` を使ったが、数値計算時は `DIVIDE` 関数などを使用して、オーバーフローやゼロ除算を未然に防ぐコーディングを心掛けること。ダンプ解析はあくまで「最後の手段」であるべきだ。

最後に

メインフレームのコードは、時に数十年もの歴史を背負っている。君が今触っているそのコードも、誰かの血と汗の結晶かもしれない。だからこそ、障害が起きたときに「なぜ落ちたのか」を論理的かつ迅速に突き止めるスキルは、君を唯一無二のエンジニアにする。

`OFFSET` オプションは、ただのツールではない。君がコードと対話するための「翻訳機」だ。次の改修時、ぜひ忘れずにオプションを追加してくれ。健闘を祈る。

タイトルとURLをコピーしました