svcadm(8)을 검색하려면 섹션에서 8 을 선택하고, 맨 페이지 이름에 svcadm을 입력하고 검색을 누른다.
ieee_handler(3m)
Mathematical Library Functions ieee_handler(3M)
NAME
ieee_handler - manage floating-point exception trap handlers
SYNOPSIS
cc [ flag ... ] file ... -lsunmath -lm [ library ... ]
#include <sunmath.h>
long ieee_handler(const char *action, const char *exception,
sigfpe_handler_type hdl);
DESCRIPTION
This function simultaneously establishes SIGFPE signal handlers and
controls floating-point trap enable modes for the five floating-point
exceptions defined by ANSI/IEEE Std 754-1985. The action and exception
arguments are pointers to case-insensitive strings that specify the
operation to perform. Invalid argument strings and invalid combinations
of arguments yield undefined results.
There are three valid values for action, "get", "set", and "clear", and
seven valid values for exception:
"inexact"
"division" ... division by zero exception
"underflow"
"overflow"
"invalid"
"all" ... all five exceptions above
"common" ... invalid, overflow, and division exceptions
When action is "set", ieee_handler() establishes the handler hdl for
the specified exception(s). hdl may be one of SIGFPE_DEFAULT,
SIGFPE_IGNORE, or SIGFPE_ABORT, or the address of a user-defined SIGFPE
handler. (The macros SIGFPE_DEFAULT, SIGFPE_IGNORE, and SIGFPE_ABORT
and the type sigfpe_handler_type are defined in <floatingpoint.h>.)
If hdl is SIGFPE_DEFAULT or SIGFPE_IGNORE, ieee_handler() disables
trapping on the specified exceptions so that subsequent occurrences of
those exceptions result in the default behavior specified by IEEE 754.
If hdl is SIGFPE_ABORT, ieee_handler() enables trapping on the speci‐
fied exceptions; a subsequent occurrence of those exceptions will cause
the program to dump core by calling abort(3c).
If hdl is the address of a user-defined SIGFPE handler, ieee_handler()
enables trapping on the specified exceptions; subsequent occurrences of
those exceptions will cause the handler to be invoked as though it were
installed via sigaction(2) with the SA_SIGINFO flag set.
When action is "clear", ieee_handler() disables trapping on the speci‐
fied exception(s) and sets the corresponding handler(s) to
SIGFPE_DEFAULT.
When action is "get", ieee_handler() returns the handler associated
with the specified exception (cast to type long). The hdl argument is
ignored.
For actions other than "get", ieee_handler() returns 1 if the requested
action is not available (e.g., the underlying hardware does not support
enabling or disabling trapping on the specified exception) and returns
0 otherwise.
EXAMPLE
To use ieee_handler() to catch a SIGFPE signal caused by a floating
point exception, a program must:
1. Set up a handler with ieee_handler.
2. Perform a floating-point operation that generates the
intended exception.
The following program shows one way to set up a handler for an invalid
operation exception and trigger that exception by attempting to compute
0/0. The handler then substitutes the value of a global variable for
the default result specified by IEEE 754 for this operation. Note that
the handler shown below only works on SPARC systems when the program is
compiled for the SPARC V8 instruction set.
/*
* Sample floating point exception handler. In this example, we trap
* on the invalid operation exception. The handler checks that the
* exception occurred as a result of an attempt to compute 0/0. If so,
* it supplies the value of the global variable zero_over_zero_value
* for the result of the instruction that raised the exception.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sunmath.h>
#include <siginfo.h>
#include <ucontext.h>
double zero_over_zero_value;
void zero_over_zero_handler(int sig, siginfo_t *sip, ucontext_t *uap) {
/* see <sys/reg.h> for structure fpregset_t */
fpregset_t *uc = &uap->uc_mcontext.fpregs;
int i, j, fop, frd, frs1, frs2;
int *con = (int *) &zero_over_zero_value;
/*
* decode the trapping instruction to determine the
* operation and source and destination registers
*/
fop = (uc->fpu_q->FQu.fpq.fpq_instr >> 5) & 0x1ff;
frd = (uc->fpu_q->FQu.fpq.fpq_instr >> 25) & 0x1f;
frs1 = (uc->fpu_q->FQu.fpq.fpq_instr >> 14) & 0x1f;
frs2 = uc->fpu_q->FQu.fpq.fpq_instr & 0x1f;
/*
* check if both rs1 and rs2 are zero (0/0 case)
*/
i = (uc->fpu_fr.fpu_regs[frs2] & 0x7fffffff) |
uc->fpu_fr.fpu_regs[frs2+1];
j = (uc->fpu_fr.fpu_regs[frs1] & 0x7fffffff) |
uc->fpu_fr.fpu_regs[frs1+1];
if (fop == 0x4e) /* instruction is fdivd */
if ((i | j) == 0) { /* both operands are 0 */
/* set rd to zero_over_zero_value */
uc->fpu_fr.fpu_regs[frd] = con[0];
uc->fpu_fr.fpu_regs[frd+1] = con[1];
}
}
}
int main(void) {
double x, w;
int i, k;
sigfpe_handler_type hdl, oldhdl;
/*
* save current invalid operation handler
*/
oldhdl = (sigfpe_handler_type) ieee_handler("get", "invalid",
(sigfpe_handler_type)0);
/*
* set up new handler
*/
hdl = (sigfpe_handler_type) zero_over_zero_handler;
(void) ieee_handler("set", "invalid", hdl);
/*
* compute (k*x)/sin(x) for k=2, x=0.5, 0.4, ..., 0.1, 0.0
*/
k = 2.0;
(void) printf("Evaluating f(x) = (k*x)/sin(x)\n\n");
zero_over_zero_value = k;
for (i = 5; i >= 0; i--) {
x = (double) i * 0.1;
w = (k * x) / sin(x);
(void) printf("\tx=%3.3f\t f(x) = % 1.20e\n", x, w);
}
/*
* restore old handler
*/
(void) ieee_handler("set", "invalid", oldhdl);
return 0;
}
The output from this program looks like this:
Evaluating f(x) = (k*x)/sin(x)
x=0.500 f(x) = 2.08582964293348816000e+00
x=0.400 f(x) = 2.05434596443822626000e+00
x=0.300 f(x) = 2.03031801709447368000e+00
x=0.200 f(x) = 2.01339581906893761000e+00
x=0.100 f(x) = 2.00333722632695554000e+00
x=0.000 f(x) = 2.00000000000000000000e+00
Note that when x = 0, the evaluation of w results in an attempt to com‐
pute 0/0, and an invalid operation exception occurs. The exception han‐
dler substitutes the value 2.0 for the result.
ATTRIBUTES
See attributes(5) for descriptions of the following attributes:
tab() box; lw(2.75i) |lw(2.75i) lw(2.75i) |lw(2.75i)
ATTRIBUTE TYPEATTRIBUTE VALUE _ Interface StabilityCommitted _ MT-Lev‐
elMT-Safe
SEE ALSO
sigaction(2), signal(3c), sigfpe(3C), abort(3c), fex_set_handling(3M),
ieee_flags(3M), attributes(5), siginfo.h(3HEAD), signal.h(3HEAD), ucon‐
text.h(3HEAD)
NOTES
Floating point exception handling routines may be installed using any
of sigfpe(3c), ieee_handler(3M), or fex_set_handling(3M). These methods
may not be mixed within a single program.
On Intel systems, the x87 floating point unit traps whenever an excep‐
tion's trap is enabled (i.e., the exception is "unmasked") and its cor‐
responding flag is raised. Thus, enabling a trap for an exception via
ieee_handler() will provoke a subsequent trap if the exception's flag
is already raised when ieee_handler() is called. To avoid such spurious
traps, a program should clear the flags corresponding to each exception
for which trapping will be enabled before calling ieee_handler(). (The
ieee_flags(3M) function provides one way to clear exception flags.)
Often, a handler installed via ieee_handler() will simply print some
diagnostic information and terminate the program. As the example above
shows, however, a handler may instead return normally, so that control
is returned to the thread that executed the trapping instruction. On
current SPARC systems, execution continues from the instruction follow‐
ing the one that trapped; in this case, the handler must provide a
result to the destination of the trapping instruction so that subse‐
quent computations may proceed using that result. On Intel systems, if
the trapping instruction is an SSE instruction, execution continues by
reissuing the instruction that trapped; in this case, the handler must
either modify the operands of the trapping instruction so that it will
compute a usable result when it is reissued or provide a usable result
to the destination of the trapping instruction and explicitly advance
the saved instruction pointer so that execution will instead resume
from the next instruction past the trapping instruction. If the trap‐
ping instruction is an x87 instruction, execution continues from the
next floating point instruction following the one that trapped; in this
case, the handler must supply a usable result to the destination of the
trapping instruction and adjust the saved x87 register stack as neces‐
sary so that the trapping instruction will appear to have completed.
See the Intel IA-32 architecture manuals for more information. (Note
that fex_set_handling(3M) provides a much simpler interface for han‐
dling a floating point exception and continuing execution.)
Studio 12.6 14 Mar 2009 ieee_handler(3M)