MSPではDYNALLOCのテキストユニットを全部書き戻す
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へ持って行った時に気づく、ということになるわけです。