dbx supports the catch command, which instructs dbx to stop a program when dbx detects any of the signals appearing on the catch list.
By default, the catch list contains many of the more than 33 detectable signals. (The numbers depend upon the operating system and version.) You can change the default catch list by adding signals to or removing them from the default catch list.
To see the list of signals currently being trapped, type catch with no signal argument.
(dbx) catch
To see a list of the signals currently being ignored by dbx when the program detects them, type ignore with no signal argument.
(dbx) ignore
You control which signals cause the program to stop by moving the signal names from one list to the other. To move signal names, supply a signal name that currently appears on one list as an argument to the other list.
For example, to move the QUIT and ABRT signals from the catch list to the ignore list:
(dbx) ignore QUIT ABRT
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 Developer Studio 12.5. 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:
Integer divide by zero.
Integer overflow.
Floating-point divide by zero.
Floating-point overflow.
Floating-point underflow.
Floating-point inexact result.
Invalid floating-point operation,
Subscript out of range.
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.
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 Developer Studio 12.5: Numerical Computation Guide.