メインフレームの闇を照らす:LENGTHとSTGで動的メモリの「素顔」を暴く
現場の諸君、今日もVSAMのレコードと格闘しているか?
大規模なバッチ改修や、レガシーシステムのマイグレーションで一番怖いのは何だと思う? データベースのデッドロック? それとも終わらないソート処理か? いや、もっと恐ろしいのは「メモリの境界線を見失った時に発生する、原因不明の異常終了(ABEND)」だ。
PL/Iは強力だ。だが、その自由度の高さゆえに、動的に割り当てられた領域のサイズや、VARYING属性を持つ文字列の長さを見誤ると、途端にシステムは牙を剥く。今日は、そんな現場のトラブルシューティングにおいて「救世主」となる、`LENGTH`関数と`STG`(Storage)関数について、実務的な視点で深掘りしよう。
—
1. なぜ今、動的メモリの把握が重要なのか
現代のメインフレーム環境でも、可変長レコード(VB)や動的割付(ALLOCATE)は至るところで使われている。特に、外部インターフェースのデータ構造が変わるたび、COBOLから移行された古いPL/Iコードを読み解く必要があるだろう。
「この変数、今のランタイムで一体どれくらいのメモリを食っているんだ?」
そんな時、デバッガを立ち上げる前に、まずはコード内でこっそりと情報を吐き出させるのが、百戦錬磨のベテランのやり方だ。
—
2. LENGTH関数:文字列の「今」を知る
`LENGTH`関数は、単に文字列の長さを返すだけではない。VARYING属性が付いた文字列において、現在の「有効な長さ」を正確に教えてくれる。
実践コード:可変長データの安全な取り扱い
1
/ 可変長文字列を扱う際の安全確認 /
DCL MSG_BUFFER CHAR(200) VARYING;
DCL CURR_LEN FIXED BIN(15);
/ 何らかの処理でバッファにデータが入る /
MSG_BUFFER = ‘TRANSACTION_ID:12345’;
/ 現在の有効な長さを取得 /
CURR_LEN = LENGTH(MSG_BUFFER);
/ 境界値チェックの例 /
IF CURR_LEN > 100 THEN DO;
PUT SKIP LIST(‘警告: バッファの安全領域を超過しています。長さ:’ || CURR_LEN);
/ 必要に応じたエラールーチンへ /
END;
ここでのポイントは、`LENGTH`が返す値が「宣言値」ではなく「現在格納されているデータ長」であるという点だ。これを怠って固定長の変数に代入しようとすれば、容赦なくTRUNCATION(切り捨て)が発生し、データ整合性が崩れる。
—
3. STG関数:メモリの「足跡」を追跡する
`STG`(あるいは`STORAGE`)関数は、変数がメモリ上で占有している「物理的なサイズ」をバイト単位で返す。構造体(STRUCTURE)のパディングや、アライメントを含めた実態を知るのに最適だ。
特に、VSAM入出力用のコピーブック(INCLUDEメンバー)が複雑に重なり合っている場合、`STG`で期待通りのサイズになっているかを確認するだけで、ポインタ操作のミスを未然に防げる。
実践コード:構造体サイズの動的検証
1
DCL 1 WORK_RECORD,
3 HEADER CHAR(10),
3 BODY CHAR(50),
3 FOOTER CHAR(5);
DCL MEM_SIZE FIXED BIN(31);
/ 構造体そのもののサイズを取得 /
MEM_SIZE = STG(WORK_RECORD);
/ デバッグ用にサイズをSYSPRINTへ出力 /
PUT SKIP LIST(‘WORK_RECORDのメモリ占有サイズは ‘ || MEM_SIZE || ‘ バイトです’);
/ もし特定のアライメントを期待するならここでチェック /
IF MEM_SIZE ^= 65 THEN
PUT SKIP LIST(‘設計上のサイズと一致しません。構造定義を見直してください’);
—
4. 現場で生き残るためのデバッグ戦略
これらの関数は、単体で使うよりも`ON CONDITION`や`ON ERROR`と組み合わせることで、真価を発揮する。
もしシステムが異常終了しそうなクリティカルな処理があるなら、以下のように組み込んでみてほしい。
- 異常検知時のダンプ出力: `ON ERROR`ユニット内で`LENGTH`や`STG`を使い、当時の変数の状態をログに残す。
- 境界値のガード: VSAMの書き込み直前に`LENGTH`をチェックし、制限値を超える場合は即座に例外を投げてプロセスを停止させる。
ベテランからのアドバイス
「動くからいいや」で済ませていると、半年後の改修で必ず泣きを見る。特にPL/Iの`VARYING`変数は、内部的に2バイトの長さ情報領域を持っている。`STG`を叩いてみて、予期せぬサイズになっていないかを確認する癖をつけておくこと。これが、バグを未然に防ぎ、コードの寿命を延ばす唯一の道だ。
—
まとめ
1. `LENGTH`は「データの実効長」を確認するために使い、データ損失を防げ。
2. `STG`は「メモリ上の物理サイズ」を把握し、構造体操作の整合性を保て。
3. 大文字記述とインデントの徹底は、未来の自分への礼儀だと思え。
メインフレームのコードは、書いた人間の「思考の跡」そのものだ。美しく、かつ強固なロジックを組むことで、我々エンジニアはシステムに命を吹き込んでいる。
次は、ONユニットを使ったより高度な例外制御について話そう。まずは手元のコードで`STG`関数を試してみろ。今まで見えていなかったメモリの構造が見えてくるはずだ。健闘を祈る。
