例: 例外箇所を突き止め (アドレスを出力して)、異常終了します。
demo% cat LocExcHan.F #include "floatingpoint.h" EXTERNAL Exhandler INTEGER Exhandler, i, ieee_handler REAL:: r = 14.2 , s = 0.0 , t C ゼロ除算の検出 i = ieee_handler( 'set', 'division', Exhandler ) t = r/s END INTEGER FUNCTION Exhandler( sig, sip, uap) INTEGER sig STRUCTURE /fault/ INTEGER address END STRUCTURE STRUCTURE /siginfo/ INTEGER si_signo INTEGER si_code INTEGER si_errno RECORD /fault/ fault END STRUCTURE RECORD /siginfo/ sip WRITE (*,10) sip.si_signo, sip.si_code, sip.fault.address 10 FORMAT(' シグナル ',i4,' コード ',i4,' 16 進アドレス ', Z8 ) Exhandler=1 CALL abort() END demo% f95 -g LocExcHan.F demo% a.out シグナル 8 コード 3 16 進アドレス 11230 異常終了 demo% |
64 ビット SPARC 環境では、各 STRUCTURE 内の INTEGER 宣言を INTEGER*8 で置き換えて、書式中の i4 を i8 で置き換えます。この例では、f95 コンパイラへの拡張により、VAX Fortran の STRUCTURE 文を受け付けられるようにしています。
ほとんどの場合、例外の実際のアドレスを知るということは、dbx だけに意味があります。
demo% dbx a.out (dbx) stopi at 0x11230 ブレークポイントをアドレスに設定する (2) stopi at &MAIN+0x68 (dbx) run プログラムを実行する 実行中: a.out (プロセス id 18803) MAIN で 0x11230 で停止しました MAIN+0x68: fdivs %f3, %f2, %f2 (dbx) where 例外が発生した行番号を表示する =>[1] MAIN()、"LocExcHan.F" の 7 行目 (dbx) list 7 ソースコード行を表示する 7 t = r/s (dbx) cont ブレークポイント後、継続してハンドラルーチンに入る シグナル 8 コード 3 16 進アドレス 11230 異常終了: _kill 0xef6e18a4 でシグナル ABRT (異常終了) が呼び出されました _kill+0x8: bgeu _kill+0x30 現関数: exhandler 24 CALL abort() (dbx) quit demo% |
もちろん、エラーの原因となるソース行を決定するためのより簡単な方法があります。しかし、この例は、例外処理の基本を示すのが目的です。