【入門編】CEE3DMPによるダンプ出力の制御とフォーマット指定 – PL/Iの基本構文とデータ制御実践ガイド

こんにちは!メインフレームの世界へようこそ。
JavaやCOBOLといったモダン、あるいはビジネスの現場でおなじみの言語を経験されてきた方にとって、IBMメインフレームの「PL/I(ピーエルワン)」や、そこに立ちはだかる「異常終了(ABEND)のダンプ」という壁は、なんだか黒魔術のように難解で冷たく感じられるかもしれません。

「夜間バッチが突如として落ちた」「『CEE3DMP』という見慣れないルーチンから出力された謎の分厚い紙(あるいはログファイル)、これはいったいどこを見ればいいの……?」

そんな不安を抱えていませんか? 大丈夫です、怖くありませんよ。一つずつ構造を紐解いていけば、ダンプはあなたを責め立てる敵ではなく、「プログラムがどこでどう苦しかったのか」を克明に語ってくれる優秀なカルテに早変わりします。

今回は、PL/Iプログラムが異常終了した際に強力な味方となる「CEE3DMP(シィーイーイー・スリー・ディー・エム・ピー)」の使いこなし方と、その読み解きのコツを、初心者の方にも分かりやすくお伝えしていきますね。

1. そもそもPL/Iの変数名って?(ちょこっと基礎知識)

本題に入る前に、JavaやCOBOLから来た人が驚くPL/Iのユニークなルールに少しだけ触れておきましょう。

PL/Iには、COBOLのように「あらかじめ厳格に予約されたキーワード(RESERVED WORDS)」の数が非常に少ないという特徴があります。例えば、`IF` や `DO` といった制御構文の名前であっても、文脈によっては変数名(識別子)として使えてしまうという、懐の深さ(あるいはカオスさ)を持っています。

そのため、PL/Iのソースコードを読むときは、変数名が独自のセンスで命名されていることが多く、デバッグ時に「この変数はいったい何を保持しているんだっけ?」と迷うことがよくあります。だからこそ、後述するダンプ出力(CEE3DMP)で「メモリ上の実態を直接覗き見るスキル」が非常に重要になってくるのです。

2. 異常終了の救世主「CEE3DMP」とは?

プログラムが予期せぬエラー(ゼロ除算やポインタ違いなど)で「U4038」や「S0C7」といったシステムABENDを起こしたとき、ただ処理がプツリと途切れるだけでは、原因究明に途方に暮れてしまいますよね。

そこで登場するのが、IBMの共通ランタイム環境(Language Environment:LE)が提供するサービス`CEE3DMP`です。
これを使用すると、プログラムが力尽きたその瞬間の「スタックトレース(呼び出し履歴)」「変数の中身(ストレージ)」を、ファイルやSYSOUTにきれいに出力させることができます。

コードでの呼び出し方イメージ

PL/Iのソースコード内でエラーをトラップした際や、意図的にダンプを残したい箇所で、以下のように記述します。

1
/ —————————————————————- /
/ CEE3DMP サンプル呼び出しプログラム /
/ —————————————————————- /
DEMO: PROC OPTIONS(MAIN);

DCL 01 W_FEEDBACK, / 結果を受け取るフィードバック・コード /
05 W_FB_SEVERITY FIXED BIN(15),
05 W_FB_MSG_NO FIXED BIN(15),
05 W_FB_FLAGS BIT(32),
05 W_FB_IC FIXED BIN(32);

DCL CEE3DMP ENTRY(
CHAR() VARYING, / ダンプ・タイトル /
CHAR() VARYING, / オプション指定 /
POINTER / フィードバック・コード /
) LINKAGE(OPLLINK);

/ 何らかの異常を検知したと仮定してダンプを要求 /
CALL CEE3DMP(
‘【業務エラー】月次集計処理で異常を検知しました’,
‘BLOCKS’, / 全ストレージとブロック情報を出力 /
W_FEEDBACK
);

IF W_FB_SEVERITY > 0 THEN
PUT SKIP LIST(‘ダンプ出力中に何らかの警告が発生しました’);

END DEMO;

ここでポイントなのが、第2引数に指定するオプション文字列です。代表的なものをいくつか見てみましょう。

  • `TRACE` : どこからどこへルーチンが呼び出されたか(スタックトレース)を出力します。まずは全体像を知りたいときに。
  • `STORAGE` : プログラムが使っていたメモリ領域をダンプします。
  • `BLOCKS` : `STORAGE` よりもさらに詳細に、制御ブロックや変数の詳細情報を出力します。実務の調査では大体これか、デフォルトを指定することが多いです。

3. 分厚いダンプのどこを見る?効率的な読み解き方

実際にCEE3DMPが出力したレポート(あるいはSYSOUT)を開くと、英語の羅列に圧倒されるかもしれません。「わっ、なんだこれ……」と思っても、見るべきポイントは決まっています。

① 最初に見るべきは「スタックトレース(Traceback)」

ダンプの中盤あたりに、以下のようなテーブル形式のセクションがあります。

————————————————————————-
Traceback:
Entry Stmt Offset Load Module CU_Name Command
CEEHDSP +0000 MYPROG MYPROG _CEE_Condition_Token
CALC_TAX 42 +01A2 MYPROG MYPROG
MAINRTN 15 +005C MYPROG MYPROG
————————————————————————-

ここを上から順に追っていくと、「`MAINRTN`(メイン処理)の15行目から `CALC_TAX`(税額計算ルーチン)の42行目が呼び出され、その内部で何かが起きてエラー(CEEHDSP)に至ったんだな」という足取りが手に取るように分かります。
「どのルーチンの、何行目で息絶えたのか」が分かれば、ソースコードの該当箇所へ一瞬でたどり着けますよね。

② 変数の内容を暴く「Formatted Dump」セクション

「何行目で止まったかは分かったけれど、そのとき変数に何が入っていたの?」という疑問に答えてくれるのが、変数の値が並ぶセクションです。

PL/Iのデータ属性(`FIXED BINARY` や `CHARACTER` など)に合わせて、変数名と、そのときの1進数・16進数の値がズラリと表示されます。

ここで、他言語からの初心者が最もハマりやすい罠に注意してください。
それは、メインフレーム特有の「ゾーン十進数(DISPLAY属性)」や「パック十進数(DECIMAL FIXED属性)」といったデータ型です。Javaの `int` や `String` の感覚で見ていると、ダンプ上に表示される謎のバイト列(例えば `0C` や `F1F2` など)の意味がチンプンカンプンになってしまいます。

  • 文字データ (`CHAR`) ならそのまま読めます。
  • 数値データ (`FIXED DEC`) なら、パッと見は文字化けしているように見えますが、実は16進数で `0-9` の数値と符号(最後の半バイト)を表しています。

もしダンプ上の変数の値がすべて `00`(ヌルバイト)になっていたら、「あ、そもそもこの変数は初期化される前に参照されて(あるいは値が落ちて)しまっているな」という推測が立ちます。このように、データの「不在」や「ゴミ(パディング)」からバグの臭いを嗅ぎ取るのが、レガシーエンジニアの醍醐味です。

4. まとめ:怖がらずに「対話」しよう

PL/IのCEE3DMPによるダンプ出力は、一見すると無機質な暗号の塊のようですが、プログラムの軌跡を記録した非常に温かみのある履歴書です。

1. まずは `TRACE` で「どこで死んだか(行番号)」を確認する。
2. 次に変数の値(ストレージ)を見て、「どんなおかしなデータを握りしめていたか」を確認する。

この2ステップを落ち着いて踏むだけで、どんなに古いレガシーシステムのエラーであっても、必ず解決の糸口が見えてきます。

「メインフレームだから」「PL/Iだから」といって身構える必要はまったくありません。エラーという名のメッセージに耳を傾け、ぜひ一歩ずつ、コードの迷宮をクリアしていってくださいね。あなたのシステム運用の旅を、心から応援しています!

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