05.3 プログラム割込みのトラップ(SPIE、ESPIE)

業務用アプリケーションでは、誤ったデータによる演算の結果、プログラムが異常終了することがしばしば起こります。プログラム・ロジックには問題がないのにデータが原因でプログラム割込みが引き起こされるためです。このようなことを防止するため、入力されたデータやデータセットから読み込んだデータの妥当性をチェックすることは、よく行われるプログラミング手法です。他の方法として、結果として誤りであったらその誤りをなかったことにする方法もあります。読み込んだデータが悪いために演算命令がエラーになったら、プログラムをそこで終了するのではなく、そのデータを捨てて次のデータを処理するようにできます。例外処理とも呼ばれ、コンパイラー言語などではON ERROR、TRY~CATCHなどの記述で行われます。
MVSでは、SPIEまたはESPIEマクロによって例外処理を設定することができます。SPIE/ESPIEは、プログラム割込みが発生した時に、プログラムをABENDさせずに予め指定されたルーチン(SPIE出口ルーチン)を実行してエラーが発生したことをプログラムに通知します。

0による除算をトラップしてメッセージを出力する

SPIEを使うと、指定した種類のプログラム割込みであれば、それが発生してもABENDせずに指定のSPIE出口ルーチンが実行されることでプログラムに通知されます。トラップ・ルーチンにはPIEというパラメータ・リストが渡され、それを見ることでABENDの内容、発生したアドレスを知ることができます。このサンプルのように、PIE内容を変更しなければABENDした次の命令から実行を再開させることができます。

指定可能な全てのプログラム割込みをトラップして、独自のABENDメッセージを出す。
データ例外であれば、その入力データを捨てる。

サンプルなので、無理して全部のプログラム割込みをトラップしていますが、実際には必要なものだけに絞って行う方がいいでしょう。一般のアプリケーションであれば、0C7や0C9で十分かと思います。

ABENDしたアドレスや割込みコードは、出口ルーチンに渡されるPIE(Program Interruption Element)を参照すれば知ることができます。PIE内のPSWアドレス・フィールドを書き換えれば、任意の場所からプログラムを再開させることができます。この例では、S0C7ABENDの場合にそれを行っています。
なお、SPIEは24ビット・モードのプログラムでなければ使用できません。31ビット・モードのプログラムの場合はSPIEではなくESPIEを利用します。

31ビットモード・プログラムにおけるSPIE(ESPIE)

2番目のサンプルと同じものを、31ビット・モードのプログラム用のESPIEで置き換えたものです。ESPIE出口ルーチンに渡されるPIEは、ESPIE(Extend PIE)に変わり、そのフォーマットは異なります。そのため、SPIEを使っている24ビットモード・プログラムを31ビットモードに書き換える場合、単にマクロをSPIEからESPIEに変更するだけでは済みません。対応するフィールドのオフセットやフィールド名を、ESPIE用に変更しなければなりません。3番目のサンプルでは直接オフセット値を指定せずに、EPIEのマッピング・マクロを使用してフィールドを名前で参照するようにしました。MVSはPIE用にIHAPIE、EPIE用にIHAEPIEマクロを提供しています。

大量の入力データを処理するようなプログラムでは、その中にいくつかの誤りデータが入っていても、途中で処理をやめずにエラー・データだけを外して正常なデータについては全て処理しきってしまいたいという仕様もあります。処理前にチェックしてはじくか、エラーになったものをはじくか何れの方法もありますが、後者であればSPIEやESPIEを利用すれば、プログラム割込みによるABENDは回避できます。どちらの場合であっても、どのデータを外したかをきちんとログを取って、完了コードも0ではなく4にするなど運用面でも誤りに気付きやすい設計にすることが大切です。