Oracle® Solaris Studio 12.4:使用 dbx 调试程序

退出打印视图

更新时间: 2015 年 1 月
 
 

捕获 FPE 信号(仅限 Oracle Solaris)

浮点和整数算术运算可能会导致异常,例如溢出和被零除。此类异常通常无提示,因此系统会返回合理答案(例如 NaN)作为导致异常的运算的结果。因此,这些异常对 dbx 不可见。

您可以进行设置使得出现异常时不再无提示,而是导致陷阱。然后,操作系统将陷阱转换为 SIGFPE 并将其传送到进程,dbx 可以拦截此信号传送。请注意以下几点:

  • 缺省情况下,F77 不会在出现任何浮点异常时自陷。

  • 缺省情况下,F95 会在出现无效操作数、除以零和溢出异常时自陷,但不会在出现下溢和不精确异常时自陷。

  • 缺省情况下,C 和 C++ 不会在出现浮点异常时自陷。

  • 没有针对整数溢出进行置备以隐式触发 SIGFPE。在 SPARC 上,您可以使用 TVS (trap-on-overflow-set) 汇编指令。在 SPARC 或 Intel 上,您可以使用类似 branch-on-overflow-set 的指令。

要查找导致异常的原因,需要在程序内设置陷阱处理程序,以使异常触发 SIGFPE 信号。

    可使用下列方式启用陷阱:

  • fpsetmask-此函数严格控制陷阱的启用。请参见 fpsetmask(3C) 手册页。

    示例:

    #include <ieeefp.h>
        int main() {
        fpsetmask(FP_X_INV|FP_X_OFL|FP_X_UFL|FP_X_DZ|FP_X_IMP);
        ... 
  • ieee_handler-不存在 Fortran 的 psetmask(3c) 精确模拟。相反,您可通过按如下所有建立缺省行为,以启用陷阱。

    示例:

        integer*4 ieeer
        ieeeer  = ieee_handler('set', 'common', SIGFPE_DEFAULT)

    有关更多信息,请参见 ieee_environment(3f)ieee_handler(3m) 手册页。

  • -ftrap 编译器标志-此标记类似于 fpsetmask()(),它将严格控制陷阱的启用。有关 Fortran 95 的信息,请参见 f95(1) 手册页。

使用以上方法之一启用浮点陷阱时,系统将设置硬件浮点状态寄存器中的陷阱启用掩码。此陷阱启用掩码会导致异常在运行时引发 SIGFPE 信号。

插入对 fpsetmask()()ieee_handler()() 的调用,或使用陷阱处理程序编译程序后,将程序装入到 dbx 中。从 Oracle Solaris Studio 12.4 起,SIGFPE 在缺省情况下已捕获。使用旧版本的 dbx 时,请确保该信号仍在捕获列表中。

(dbx) 
catch FPE

您可以通过对 fpsetmask()ieee_handler() 的参数稍作调整,并通过使用 dbx 捕获命令的替代命令,就如捕获 FPE 一样,进一步量身定制查看哪些特定异常。

(dbx) stop sig FPE
(dbx) ignore SIGFPE #don't catch it twice

可以使用以下代码优化控制:

stop sig FPE subcode

其中 subcode 可以是下列选项之一:

FPE_INTDIV

整数除以零。

FPE_INTOVF

整数溢出。

FPE_FLTDIV

浮点除以零。

FPE_FLTOVF

浮点溢出。

FPE_FLTUND

浮点下溢。

FOE_FLTRES

浮点不精确结果。

FPE_FLTINV

无效的浮点运算。

FPE_FLTSUB

下标超出范围。

确定发生异常的位置

FPE 添加到捕获列表后,在 dbx 中运行程序。出现要捕获的异常时,系统将引发 SIGFPE 信号且 dbx 会停止程序。然后,可以使用 dbx where 命令跟踪调用堆栈,以帮助查找程序中发生该异常的特定行号。

确定导致异常的原因

要确定导致 SPARC 异常的原因,请使用 regs -f 命令显示浮点状态寄存器 (floating point state register, FSR)。 查看寄存器的已产生的异常 (aexc) 和当前异常 (cexc) 字段,这些字段包含下列浮点异常条件位:

  • 无效操作数

  • 溢出

  • 下溢

  • 除以零

  • 不精确结果

在 Intel 中,x87 的浮点状态寄存器是 fstat,SSE 的浮点状态寄存器是 mxcsr

有关浮点状态寄存器的更多信息,请参见《The SPARC Architecture Manual》的版本 8 (V8) 或版本 9 (V9)。有关更多讨论和示例,请参见Oracle Solaris Studio 12.4:数值计算指南