示例:定位异常(打印地址)并中止:
demo% cat LocExcHan.F #include "floatingpoint.h" EXTERNAL Exhandler INTEGER Exhandler, i, ieee_handler REAL:: r = 14.2 , s = 0.0 , t C Detect division by zero 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(’Signal ’,i4,’ code ’,i4,’ at hex address ’, Z8 ) Exhandler=1 CALL abort() END demo% f95 -g LocExcHan.F demo% a.out Signal 8 code 3 at hex address 11230 Abort demo% |
在 64 位 SPARC 环境中,请用 INTEGER*8 替换每个 STRUCTURE 中的 INTEGER 声明,用 i8 替换 i4 格式。(注意,该例接受 VAX Fortran STRUCTURE 语句,依靠的是 f95 编译器的扩展。)
大多数情况下,知道异常的实际地址并无太大用处,但对于 dbx 除外:
demo% dbx a.out (dbx) stopi at 0x11230 Set breakpoint at address (2) stopi at &MAIN+0x68 (dbx) run Run program Running: a.out (process id 18803) stopped in MAIN at 0x11230 MAIN+0x68: fdivs %f3, %f2, %f2 (dbx) where Shows the line number of the exception =>[1] MAIN(), line 7 in "LocExcHan.F" (dbx) list 7 Displays the source code line 7 t = r/s (dbx) cont Continue after breakpoint, enter handler routine Signal 8 code 3 at hex address 11230 abort: called signal ABRT (Abort) in _kill at 0xef6e18a4 _kill+0x8: bgeu _kill+0x30 Current function is exhandler 24 CALL abort() (dbx) quit demo% |
当然,还有更容易的方法来确定引起错误的源码行。但是,本例确实足以展示异常处理的基本内容。