fex_set_log, fex_get_log, fex_set_log_depth,
fex_get_log_depth, fex_log_entry - log retrospective diag-
nostics for floating point exceptions
cc [ flag ... ] file ... -R/opt/SUNWspro/lib
-L/opt/SUNWspro/lib -lm9x [ library ... ]
int fex_set_log(FILE *fp);
int fex_set_log_depth(int depth);
void fex_log_entry(const char *msg);
fex_set_log(fp) enables logging of retrospective diagnostic
messages regarding floating point exceptions to the file
specified by fp. If fp is NULL, logging is disabled. When
a program starts, logging is initially disabled.
The occurrence of any of the twelve exceptions listed in
fex_set_handling(3M) constitutes an event that may be
logged. To prevent the log from becoming exhorbitantly
long, the logging mechanism eliminates redundant entries by
two methods. First, each exception is associated with a
site in the program. The site is identified by the address
of the instruction that caused the exception together with a
stack trace. Only the first exception of a given type to
occur at a given site will be logged. Second, when
FEX_NONSTOP handling mode is in effect for some exception,
only those occurrences of that exception that set its previ-
ously clear flag are logged. (Clearing a flag using
feclearexcept() allows the next occurrence of the exception
to be logged provided it does not occur at a site at which
it was previously logged.)
Note that each of the different types of invalid operation
exceptions may be logged at the same site. Because all
invalid operation exceptions share the same flag, however,
of those types for which FEX_NONSTOP mode is in effect, only
the first exception to set the flag will be logged. (When
the invalid operation exception is raised by a call to
feraiseexcept() or feupdateenv(), which type of invalid
operation is logged depends on the implementation.)
If an exception results in the creation of a log entry, the
entry is created at the time the exception occurs and before
any exception handling actions selected via
fex_set_handling(3M) are taken. (In particular, the log
entry is available even if the program terminates as a
result of the exception.) The log entry shows the type of
exception, the address of the instruction that caused it,
how it will be handled, and the stack trace. If symbols are
available, the address of the excepting instruction and the
addresses in the stack trace are followed by the names of
the corresponding symbols.
fex_get_log() returns the current log file.
fex_set_log_depth(depth) sets the maximum depth of the stack
trace recorded with each exception to depth stack frames.
The default depth is 100.
fex_get_log_depth() returns the current maximum stack trace
fex_log_entry(msg) adds a user-supplied entry to the log.
The entry includes the string pointed to by msg and the
stack trace. Like entries for floating point exceptions,
redundant user-supplied entries are eliminated: only the
first user-supplied entry with a given msg to be requested
from a given site will be logged. (For the purpose of a
user-supplied entry, the site is defined only by the stack
trace, which begins with the function that called
fex_set_log returns a nonzero value if logging is enabled or
disabled accordingly and returns zero otherwise.
fex_set_log_depth returns a nonzero value if the requested
stack trace depth is established (regardless of whether log-
ging is enabled) and returns zero otherwise.
The following example shows the output generated when a
floating point overflow occurs in sscanf().
* enable logging of retrospective diagnostics
* establish default handling for overflows
(void) fex_set_handling(FEX_OVERFLOW, FEX_NONSTOP, NULL);
* trigger an overflow in sscanf
(void) sscanf("1.0e+400", "%lf", &x);
The output from the preceding program reads:
Floating point overflow at 0xef71cac4 __base_conversion_set_exception, nonstop mode
(Recompiling the program or running it on another system may
produce different text addresses from those shown above.)
See attributes(5) for descriptions of the following attri-
| ATTRIBUTE TYPE | ATTRIBUTE VALUE |
| Availability | SPROm9xs |
| Interface Stability| Stable |
| MT-Level | MT-Safe (see Notes)|
feclearexcept(3M), fegetenv(3M), fex_set_handling(3M),
Numerical Computation Guide
All threads in a process share the same log file. Each call
to fex_set_log() preempts the previous one.
In addition to the log file itself, two additional file
descriptors are used during the creation of a log entry in
order to obtain symbol names from the executable and any
shared objects it uses. These file descriptors are relin-
quished once the log entry is written. If the file descrip-
tors cannot be allocated, symbols names are omitted from the
The functions described on this page automatically install
and deinstall SIGFPE handlers and set and clear the trap
enable mode bits in the floating point status register as
needed. If a program uses these functions and attempts to
install a SIGFPE handler or control the trap enable mode
bits independently, the resulting behavior is not defined.
As described in fex_set_handling(3M), when a handling func-
tion installed in FEX_CUSTOM mode is invoked, all exception
traps are disabled (and will not be reenabled while SIGFPE
is blocked). Thus, retrospective diagnostic messages are
not logged for exceptions that occur within such a handler.
As shown in the synopsis, the recommended way to link with
libm9x using cc is to specify
-Rinstall-path/lib -Linstall-path/lib -lm9x
on the command line, where install-path refers to the loca-
tion in which the compilers are installed (/opt/SUNWspro by
default). See the Numerical Computation Guide for addi-
tional information about linking with libm9x.