Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Dec 1996 15:43:04 +0100 (MET)
From:      cracauer@cons.org
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/2142: FP mask not saved for signal handlers
Message-ID:  <199612031443.PAA03960@knight.cons.org>
Resent-Message-ID: <199612031510.HAA19198@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         2142
>Category:       kern
>Synopsis:       FP mask not saved for signal handlers
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Dec  3 07:10:02 PST 1996
>Last-Modified:
>Originator:     Martin Cracauer
>Organization:
private
>Release:        FreeBSD 2.1.5
>Environment:

The problem happens on FreeBSD-2.1.5 and NetBSD-1.1. I didn't test on
newer FreeBSD version.

CPUs in question were: P6-200 (FreeBSD) and P-166 (NetBSD).

>Description:

I have an appliation that uses timer interrupts to show a "progress
bar". The signal handler does some floating point calculation and then
uses fputc to stderr. The application is a floating-point intensitive
tabular generator.

The problem that arises is that apparently random values in the
floating point arrays of the main application are set to NaN when the
program completes. When I turn off the "progress bar", and therefore
the timer-called signal handler, no values are incorrect (the
application can't produce a NaN in normal operation). The number of
wrong values grows with the total (wall clock) time the program needs
to complete (and therefore with the number of times the signal handler
is called).

I suspect the FP status register is not correctly saved when the
signal handler is called and as a result an interrupted floating point
calculation will see the 'NaN' flag set in the FP status register
(whatever that is called, don't know anything about the 80387) after
the signal handler returned. Therefore, the result of this operation
will be set to NaN, no matter what the original calculation said.

The same application doesn't show the problem when running on
SPARC/SunOS SPARC/Solaris and SGI/Irix. The problem is worse on the
FreeBSD-P6 than on the NetBSD-P166 (worse means: The number of wrong
values compared to the number of signal handler calls is higher).

>How-To-Repeat:

I'm sorry I can't provide a short example program. I tried to isolate
the problem, but the problem disapears when I replace the original
calculation routines with something thought-out. The application makes
heavy use of subroutine calls returning doubles, maybe that's related
to the problem.

I hope this problem is quite easy to solve for someone familar with
the signal handling code in FreeBSD and the FP registers on the
CPU. If that's not the case, please let me know what I can do. I'm not
really lazy, I just hope it the solution is obvious.


Here's the signal handler code I use: It purpose is to add a number of
blanks to stderr, where is number of blanks shown is the "progress
bar" (80 chars = 100%).

void interrupt(int sig)
{
  int n,i;
  static int wieviel=0;
  
  setitimer(ITIMER_REAL,&timer1,&timerdummy);
  bsdsignal(SIGALRM,(void *)(interrupt));

  n=(int)((double)counter/(double)max*(double)80);
  for (i=wieviel;i<n;i++) {   
    fputc(' ',stderr);   
    wieviel++;
  }
}

And this is the code that sets the timer:

oid cra_settimer(long usec)
{
  timer1.it_interval.tv_sec=0;
  timer1.it_interval.tv_usec=0;

  timer1.it_value.tv_sec=0;
  timer1.it_value.tv_usec=300000;

  setitimer(ITIMER_REAL,&timer1,&timerdummy);

  bsdsignal(SIGALRM,interrupt);
}

>Fix:
	
I suspect one has to add a proper saving of the floating point status
register to the signal handler code.



>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199612031443.PAA03960>