COBOL2002 ユーザーズガイド


37.7 COBOLが検出するハードウェア例外およびソフトウェア例外

〈この節の構成〉

(1) ハードウェア例外およびソフトウェア例外とは

例外は,プログラムの実行状態が異常になった場合に発生します。PCのアーキテクチャでは,命令実行中の異常事態を検知するためにCPU内部で発生させる割り込みのことを特に例外と呼び,CPU外部の要因で引き起こされる割り込みとは区別します。この例外にはCPUが検知するハードウェア例外とソフトウェアによって発行されるソフトウェア例外があります。

(2) アプリケーションエラー

-DebugInf,-DebugInf,Trace,-DebugCompati,-DebugData,-TDInf,-CVInf,-DebugRangeオプションのどれも指定しないでコンパイルしたプログラムの実行でハードウェア例外やソフトウェア例外が発生した場合,OSがアプリケーションエラーのダイアログボックスを表示します。代表的なアプリケーションエラーと対処法を「表37‒3 代表的なアプリケーションエラー」に示します。

アプリケーションエラーが発生した場合は,次の手順で発生している例外種別および発生個所を調べてください。

  1. -DebugInfまたは-DebugInf,Traceオプションを指定して再度コンパイルと実行をする

  2. 異常終了時要約情報リストで発生している例外種別および発生個所を調べる

発生個所がCALL文を指している場合は,その呼び出し先プログラムも調査の対象としてください。

表37‒3 代表的なアプリケーションエラー

例外名称(例外コード)

意味と対処方法

アクセス違反

(0xc0000005)

(原因)アクセスが許されていないメモリに読み書きしようとした。

(対処)このエラーは主に次の要因で発生する。これに該当しないかを確認する。

  1. 呼び出し元プログラムと呼び出し先プログラムで,引数の属性,長さ,または数が一致していない

  2. 表操作で使用する添字または指標の値がOCCURSで定義した範囲を超えた

  3. 部分参照でデータ項目の領域を超えて参照した

  4. アドレス名に不正なアドレスが入っている状況で,ADDRESSED句付きで定義されたデータ名を参照した

  5. 可変長項目のDEPENDING ONに指定されたデータ項目に不当な値が入っている状態で,その可変長項目,またはその従属項目を参照した

1.〜3.の場合,-DebugRangeを指定してコンパイル・実行することで,そのエラーであることおよび発生個所を特定できる。

ゼロ除算

(0xc0000094)

(原因)ゼロで除算しようとした(被除数,除数ともに浮動小数点データでない場合)。

(対処)ゼロによる除算が発生しないようにプログラムを変更する。

スタックオーバフロー

(0xc00000fd)

(原因)プログラムが使用するスタックサイズが,プログラムで許されたスタックの上限を超えた。再帰属性プログラム,メソッド,および利用者定義関数で,次の場合に発生しやすくなる。

  • 局所場所節のデータ定義の合計サイズが大きい

  • 大量に再帰呼び出しがある

  • 連絡節のデータ定義の合計サイズが大きい

  • BY CONTENT,BY VALUEが仮定される関数の引数に大きなデータ項目がある

(対処)プログラムのスタックの上限は,-STACKオプションで変更できる。このオプションで変更してから再リンクして,スタックの上限を変更する。-STACKオプションについては,「38.1.3 オプション」を参照のこと。

COBOLプログラムが使用するスタック領域については,「31.3 COBOLプログラムが使用するスタック領域」を参照のこと。

(3) COBOL実行時ライブラリが検出する例外

(a) 例外種別の出力

-DebugInf,-DebugInf,Trace,-DebugCompati,-DebugData,-TDInf,-CVInf,-DebugRangeオプションのどれかを指定してコンパイルしプログラムを実行した場合に例外が発生すると,COBOLがこれを検知し,実行時メッセージ,および異常終了時要約情報リストで例外種別を出力します。この情報によって,どのような例外が発生したか,および例外がどの実行文で発生しているかを把握できます。

実行時メッセージ,および異常終了時要約情報リストに表示される例外種別とその意味を次に示します。

表37‒4 実行時メッセージ,および異常終了時要約情報リストに表示される例外種別

例外種別

意味

RUNTIME ERROR

COBOL実行時エラーが発生した。

CBLABN

CBLABNサービスルーチンが呼び出された。

EXCEPTION_ACCESS_VIOLATION

表37‒3 代表的なアプリケーションエラー」の「アクセス違反」を参照

EXCEPTION_INT_DIVIDE_BY_ZERO

表37‒3 代表的なアプリケーションエラー」の「ゼロ除算」を参照

EXCEPTION_INT_OVERFLOW

整数演算の結果,最上位ビットのキャリーアウトが発生した。

EXCEPTION_FLT_DENORMAL_OPERAND

浮動小数点演算で使用している作用対象に異常があり,その値が小さ過ぎるため,標準の浮動小数点値として表せない。

EXCEPTION_FLT_DIVIDE_BY_ZERO

浮動小数点値を浮動小数点値0で割ろうとした。

EXCEPTION_FLT_INEXACT_RESULT

浮動小数点演算の結果を10進小数として正確に表せない。

EXCEPTION_FLT_OVERFLOW

浮動小数点演算の指数の値が,対応する型の上限値を超えている。

EXCEPTION_FLT_UNDERFLOW

浮動小数点演算の指数の値が,対応する型の下限値を超えている。

EXCEPTION_FLT_STACK_CHECK

浮動小数点演算の結果,スタックのオーバフローまたはアンダーフローが発生した。

EXCEPTION_FLT_INVALID_OPERATION

この表にないすべての浮動小数点例外を表す。

EXCEPTION_PRIV_INSTRUCTION

現在のマシンモードでは実行できない演算命令を実行しようとした。

STATUS_NONCONTINUABLE_EXCEPTION

実行を続行できない例外の発生後,実行を続行しようとした。

(b) プロセスの終了

異常終了時要約情報リストを出力後,プロセスは終了コード1で終了します。

ただし,環境変数CBLEXCEPT=THROWを指定したときはシステムが返す値が設定されます。

(c) 例外発生時の動作を指定する実行時環境変数CBLEXCEPT

形式
CBLEXCEPT=THROW
規則

この環境変数にTHROWを指定すると,デバッグ用コンパイラオプション-DebugInf,-DebugInf,Trace,-DebugCompati,-DebugData,-TDInf,-CVInf,-DebugRangeのどれかを指定したプログラムの実行中に例外が発生した場合,例外コードを上位プログラムにスローします。

このとき,異常終了時要約情報リストを出力し,終了方法は上位の制御プログラムの終了処理に依存します。

例えば,デバッグ環境を構築できない環境でシステム例外発生時のデバッグをする場合に指定します。

この環境変数を指定したときの動作を次に示します。

  • COBOLプログラムがメインでないアプリケーションやGUIプログラムでは,この環境変数を指定しても,有効となりません。

  • CBLDBGINFサービスルーチンを呼び出した場合は,例外コードを上位プログラムにスローしません。

  • THROWを指定した場合,ハードウェア例外やソフトウェア例外の発生により異常終了したとき,Windows問題レポートの設定などによって,クラッシュダンプが出力される場合があります。

    クラッシュダンプからシステム例外発生時点のスタックトレースなどを参照するために有用なコンテキスト情報のアドレスが実行時メッセージ中に出力されます。

    また,上位プログラムのユーザープログラムに例外処理があれば,そちらに制御が移ります。

    なお,ミドルソフトなどでこの例外処理を実装している場合もありますので,異常終了時の出力情報を確認してください。

  • この環境変数を指定しても実行性能への影響はありません。

(4) 注意事項