ダンプ・リスト解析入門 ④:ABENDの原因を調べる②

レジスター・セーブエリア・トレース

異常終了時の徴候ダンプにはエラーを起こしたモジュール名が表示されます。JCL EXECステートメントのPGMパラメーターで指定されたモジュールやLOADあるいはLINKなど、スーパーバイザー経由でローディングされたモジュールについてはOSがローディング・アドレスとモジュールの長さを管理しているからです。プログラムが1つのセクション(CSECT)しか持たない場合や、複数のセクションで構成されていても各々のセクションが独立したロード・モジュールになっている動的構造プログラム(*1)であれば、徴候ダンプに表示されたモジュールが示すセクションでABENDしたことがわかります。
しかし、単純構造プログラムで複数のセクション(CSECT)がバインダーで結合されている場合、OSは結合されたモジュール全体は認識できますが、その中の個々のセクション(CSECT)までは管理しないので、ABEND時の徴候ダンプに表示されるモジュール名は結合されたモジュール名(*2)になります。その中のどれかのモジュールでABENDしたけれど、それがどのモジュールなのかはOSにはわかりません。
このような場合、ABENDした具体的なセクション(CSECT名)を特定するには、バインダーのリストによってプログラムを構成する各々のセクションのモジュール内におけるオフセット位置と徴候ダンプが示すオフセット位置を照らし合わせます。バインダーのリストが保存されていない場合は、AMBLISTユーティリティーのLISTLOAD機能でCSECTマップを出力しそれを参照します。

*1 プログラムを構成するモジュールが1つ1つ独立したロードモジュール・メンバーで、LOADあるいはLINKマクロによってローディングされる。
*2 例えば、EXECステートメントのPGMパラメーターに指定した名前。

徴候ダンプから、ABENDしたプログラム・モジュールのローディング・アドレスはx78D8で、PSWが示すアドレスx7B02はローディング・アドレスの先頭からx22A離れた位置にあることがわかる。

バインダーのリストと照らし合わせると、最初のMAINENTRは長さ194なのでABENDオフセットx22Aの範囲外。2番目のSUBPGM01がオフセット位置x198から始まっている。x22A-x198でx92、これはSUBPGM01の長さx590の範囲に収まっているから、ABENDした箇所はCSECT SUBPGM01のオフセット位置x92となる。

ダンプ・リストだけで調査する場合は、レジスター・セーブエリア・トレース(SAトレース)を参照する方法があります。

SA(保管域)アドレス000078E8の箇所が、ABENDしたモジュールを呼び出したセクションまたはモジュール側のレジスター退避領域の内容。EPAはABENDしたモジュールの入口点アドレス(GPR退避領域の+16バイトの1ワード)。RETは呼び出し側モジュールへの戻りアドレス(GPR退避領域の+12バイトの1ワード)。ABENDしたアドレスはx7B02なのでそこからEPAのx7A70を引くとx92、ABENDした箇所は入口点x7A70からのセクションまたはモジュールのオフセット位置x92となる。

複数のモジュールを静的にリンクしたプログラム・モジュールでも、バインダーやAMBLISTのCSECTマップ、ダンプ・リストのSAVE AREA TRACEなどからABENDしたセクション(CSECT)やそれを呼び出したモジュールを特定することができます。ABENDしたセクションやモジュールがわかれば、後はレジスターとメモリーの内容から原因を調査していきます。