Oracle® Solaris Studio 12.4: Debugging a Program With dbx

Exit Print View

Updated: January 2015
 
 

Trapping the FPE Signal (Oracle Solaris Only)

Floating-point and integer arithmetic operations can cause exceptions like overflow or divide by 0. Such exceptions are often silent such that the system returns a reasonable answer (e.g. NaN) as the result for the operation that caused the exception. Therefore these exceptions are not visible to dbx.

You can arrange for the exception to not be silent and instead cause a trap. Then the operating system will convert the trap to a SIGFPE and deliver it to the process and dbx can intercept this signal delivery. Note the following:

  • F77 by default does not trap on any floating-point exception.

  • F95 by default traps on invalid operand, divide-by-zero, and overflow exceptions, but not underflow and inexact exceptions.

  • C and C++ do not trap on floating-point exceptions by default.

  • There is no provision for integer overflow to implicitly trigger a SIGFPE. On SPARC, you can use the TVS (trap-on-overflow-set) assembly instruction. On SPARC or Intel, you can use analogous branch-on-overflow-set instructions.

To find the cause of an exception, you need to set up a trap handler in the program so that the exception triggers the signal SIGFPE.

    You can enable a trap using the following:

  • fpsetmask – This function strictly controls the enabling of traps. See the fpsetmask(3C) man page.

    Example:

    #include <ieeefp.h>
        int main() {
        fpsetmask(FP_X_INV|FP_X_OFL|FP_X_UFL|FP_X_DZ|FP_X_IMP);
        ... 
  • ieee_handler – There is no exact analog of psetmask(3c) for Fortran. Instead, you can enable traps by establishing the default behavior as follows.

    Example:

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

    See the ieee_environment(3f) and ieee_handler(3m) man pages for more information.

  • -ftrap compiler flag – This tag, like fpsetmask()(), strictly controls the enabling of traps. For Fortran 95, see the f95(1) man page.

When you enable a floating-point trap handler using one of the previously mentioned methods, the trap enable mask in the hardware floating-point status register is set. This trap enable mask causes the exception to raise the SIGFPE signal at run time.

Once you have inserted a call to fpsetmask()() or ieee_handler()() or compiled the program with the trap handler, load the program into dbx. SIGFPE is caught by default as of Oracle Solaris Studio 12.4 . With older versions of dbx, ensure that the signal is still in the catch list.

(dbx) 
catch FPE

You can further tailor which specific exceptions you see by tweaking the parameters of fpsetmask() and ieee_handler() by using an alternative to the dbx catch command which acts like catch FPE, similar to the following.

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

You can use the following code for finer control:

stop sig FPE subcode

where subcode can be one of the following:

FPE_INTDIV

Integer divide by zero.

FPE_INTOVF

Integer overflow.

FPE_FLTDIV

Floating-point divide by zero.

FPE_FLTOVF

Floating-point overflow.

FPE_FLTUND

Floating-point underflow.

FOE_FLTRES

Floating-point inexact result.

FPE_FLTINV

Invalid floating-point operation,

FPE_FLTSUB

Subscript out of range.

Determining Where the Exception Occurred

After adding FPE to the catch list, run the program in dbx. When the exception that you are trapping occurs, the SIGFPE signal is raised and dbx stops the program. Then you can trace the call stack using the dbx where command to help find the specific line number of the program where the exception occurs.

Determining the Cause of the Exception

To determine the cause of the exception on SPARC, use the regs -f command to display the floating point state register (FSR). Look at the accrued exception (aexc) and current exception (cexc) fields of the register, which contain bits for the following floating-point exception conditions:

  • Invalid operand

  • Overflow

  • Underflow

  • Division by zero

  • Inexact result

On Intel, the floating-point status register is fstat for x87 and mxcsr for SSE.

For more information on the floating-point state register, see Version 8 (for V8) or Version 9 (for V9) of The SPARC Architecture Manual. For more discussion and examples, see Oracle Solaris Studio 12.4: Numerical Computation Guide .