IBM Z Japan - Group home

#082【z/OS V2R5変更点】 「LOWCORE」(PSA)レイアウト変更に伴うプログラム不具合の顕在化

  

従来、ASMプログラムをコーディングする際、意図した初期化が行われていないレジスターを利用した結果、仮想記憶域上の「LOWCORE」(PSA)を間違って参照する可能性があります。
その場合、たまたま、「LOWCORE」の内容がプログラム・ロジック的に好ましい値を示していれば、表面上は何ら不具合が起きているようには見えないので、プログラムの潜在バグが顕在化することなく放置されてしまいます。
※以前、「z/Architecture」モードへの移行時、「LOWCORE」(PSA)の先頭1バイトが「x'04'」(ESA/390)から「x'00'」(z/Architecture)に変わり、潜在バグを含むプログラムの挙動変化が報告されました

【z/OS V2R5の変更点】
■z/OS V2R5では、「LOWCORE」(PSA)のレイアウトが変更され、「0番地」から先頭の16バイトは「バイナリー・ゼロ」を示すようになりました。(同様な変更は、それ以外のフィールドでも発生しました)
(例) PSA先頭4バイトの比較
(z/OS V2R4まで)    x'000A0000'
(z/OS V2R5)        x'00000000'
■「Data Area」マニュアルを参照すると、例えば、PSAの先頭16バイトは「プログラミング・インターフェース」として定義されておらず、z/OS V2R5での変更点としては明記されていません。
■実機での確認結果(IBM z14サーバー)
※IPCS 6: LIST (PSAO) STRUCTURE(PSA)コマンド

【「LOWCORE」(PSA)レイアウト変更に伴う影響】 ※潜在バグが顕在化するプログラム例
■例えば、次のような「CLC」命令では、「ベース・レジスター(3)」、「変位(0)」、「長さ(4)」から求められた主記憶の内容を、「VALUE0」(バイナリー・ゼロ)と比較します。

■この場合、「ベース・レジスター(3)」への初期値ロード有無に応じて、プログラムの挙動が大きく変わります。

■「LOWCORE2」プログラムでは、意図せず「LOWCORE」(PSA)の先頭4バイトが「バイナリー・ゼロ」よりも大きいことを確認しているため、z/OS V2R5では、その内容が、x'000A0000'からx'00000000'に変更されたことに伴い、従来のような処理結果がもはや得られません。
※z/OS V2R3では、「LOWCORE2」プログラムの潜在バグが顕在化せず

【SLIP PER 「Zero Address Detection (ZAD)」トラップ】
■SLIP PER 「ZAD」トラップ(z/OS V2R1新機能)は、「IBM z196」、「IBM z114」以降のサーバーを対象とし、未初期化(初期化漏れなど)のレジスター(中身は「ゼロ」)により生成されたオペランド・アドレスを使用してストレージ・アクセスしたジョブ名、プログラム名、及び命令を検知することが可能です。
※意図せず「LOWCORE」(PSA)を参照しているプログラム・エラーの洗い出しに効果的
■SLIP PER 「ZAD」トラップ利用時の考慮事項
・本番環境ではなく、テスト環境でのみ使用することを想定しています。ただし、z/OSがVM下で稼働する場合には利用できません。

・意図した挙動として、IBM提供モジュールを検知する場合も十分あり得ますが、あくまでお客様プログラムの洗い出しを行う目的で利用ください。
・IBM提供モジュールによる意図した「ZAD」イベントが多数発生し、顕著なシステム・オーバーヘッドを伴う場合があります。

【SLIP PER 「ZAD」トラップを利用した「LOWCORE」アクセスの検知例】(z/OS V2R4環境)
■前述の「LOWCORE2」プログラムを検知するための利用手順例(①~⑨)

⑥SYSPRINT確認例(STC IEAVTSZR)

■SLIP PER 「ZAD」トラップを利用した結果、「LOWCORE」アクセスが検知された場合、z/OS V2R5移行有無によらず、対象プログラムの確認と必要な対応が推奨されます。
How to generate and read a z/OS SLIP Zero Address Detection (ZAD) Report

【考慮事項】
■例えば、次のような「CLC」命令では、「ベース・レジスター(3)」、「変位(0)」、「長さ(4)」から求められた主記憶の内容を、「VALUE0」(x'00000000')と比較します。

■意図的かどうかによらず、この「ベース・レジスター」指定を省略した場合、「ベース・レジスター(0)」(中身は「ゼロ」)が暗黙的に使用されます。

■このように「ベース・レジスター」指定がない場合、ASM処理を行う際に「FLAG(PAGE0)」オプションを明示指定すると、次のようなワーニング・メッセージ ASMA309Wが出力されます。
※省略時値は「FLAG(NOPAGE0)」オプションのため、ワーニング・メッセージを出力せず

■ただし、「ベース・レジスター(0)」(中身は「ゼロ」)が暗黙的に使用された結果、「LOWCORE」を参照しているような場合は、前述の「ZAD」イベントとして検知されません。

 

【追加情報: 2023/12/26】

SLIP PER ZAD」トラップを利用した「LOWCORE」アクセスの検知は限定的であり、網羅性の観点から課題が残ります。

①非本番環境、かつ、パフォーマンスに配慮した上で、実際に稼働したジョブのみが洗い出し対象

➁IEAVTSZRプロシージャー起動時の「SIZE=」パラメータ(nK/nnK/nnnK/nM/nnM/nnnM)で指定された大きさの「テーブル」(情報格納エリア)がフルになると、それ以降のデータ・キャプチャー処理は停止

■プロシージャー起動時に「STATS=YES」パラメータを指定すると、「テーブル」の使用状況がSYSPRINTに表示されます。(使用済エントリー数とスペース使用率)

※「SIZE=1K」指定時の表示例  ➡       Used Entries:            30 ( 64%)

※スペース不足による「ロスト・イベント」発生時はメッセージ出力 ・・・ IEAVTSZR Some event(s) were not captured. Data area too small

■上記のような考察を踏まえ、z/OS V2R5以降への移行時に顕在化する可能性があるプログラム不具合を漏れなく事前に検知、洗い出すことは困難と考えられます。

※移行時、テスト時に想定外のプログラム挙動に遭遇した際、問題判別を助けるヒントとして既知情報を活用するのが推奨

以上