05.4ABENDリカバリーを行う(ESTAE)
ESTAEは、プログラム独自のリカバリー環境を作成するためのAPIです。リカバリーとは、プログラムが異常終了する際に行われる一連の回復手順です。ESTAEを使用すれば、プログラムは異常終了の発生を受け取り、必要な診断情報を集め、必要に応じた回復処理が行えます。異常終了させずに、プログラムの実行を再開させることもできます。
同様のサービスにはSPIE/ESPIEがありますが、ESTAEはプログラム割込みに限定されず、すべての異常終了についてトラップすることができます。
ESTAEによるABENDリカバリー環境の作成
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- MAINLINE DS 0H : : L R2,=CL4'PARM' GR2 <-- c'parm' ESTAE TRAPABND, BUILD OUR ESTAE ENVIRONMENT + PARAM=(2), + TERM=YES, + XCTL=YES, + PURGE=NONE, + ASYNCH=NO * : : メインラインの処理 : : B EXITPROG * BADDATA DS 0H WTO '(MAIN)OCCURRED DATA EXCEPTION(ABEND S0C7)' : : 残りの処理があれば続ける : : * EXITPROG DS 0H ESTAE 0 PURGE OUR ESTAE ENVIRONMENT これは以前のESTAE環境に戻す処理。 他のモジュールから呼ばれる サブルーチンであれば必ず以前の 環境を戻すこと。 : : : * *----------------------------------* * * ESTAE EXIT ROUTINE * * * ============================== * * * GR0 --> RTM STATUS * * * 12: SDWA NOT AVAILABLE * * * GR1 --> SDWA OR TCBCMP(GR0=12) * * * GR2 --> PARM AT ESTAE ISSUED * * * GR14 -> RETURN ADDR TO OS * * * GR15 -> ENTRY ADDR * * *----------------------------------* TRAPABND DS 0H ENTER AT HERE WHEN OCCURED + PGM-CHECK INTERRUPTION USING *,RF DEFINE TEMP BASE L RC,=A(MAINENTR) ESTABLISH OUR BASE REGISTER DROP RF FORGET TEMP BASE LR R6,R1 GR6 --> SDWA USING SDWA,R6 ADDRESS IT SLR R0,R0 CLEAR WORKREG ICM R0,B'0111',SDWACMPC GR0 --> INTERRUPT CODE L R1,SDWAEC2+4 GR1 --> INTERRUPT ADDRESS SPACE , CL R0,=A(X'000C7000') DATA EXCEPTION(ABEND S0C7) ? BNE DOABEND NO, ABEND WITH DIAG MSG SPACE , ST R0,SDWASRSV+0*4 PASS GR0(ABEND CODE) TO MAIN ST R1,SDWASRSV+1*4 PASS GR1(ABEND ADDR) TO MAIN L RA,=A(BADDATA) LOAD RESUME ADDRESS SETRP WKAREA=(6), SDWA ADDRESS + DUMP=NO, INDICATE IGNORE RTM DUMP + RETADDR=(10), RETRY ROUTINE ADDRESS + RETREGS=YES, PASS REGS FROM SDWA + FRESDWA=YES, NO LONGER NEED SDWA + RC=4 INDICATE SCHEDULING RETRY RTN BSM 0,RE CONTINUE MAINLINE PROCESSING SPACE , DOABEND DS 0H LR R2,R1 SAVE ABEND ADDRESS SRL R0,12 MOVE CODE TO LOW ORDER BYTE LA R1,DOUBLE LOAD WORKAREA BAS RE,CNVRTX GR0 CONVERT TO HEX-DECIMAL MVC SWTOLIST+26(3),DOUBLE+1 SET INTERRUPT CODE IN MSG LR R1,R2 LOAD ABEND ADDRESS SLL R1,8 EDIT INTERRUPTED ADDRESS SRL R1,8 I SLR R1,RC V LR R0,R1 SET INTERRUPT ADDR IN MSG LA R1,SWTOLIST+39 I BAS RE,CNVRTX V WTO MF=(E,SWTOLIST) INFORM PROGRAM ABENDED MSG SETRP WKAREA=(6), SDWA ADDRESS + DUMP=YES, REQUIRE TO FORMATTED DUMP + RC=0 INDICATE PERCOLATION SVC 3 RETURN TO OS(END OF PROGRAM) CNVRTX DS 0H CONVERT GR0 TO HEX-DECIMAL LA R1,3(,R1) I LA RF,4 I STC R0,0(,R1) I NI 0(R1),X'0F' I TR 0(1,R1),CNVTRT I SRL R0,4 I BCTR R1,0 I BCT RF,*-2-4-6-4-4 I BR RE V CNVTRT DC CL16'0123456789ABCDEF' SWTOLIST DS 0F WTO 'THIS PROGRAM ABENDED(SXXX) OFFSET(X0000)',MF=L *---------------------------------------------------------------------* DOUBLE DC D'0' : : : IHASDWA , SDWA MAP
ESTAEを使用した簡単なサンプルです。メインラインの処理で何らかのABENDが発生すると、ESTAE出口ルーチン(リカバリー出口ルーチン)TRAPABNDが実行されます。SPIE/ESPIEと異なり、ABEND時のレジスターが保持されているわけではないので、呼び出された外部サブルーチンとしてのハウスキープの処理が必要です。
ABENDコードはSDWACMPCフィールドに入っています。xxxyyyの3バイトで、xxxがSYSTEM ABENDコード、yyyがUSER ABENDコードを示します。001000ならS001、000001ならU0001です。サンプルではABENDコードがS0C7の場合、ABENDせずにメインラインのラベルBADDATAから再開し、S0C7でなければ、ABENDコードとABENDしたプログラム内オフセットをメッセージ出力して、ABENDしています。
プログラムチェック割込みだけをトラップするならSPIE/ESPIEの方が簡単ですが、その他のシステムアベンドなども含めてすべての異常終了をトラップするには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とすれば回復時にダンプがSYSABENDあるいはSYSUDUMP DD文に定義したデータセットに出力されます。ただしMSPでは再試行の場合はダンプは採取されないので、リカバリー出口ルーチン内でSNAPマクロなどにより自分で出力しなければなりません。
一般のプログラムではESTAEを使う必要は必ずしもありませんが、OSのABENDダンプではなく、もっとプログラムに特化した独自の診断情報を集めたい場合などには便利な機能です。
空間に固有なリソース以外のシステム共通のリソースを使うプログラムの場合は、必ずESTAEでABENDをリカバリーすべきです。実際にABENDを回避せずに、異常終了するにしてもESTAEは必須と言っていいでしょう。この場合、ESTAEのリカバリー出口ルーチンは、プログラムの回復ではなく、プログラムが使用したリソースの解放のために使います。空間に固有なリソースはABENDしてもOSがクリーンアップしてくれますが、CSAなどの共通域のストレージなど、OSがクリーンアップしてくれないリソースは確保したプログラムの責任できちんと掃除をする必要があります。
サンプルでは無条件にSDWAを使用していますが、実戦で使うプログラムの場合はSDWAの有無を判別すべきです。実際にはSDWAが渡されないケースは通常ではまずなくて、リージョン内の仮想記憶がSDWAも作れないほど一杯であるような状況ぐらいと思います。私は実戦でSDWAが渡されなかった経験はありませんでした。しかし予期しない事が起きるのがソフトウェアでもありますから、実際に通ることはないであろうにしても、SDWAが提供されたかどうかは判定しなければなりません。実際にSDWAが渡されなかった場合、恐らくはその空間にとっては危機的なメモリー不足の状況でしょうから、絶対解放が必要なリソースのクリーンアップだけして、速やかにパーコレート(リトライを要求せずにOSに戻る)すればいいでしょう。
ESTAEXIT DS 0H USING *,RF DEFINE TEMP BASE CH R0,=H'12' AVAILABLE SDWA ? BNE HAVESDWA YES, DO STD PROCESSING + NO, GR0=12 + GR1=ABEND CODE(00XXX000) + GR2=ESTAE PARM BAS R10,CLUPCMRS CLEAN HOLDING COMMON RESOURCES SLR RF,RF INDICATE PERCOLATION SVC 3 REQUIRE TO PERCOLATE ABEND... SPACE , HAVESDWA DS 0H L R12,AOURBASE ESTABLISH OUR BASE REGISTER DROP RF FORGET TEMP BASE LR R3,R1 GR3 --> SDWA USING SDWA,R3 ADDRESS IT : : :