Q: getting at the FPU status in a SIGFPE handler

Q: getting at the FPU status in a SIGFPE handler

Post by Christoph Baumh » Thu, 10 Aug 1995 04:00:00



environment: kernel 1.2.4, libc.4.5.26, P90

I'm trying to write a SIGFPE handler to catch numeric exceptions
(overflow...) and to do some recovery. On a numeric exception, the
SIGFPE handler is invoked successfully, and I can get at the register
values via sigcontext_struct, but no coprocessor state is in there.

The coprocessor state is saved (in math_error() in arch/i386/kernel/
traps.c), and if I could get the task_struct for the current process,
the saved coprocessor state would be in there. Is it possible to get
at the task_struct of the current process (or, that would be sufficient
for me, at current->tss.i387.hard) in a (user level) signal handler?
Unfortunately, the fsave instruction in math_error() clears the
coprocessor control and status words, so I can not get the information
directly from the coprocessor.

Thank you for any help,
Christoph.
--
Christoph Baumhof - Institut fuer Angewandte Mathematik - Uni Karlsruhe

www   : http://www.uni-karlsruhe.de/~ae60/index.html

 
 
 

Q: getting at the FPU status in a SIGFPE handler

Post by Peter Dalgaar » Fri, 11 Aug 1995 04:00:00



>environment: kernel 1.2.4, libc.4.5.26, P90

>I'm trying to write a SIGFPE handler to catch numeric exceptions
>(overflow...) and to do some recovery. On a numeric exception, the
>SIGFPE handler is invoked successfully, and I can get at the register
>values via sigcontext_struct, but no coprocessor state is in there.

>The coprocessor state is saved (in math_error() in arch/i386/kernel/
>traps.c), and if I could get the task_struct for the current process,
>the saved coprocessor state would be in there. Is it possible to get
>at the task_struct of the current process (or, that would be sufficient
>for me, at current->tss.i387.hard) in a (user level) signal handler?
>Unfortunately, the fsave instruction in math_error() clears the
>coprocessor control and status words, so I can not get the information
>directly from the coprocessor.

It IS possible and I have the code to prove it. I'll mail it to you when I get
home. This is going into my libieee extentions, which I'll get done whenever
the Danish summer returns to normal (rainy) behaviour.

(If you look closer, you will see that the kernel does some curious stuff with
the FPU state before passing control to the signal handler. The control and
status words get copied to the top bits of some other registers, where you'll
find them again if you do an fsave instruction in the signal handler.)

--
   O_   ---- Peter Dalgaard
  c/ /'  --- Dept. of Biostatistics
 ( ) \( ) -- University of Copenhagen


 
 
 

1. Getting FPU status in SIGFPE handler -- must hack kernel?

Problem: Signal handler can't get the FPU error flags after a SIGFPE.

OS version: 1.2.13, on a Pentium machine.

Detailed description:

    I do a lot of numerical work on my Linux box (that's one of my
main justifications for buying it), and I find that the handling
of floating-point errors is, let us say, a little primitive:
You get an IOT trap.

    I have tried to get more info by installing a signal handler.
However, I cannot figure out how to find out what sort of an
exception occurred (overflow, divide-by-zero, etc.)

    I have dug through the kernel sources, and find that "math_error",
in i386/kernel/traps.c saves the FPU state in the task's task_struct
(component task.tss.i387.hard), but I find no way to get at that
from user mode.  "setup_frame", in i386/kernel/signal.c, sets
up a frame (i.e., argument list) for the signal handler, but the
part that arguably would point to the FPU state (frame+21) is
set to 0.

Questions:

(1) Has anyone done any work in this area?  Is there a way to get
    the saved FPU state without hacking the kernel?

(2) Are there any proposals for improving the situation?

(3) If not, what would more experienced Linux developers say to
    the following two ideas for getting the info:

    (a) Modify setup_frame (and its caller?) to copy the FPU
        state onto the stack, after the frame, and put a pointer
        to it into "frame+21", if-and-only-if the signal number
        is SIGFPE.  IMHO, this is the cleanest way to do it,
        but I might need some hand-holding, as I don't know
        what to do if I make the stack extend into non-existent
        memory in the process.

        Moreover, I would be inclined to offer such a fix to
        the general Linux development effort.  To do so, I would
        need to have some idea whether and how the signal handler
        calling interface may have changed.

    (b) Add a new system call, to retrieve the FPU state.  This
        would be easier, but an ugly hack.

If anyone follows-up to this posting, please send me a copy,
as articles often expire here before I have a chance to read them.

--

Courant Institute,NYU,USA     ...!cmcl2!cims.nyu.edu!mckenney   (UUCP)

2. OpenWindows in TrueColor??

3. Move "used FPU status" into new non-atomic thread_info->status field.

4. WD 9197 SCSi card?

5. Problem compiling programs for x

6. FPU precision & signal handlers (bug?)

7. Help: kernel messages into a Sybase dataserver errorlog.

8. Handlers, Handlers, Handlers

9. acroread4 gets SIGFPE

10. Cyrix 5x86 FPU better than AMD 5x86 FPU?

11. Add new handlers (similar to http-status)

12. Getting signal handler function address?!