05.4 ABENDリカバリーを行う(ESTAE)

ESTAEは、プログラム独自のリカバリー環境を作成するためのAPIです。リカバリーとは、プログラムが異常終了する際に行われる一連の回復手順です。ESTAEを使用すれば、プログラムは異常終了の発生を受け取り、必要な診断情報を集め、必要に応じた回復処理が行えます。異常終了させずにプログラムの実行を再開させることもできます。同様のサービスとしてSPIEとESPIEもありますが、ESTAEはプログラム割込みに限定されず全ての異常終了についてトラップすることができます。

ESTAEによるABENDリカバリー環境の作成

ESTAEを使用した簡単なサンプルです。メインの処理で何らかのABENDが発生すると、ESTAE出口ルーチン(リカバリー出口ルーチン)TRAPABNDが実行されます。SPIE/ESPIEと異なり、ABEND時のレジスターが保持されているわけではないので、呼び出された外部サブルーチンとしてのハウス・キーピング処理が必要です。
ABENDコードは、SDWACMPCフィールドに入っています。xxxyyyの3バイトで、xxxがSYSTEM ABENDコード、yyyがUSER ABENDコードを示します。x001000ならS001、x000001ならU0001です。サンプルでは、ABENDコードがS0C7の場合、ABENDせずにメイン処理のラベルBADDATAから再開し、S0C7でなければABENDコードとABENDしたプログラム内オフセットをメッセージ出力してABENDします。

プログラム割込みだけをトラップするならSPIE/ESPIEの方が簡単ですが、その他のシステムABENDなども含めて全ての異常終了をトラップするにはESTAEを使用します。ESTAEマクロでは、回復(リカバリー)ルーチン、回復ルーチンへ渡すパラメーターやその他のオプションを指定します。
ABENDが発生した際に制御を受けるのが回復ルーチンです。回復ルーチンにはSDWAが渡されます。このSDWAにABEND時の詳細な情報が入っています。ABEND時や最終割込み時のPSW、レジスターの内容、プログラム・アドレス、さまざまなステータス情報などです。SDWAが渡されない場合もあります。この場合、GR0に12が設定されています。GR1には、SDWAの代わりにABENDコードがTCBCMPフィールドの内容で格納されています。
回復ルーチンは、リカバリー可能と判断したら再試行(リトライ)ルーチンを設定します。再試行ルーチンとは、回復ルーチンがOSに戻った後、元のプログラムを再び実行させる開始点です。呼び出されてどこかへ戻るサブルーチンではなく、プログラムの実行を継続する再開点と考えればいいでしょう。再試行ルーチンを実行してABENDを回避するには、SETRPマクロに再試行ルーチンのアドレスとRC=4を指定します。レジスターに特定の値を入れて制御を渡したい場合は、SDWASRSVの対応するレジスター番号のフィールドに置き換える値を入れ、RETREGS=YESを併せて指定します。回復ルーチンはABENDしたタスクの新たなIRBルーチンとして実行されますが、再試行ルーチンは元のプログラムのRB(PRB)で実行されます。なお、SETRPマクロにDUMPパラメーターを指定することで、ダンプの採取をコントロールできます。例え、ABENDを回避する場合でも、調査のためにダンプを出力する場合、SETRPマクロでDUMP=YESとすれば回復時にダンプがSYSUDUMP、SYSABENDあるいはSYSMDUMP DDステートメントに定義したデータセットに出力されます。

一般のプログラムではESTAEを使う必要は必ずしもありませんが、OSのABENDダンプではなく、もっとプログラムに特化した独自の診断情報を集めたい場合などには便利な機能です。空間に固有なリソース以外のシステム共通のリソースを使うプログラムの場合は、必ずESTAEでABENDをリカバリーすべきです。ABENDを回避せずに異常終了するにしても、ESTAEは必須と言っていいでしょう。この場合のESTAEの回復ルーチンは、プログラムのリカバリーではなくプログラムが使用したリソースの解放のために使います。空間に固有なリソースはABENDしてもOSがクリーンアップしてくれますが、共通域(例、CSA)などOSがクリーンアップしてくれないリソースは、確保したプログラムの責任できちんと解放する必要があります。

サンプルでは無条件にSDWAを使用していますが、業務プログラムなどではSDWAの有無を判別すべきです。実際にはSDWAが渡されないケースは通常ではまずなくて、リージョン内の仮想記憶がSDWAも作れないほど一杯であるような状況ぐらいと思います。私自身はSDWAが渡されなかった経験はありませんでした。しかし、予期しない事が起きるのがソフトウェアでもありますから、実際に通ることはないであろうにしてもSDWAが提供されたかどうかは判定しなければなりません。実際にSDWAが渡されなかった場合、恐らくはその空間にとっては危機的なメモリー不足の状況でしょうから、絶対解放が必要なリソースのクリーンアップだけを行い、速やかにパーコレート(再試行を要求せずにOSに戻る)すればいいでしょう。