ダンプリスト解析入門⑩

By 神居 - Posted: 2013/03/27 Last updated: 2013/03/27 - Leave a Comment

ダンプリスト解析入門⑩:プログラム割込みによるABENDダンプ解析サンプル

シリーズの最後に、簡単なプログラムを使ってABENDダンプの解析を行ってみます。アセンブラー・プログラムで起こりがちなS0C4 ABEND(記憶保護例外)です。故意にプログラムで0番地などに書き込むのは現実的ではないので、実践でもありがちな例を使ってみます。
サンプル・プログラムの内容は、STCK命令で得たCPUの現時刻をYYYYMMDD HHMMSS形式に変換するものです。実際の変換にはMVSのAPIサービスであるCONVSTCKマクロを使用します。


サンプル・プログラムのABENDによるダンプリスト(SYSUDUMP)とプログラムのアセンブル結果


ダンプとアセンブル・リストからエラーの箇所を見つける

まずはダンプリストからABEND時のPSWとレジスターの内容を確認します。徴候ダンプを見るのが早くて簡単です。

PSWが示すABENDアドレスはx7FD6、プログラムのペースアドレスはX7F18であることがわかります。x7FD6はプログラムの先頭からのオフセットxBEの位置です。PSWは次の命令を指すので、実際にABENDしたのは1つ前の命令です。ILC(命令長)が示す値を引くとxB8がABENDした命令の位置です。アセンブル・リストからこれがMVC命令であることがわかります。
この命令はGR1が示すアドレスのオフセット12の位置のメモリーの内容をGR14が示すアドレスにコピーするものです。

GR1とGR14の内容を確認すると、GR1はプログラム内で問題なさそうですが、GR14には6が入っています。つまりアドレス6番地に書き込もうとしています。そのため記憶保護例外S0C4 ABENDとなったようです。
では何故コピー先のアドレスを示すGR14に6などという誤った値が入ったのかを引き続き追求します。そのためにはアセンブル・リストでこの命令よりさらに前の命令列を確認します。

アセンブル・リストを見ると、オフセットxB4のLAE命令でR6というラベルのアドレスがGR14にセットされています。ラベル名R6?って何でしょうか。実はここはマクロ命令による展開命令列です。実際に自分でソース・プログラム上に書いた命令ではありません。マクロ命令による展開命令列かどうかは命令の左側の通し番号の直後に+マークの有無でわかります。このABENDで問題となっているLAE命令にもMVC命令にも+マークが付いているのでマクロ命令による展開命令列であることがわかります。命令列をリスト上で上方向にさかのぼれば展開したマクロ命令がわかります。これはプログラマーがソース・プログラム上に書いたものです。

問題となっている命令列を展開したのはSTCKCONVマクロであることがわかります。一見すると問題なさそうですが、パラメーターをよく見てみると、CONVVALパラメーターに値として「R6」が指定されています。これがLAE命令でのラベル名R6に関係があるようです。
STCKCONVマクロの直前でGR6にEDITAREAのアドレスをロードしていますから、CONVVALパラメーターではGR6に格納されたアドレスの領域を指定したものですが、値の表記が誤っているため、マクロ内でR6をレジスター番号ではなくラベル名として処理されてしまったものです。正しくは次のようにマクロ命令を書かなければなりません。

マクロ命令ではパラメーターの値にレジスターの内容を指定する場合は、レジスター番号を()でくくって記述するのが一般的です。この事は各マクロのマニュアルでも明記されています。ソース・プログラムだけを追っているとわかりにくいバグの例でもあります。
正しく記述されたSTCKCONVマクロの展開は次のようになります。

エラーの原因となったLAE命令では、R6ではなく0(0,R6)の表記に変わり、6番地ではなくレジスター6番の内容をベースにしたアドレスがGR14にロードされることになり、プログラムは意図した通りに正しく実行されます。


サンプル・プログラムのソースコード

Posted in ダンプ解析入門 • • Top Of Page