ダンプリスト解析入門④
ダンプリスト解析入門④:ABENDの原因を調べる②
レジスターセーブエリア・トレース
プログラムが1つのモジュール(CSECT)しか持たない場合や、複数のモジュールで構成されていても動的構造プログラム(プログラムを構成するモジュールが1つ1つ独立したロードモジュール・メンバーでLOADあるいはLINKマクロによってローディングされる)では、どのモジュールでABENDしたのかが徴候(SYMPTOM)ダンプにその名前が表示されます。これは、JCL EXECステートメントのPGMパラメーターで指定されたモジュールや、LOADあるいはLINKなどスーパーバイザー経由でローディングされたモジュールについては、OSがローディング・アドレスとモジュールの長さを管理しているからです。
しかし、単純構造プログラムで複数のCSECTモジュールがリンケージエディターで結合されている場合、OSは結合されたモジュール全体は認識できますが、その中の個々のCSECTまでは管理しないので、ABENDした場合、徴候ダンプに表示されるモジュール名は結合されたモジュール名(例えばEXEC PGM=に指定した名前)になり、その中のどれかのモジュールでABENDしたけど、それがどのモジュールなのかはOSにはわからないよ。となります。
このような場合、ABENDした具体的なモジュール名(CSECT名)を特定するには、リンケージエディターのリストからプログラムを構成する各々のCSECTの結合されたモジュール内におけるオフセット位置と徴候ダンプが示すオフセット位置を照らし合わせる方法があります。リンケージエディターのリストが保存されていない場合は、AMBLISTユーティリティーのLISTLOAD機能でCSECTマップを出力し、それを参照できます。
SYSTEM COMPLETION CODE=0C4 REASON CODE=00000010 TIME=11.44.20 SEQ=00018 CPU=0000 ASID=0016 PSW AT TIME OF ERROR 078D0000 80007B02 ILC 4 INTC 10 ACTIVE LOAD MODULE ADDRESS=000078D8 OFFSET=0000022A NAME=TEMPNAM0 ~~~~~~~~ DATA AT PSW 00007AFC - D00C0B0E 07005810 10004800 GR 0: FD000008 1: 11111111 2: 22222222 3: 33333333 : 徴候ダンプではABENDしたプログラム・モジュールのローディング・アドレスはx78D8で PSWが示すアドレスx7B02は、ローディング・アドレスの先頭からx22A離れた位置にある ことがわかる。 *** M O D U L E M A P *** --------------- CLASS B_TEXT LENGTH = 20728 ATTRIBUTES = CAT, LOAD, RMODE= 24 OFFSET = 0 IN SEGMENT 001 ALIGN = DBLWORD --------------- SECTION CLASS ------- SOURCE -------- OFFSET OFFSET NAME TYPE LENGTH DDNAME SEQ MEMBER 0 MAINENTR CSECT 194 SYSLIN 01 **NULL** 198 SUBPGM01 * CSECT 590 SYSLIB 01 SUBPGM01 : リンケージエディターのリストと照らし合わせると、最初のMAINENTRは長さ194なので、 ABENDオフセットx22Aの範囲外。2番目のSUBPGM01がオフセット位置x198から始まっている。 x22A-x198でx92、これはSUBPGM01の長さx590の範囲に収まっているから、ABENDした箇所は CSECT SUBPGM01のオフセット位置x92となる。
ダンプリストだけで調査する場合は、レジスターセーブエリア・トレース(SAトレース)を参照する方法があります。
SYSTEM COMPLETION CODE=0C4 REASON CODE=00000010 TIME=11.44.20 SEQ=00018 CPU=0000 ASID=0016 PSW AT TIME OF ERROR 078D0000 80007B02 ILC 4 INTC 10 ACTIVE LOAD MODULE ADDRESS=000078D8 OFFSET=0000022A NAME=TEMPNAM0 ~~~~~~~~ DATA AT PSW 00007AFC - D00C0B0E 07005810 10004800 GR 0: FD000008 1: 11111111 2: 22222222 3: 33333333 : ダンプリストのレジスターセーブエリア・トレース表示部 SAVE AREA TRACE PROCEEDING FORWARD FROM TCBFSA NAME=TEMPNAM0 WAS ENTERED VIA LINK SA 00006F60 WD1 00000000 HSA 00000000 LSA 800078E8 RET 80FC8308 … R1 00006FF8 R2 00000040 R3 009D29D4 R4 009D29B0 … R7 FD000000 R8 009EC610 R9 009ECAE8 R10 00000000 … NAME=TEMPNAM0 WAS ENTERED VIA CALL SA 000078E8 WD1 FFFFFFFF HSA 00006F60 LSA 00007A70 RET 80007972 … R1 11111111 R2 22222222 R3 33333333 R4 44444444 … R7 77777777 R8 88888888 R9 99999999 R10 AAAAAAAA … NAME=UNKNOWN WAS ENTERED VIA CALL SA 00007A70 WD1 47F0F052 HSA 800078E8 LSA FFFFFFFF RET FFFFFFFF … R1 FFFFFFFF R2 FFFFFFFF R3 FFFFFFFF R4 FFFFFFFF … R7 FFFFFFFF R8 FFFFFFFF R9 FFFFFFFF R10 FFFFFFFF … INTERRUPT AT 80007B02 <=== ABEND発生アドレス PROCEEDING BACK VIA REG 13 <=== ABEND時のGR13が示すレジスター退避領域の内容 SA 00007A70 WD1 47F0F052 HSA 800078E8-+ LSA FFFFFFFF RET FFFFFFFF … R1 FFFFFFFF R2 FFFFFFFF I R3 FFFFFFFF R4 FFFFFFFF … R7 FFFFFFFF R8 FFFFFFFF I R9 FFFFFFFF R10 FFFFFFFF … NAME=TEMPNAM0 I WAS ENTERED VIA CALL I +---------------------------------+ V SA 000078E8 WD1 FFFFFFFF HSA 00006F60 LSA 00007A70 RET 80007972 EPA 00007A70 … R1 11111111 R2 22222222 R3 33333333 R4 44444444 R5 55555555 … R7 77777777 R8 88888888 R9 99999999 R10 AAAAAAAA R11 BBBBBBBB … ここがABENDしたモジュールを呼び出したモジュール側のレジスター退避領域の内容 EPAがABENDしたモジュールの入口点アドレス。(GPR退避領域の+16バイトの1ワード) RETが呼び出し側モジュールへの戻りアドレス。(GPR退避領域の+12バイトの1ワード) ABENDしたアドレスはx7B02なので、そこからEPAのx7A70を引くとx92、ABENDした箇所は 入口点x7A70からのモジュール(CSECT)のオフセット位置x92となる。
複数のCSECTモジュールを静的にリンクしたプログラム・モジュールでも、リンケージエディターやAMBLISTのCSECTマップ、ダンプリストのSAVE AREA TRACEなどからABENDしたCSECTモジュールやそれを呼び出したモジュールを特定することができます。ABENDしたモジュールがわかれば、後はレジスターとメモリーの内容から原因を調査していきます。