MSPではDYNALLOCのテキストユニットを全部書き戻す

By 神居 - Posted: 2011/06/16 Last updated: 2011/06/16 - Leave a Comment

DYNALLOCなんて、ややこしいパラメーターでなければ基本は互換だと思っていたが、MSPでは不思議な現象だったので記録してあった。
DYNALLOCでDISP=SHRの定義をするためのテキストユニットなど、読み出ししかされない(はず)テキストユニットだからと、キー0のプロテクト領域に置かれていた(APF許可のリエントラント・プログラムなのでプログラムはキー0のサブプール252にロードされる。テキストユニットはプログラム内データとして定義したので結果としてキー0のプロテクト領域となる)。
MVSでは問題なく動いたが、MSPではSVC99ルーチンの処理内でABENDS0C4が発生した。次のサンプルが同様の処理を行うプログラム。

PGMNAME  CSECT
         USING *,12                     DEFINE BASE REGISTER
         STM   14,12,12(13)             SAVE CALLER REGISTERS
         LR    12,15                    GR12 -> OUR 1ST BASE ADDRESS
         GETMAIN R,LV=LWORK             GETMAIN OUR GPR SAVEAREA
         ST    13,4(,1)                 SAVE CALLER SAVEAREA POINTER
         ST    1,8(,13)                 SET BACK CHAIN FOR SA TRACE
         LR    15,13                    KEEP CALLER GPR SAVEAREA
         LR    13,1                     LOAD OUR NEW SAVEAREA
         LM    0,1,20(15)               RELOAD ENTERED GR0-1(PARAMETER)
         USING DWORK,13                 ADDRESS TO LOCAL WORKAREA
         SPACE ,
         USING S99RBP,W99RBP            ADDRESS TO RB POINTER
         USING S99RB,W99RB              ADDRESS TO RB
         LA    R0,S99RB                 MAKE SVC99 RB POINTER
         ST    R0,S99RBP                 I
         OI    S99RBP,X'80'              V

         XC    S99RB(S99RBEND-S99RB),S99RB  CLEAR RB AREA
         MVI   S99RBLN,S99RBEND-S99RB   MAKE SVC99 RB
         MVI   S99VERB,S99VRBAL          I
         LA    R0,W99TUPL                I
         ST    R0,S99TXTPP               V

         LA    R0,A99DDN                MAKE TEXT UNIT POINTER
         ST    R0,W99TUPL+0              I
         LA    R0,A99DSN                 I
         ST    R0,W99TUPL+4              I
         LA    R0,A99STATS               I
         ST    R0,W99TUPL+8              I
         OI    W99TUPL+8,X'80'           V

         LA    R1,S99RBP                GR1 <- svc99 rb pointer
 dynalloc , issue svc99

 lr 1,13 gr1 --> OUR GPR SAVEAREA
         L     13,4(,13)                RESTORE CALLER GPR SAVEAREA
         ST    15,16(,13)               SAVE RETURN CODE
         FREEMAIN R,LV=LWORK,A=(1)      FREEMAIN OUR LOCAL WORKAREA
         LM    14,12,12(13)             RESTORE CALLER REGISTERS
         BR    14                       RETURN TO CALLER
         SPACE ,
A99DDN   DC    AL2(DALDDNAM)
         DC    AL2(1)
         DC    AL2(8)
         DC    CL8'SYSUT1'
A99DSN   DC    AL2(DALDSNAM)
         DC    AL2(1)
         DC    AL2(44)
         DC    CL44'TEST.OUTPUT'
A99STATS DC    AL2(DALSTATS)
         DC    AL2(1)
         DC    AL2(1)
         DC    XL1'08'
         SPACE ,
         :
         :

テキストユニットがDALRTDDNのように、割り振ったDD名を戻すような書き込みがなされるものであれば、MVSでもSVC99の処理内でABENDS0C4が起きる。しかし書き戻しがなければ問題なく動く。しかしMSPではDYNALLOCの結果OS側で設定するようなものでなくても、書き込み可能になっていないと(キー8で書き込みできる領域にないと)ABENDしてしまう。
実際の仕事で引っ掛かったのは、DALSTATSのテキストユニットであった。OSのバグではとも思ったが、よくよくマニュアルを見ると、MSPではDYNALLOC発行時に用意すべきパラメーターの構造の解説があって、その後に「これらのフィールドは、動的割当てルーチン呼出し後、動的割当てルーチンの作業域へコピーされ、処理終了後、再び呼出し元領域へ、呼出し元のキーで書き戻される。したがって、これらの領域は呼出し元キーで書込み可能な領域になくてはならない。」と確かに書いてある。なので、テキストユニットをサブプール0にコピーして使用することで問題を回避した。
ちなみにMVSの場合、マニュアルには「システムが情報を戻すテキスト単位は、動的記憶域の中に入っていなければなりません。(中略) システムが情報を戻すときに使用しないテキスト単位は、動的記憶域に入っている必要はありません。プログラム内の静的記憶域に入っていれば十分です。」とあり、実際情報が戻されないテキストユニットがPSWのキーと違うところにあってもABENDはしなかった。
ただし別の解説として、パラメーター・リストの記憶域の特性、として「パラメーター・リストの記憶域は、フルワード境界で始まらなければなりません。パラメーター・リスト構造全体は、DYNALLOC の呼出し側と同じキーを使って記憶域内に作成する必要があります。さらに、要求ブロック、要求ブロック拡張、およびすべての情報検索テキスト単位は、記憶保護されていない記憶域になければなりません。この要件を満たせば、DYNALLOC が情報検索テキスト単位を呼出し側の記憶域に格納するときに 0C4 の異常終了を回避することができます。」とある。なので、書き戻しされないテキストユニットだからとか気にせず、全部非プロテクト領域に入れるのが本来で、たまたまMVSではOS側が情報を戻さないテキストユニットでは書き戻しされず、MSPでは全部書き戻してるからABENDしてしまった、ということなんでしょう。元の作りも確かにマニュアルの奨めに沿ってませんが、動いてしまえばわざわざ直さないんで、こんなように他のOSへ持って行った時に気づく、ということになるわけです。

Posted in API、インターナルの違い • • Top Of Page