«

ダンプリスト解析入門(番外編①)

By 神居 - Posted: 2011/10/18 Last updated: 2011/10/18 - Leave a Comment

ダンプリスト解析入門(番外編①):正しいアドレスなのにS0C4でABENDする??

MVCL命令でデータの移動先アドレスや移動するデータの長さなどを間違えた場合に、データの移動中にプログラムチェック割り込みを起こし、S0C4でABENDすることがあります。命令で指定したレジスターはABENDした時点の移動元や移動先のアドレス、残りの領域長やデータ長を示します。

この命令は、GR14が示すアドレスの領域内データを、GR0が示すアドレスの領域にコピーするものです。領域の長さは対となっているGR1およびGR15に入っています。この命令実行中に次に示すようなPSWとレジスターでABENDしました。

ABENDした時点のGR0はx0000A000、GR14はx00008EBCで、残りデータ長はx60バイトを示しています。SYSUDUMPに出力された移動元と移動先の領域内容は次の通りでした。

プログラムではGR14が示す移動元は、自プログラム領域内でアドレスと長さの指定には問題がありません。となれば移動先のアドレスxA000が問題となったものと考えられます。しかしダンプには問題であろうアドレスxA000は有効なストレージ領域として出力されています。仮想アドレスとして存在しているのにどうして不正アドレスでS0C4してしまうのか?という疑問も生じます。

結論から言うと、この場合確かにxA000は誤ったアドレスなのです。プログラム・コードを見るとGETMAINで長さを4000バイトとして移動先の領域を割り振っているのに、MVCL命令は4096バイトの長さで実行しています。そのため4000バイト移動し終わった時点でABENDしたものです。
アドレスA000の領域は存在しないのですからダンプには出てこないはずですが、出てきているために、ならば有効な仮想記憶域ではないか?と思ってしまうわけです。
手元にプログラムコードがあって、単純なミスのようなバグであればダンプがどうであれ、簡単に原因はわかりますが、複雑なプログラムであったり、過去に作られたもので内容もよくわからない、といったような場合では、ダンプされた領域の内容から問題を起こしたモジュールや箇所を特定したい場合もあります。プログラムの規模が大きくなると原因を作った箇所と実際にABENDしたモジュールが違う、などということはよくあることです。ダンプ上でxA000は、Storage not available であるとはっきり出ていればいいのですが、上記のようにダンプにも領域として出てきてしまうと、どうしてこのアドレスでS0C4になるのか?と考えてしまうかも知れません。

実はダンプに出ているxA000からの領域は、このプログラムがABENDした後に、MVSのABEND処理によって割り振られた領域です。このケースではSYSUDUMP(SYSABEND)を出力するための作業域、関連するモジュールのローディングなどに使われていました。ダンプリストはABENDした時点の空間内の記憶域を編集して出力しますが、ABENDそのものを処理したりダンプを出力するためにMVSのRTMなど関連するコンポーネントのモジュールが実行されます。そのためABEND発生からダンプのためにメモリー内容が読み取られるまでの間にOSの作業域として空間内の領域が使用され、そこがたまたまアプリケーション・プログラムが割り振った領域の直後に続いて割り振られると、ダンプ上は有効な仮想記憶域が続いているように見えるのです。
落ち着いて見ればその後に、OSのモジュール名らしきものやABEND処理に使われそうな内容の文字列などが入っていれば当たりもつきますが、ヌルなどがある程度続いていたりすると元々GETMAINしていたアプリケーションの領域ではないのか?とも思えてしまうのです。このケースではSYSUDUMPではなくSYSMDUMPでバイナリーダンプの出力に変えたところ、xA000の領域はダンプ上存在せず Storage not available となっていました。SYSMDUMPはフォーマットしないのでより少ない作業域で処理されたものと考えられます。

もしMVCL命令実行中にABENDしたので関連するレジスターからダンプでストレージ内容を確認したら、仮想記憶域として出力されているからS0C4するようには見えないが?と思ったら、データの移動元や移動先アドレスが、ちょうどページの始まりを示すきりのいいアドレス値になっていないかを確認してみて下さい。もしこのケースのようにxA000など仮想ページの開始アドレスつまりページバウンダリーになったアドレスであれば、間違いなくデータ移動中に有効なページを超えてデータを処理しようとしたものです。GETMAINしていない領域でもまたFREEMAINしてしまった領域でも、ページの1部でも有効に残っていればそのページの4KBの中であればS0C4にはなりません。そのページを超えて次のページが割り振られていないとそこでS0C4となります。

いずれにしてもダンプリスト(特にSYSUDUMPやSYSABEND)で出てくるメモリー内容は、純粋にアプリケーション・プログラムでだけ使われている領域だけではない、ABENDした時にはなかったけどABEND処理の過程でリージョン内の領域が割り振られて使われた結果ダンプにでてくる領域もあるのだ、ということを知った上でダンプを調べると余計な疑問を持たずに済みます。原因がなかなか掴めないとどうしても他の誰かが悪いのでは?と考えたくなりますが、ABENDの原因は99.999%自分の作ったプログラムにあるのだと考える方が無難です。

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