-fp-trap-all=all generates SIGFPE in log10

-fp-trap-all=all generates SIGFPE in log10

Bild des Benutzers mfactor

Hello all,

I'm testing the icpc compiler and found a curious case: if I compile the code below

   

#include <math.h>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fenv.h>
using namespace std;
int main() {
feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
 cout << log10(0.0049999999992) <<endl;
return 0;
}

If I compile it with icpc log10.cxx -lm -g, it runs ok and gives the right answer (-2.30103), but if I enable icpc log10.cxx -lm -g -fp-trap-all=all , I get a SIGFPE. I'm using icpc version icpc (ICC) 13.0.0 20120731 on Linux x86_64. Any ideas?

Cheers 

24 Beiträge / 0 neu
Letzter Beitrag
Nähere Informationen zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.
Bild des Benutzers Sergey Kostrov

>>...cout << log10(0.0049999999992)...

Please try to do another test with CRT-function printf or separate calls to log10 and cout.

Actually this is the 3rd time I see a problem when cout is used with some CRT-function from math.h header file. Thanks in advance for results of your additional test.

Bild des Benutzers mfactor

Hello Sergey,

#include <math.h>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fenv.h>
int main() {
 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
 double x = 0;
 x = log10(0.0049999999992) ;
 printf("%f",x);
 return 0;
}

Exactly same behavior. With g++ 4.6.3 exactly the same code does not generate a SIGFPE.

Cheers

Bild des Benutzers mfactor

Hello again,

I managed to narow it down a little bit more. An ANSI C version of the same code compiled with gcc, icc AND icpc gives no SIGFPE:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <fenv.h>
int main() {
 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
 double x = 0;
 x = log10(0.0049999999992) ;
 printf("%f",x);
 return 0;
}
 

icc log10.cxx  -g -fp-trap-all=all - no SIGFPE - ok
icpc log10.cxx  -g -fp-trap-all=all  - no SIGFPE - ok
gcc log10.cxx -g -lm - no SIGFPE - ok
 

This code also compiles with all the options above and runs without SIGFPE:

#include <math.h>
#include <cstdio>
#include <cstdlib>
#include <fenv.h>
int main() {
 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
 double x = 0;
 x = log10(0.0049999999992) ;
 printf("%f",x);
 return 0;
}

But if <iostream> is included, I get the SIGFPE with icpc and ftrap, even without any mention to cout or printf.

Cheers

Bild des Benutzers Sergey Kostrov

Thank you. Take into account that on a 64-bit platform with Intel CPUs a precision control can not be used and this is by design. You'll need to do a set of tests like:

Debug Configuration

- For 32-bit platform with "iostream"
- For 32-bit platform without "iostream"
- For 64-bit platform with "iostream"
- For 64-bit platform without "iostream"

Release Configuration

- For 32-bit platform with "iostream"
- For 32-bit platform without "iostream"
- For 64-bit platform with "iostream"
- For 64-bit platform without "iostream"

and with all the rest variants of the test case (!).

If some code in "iostream" ( possibly static which does some initialization ) tries to change a precision of the Floating-Point Unit with a CRT-function _control87 ( or similar ) on a 64-bit platform than an exception will be thrown and this is what you see.

Also, it is not clear for me on what platform you're doing your tests. You've metioned ''...Linux x86_64...". So, did you get the exception on 32-bit platform or 64-bit platform?

Bild des Benutzers iliyapolak

>>>You've metioned ''...Linux x86_64...".>>>

That's mean that 64-bit Linux version is used.

Bild des Benutzers Tim Prince

Original post did leave unspecified whether the 32-bit ia32 or 64-bit Intel64 compiler was in use.  As g++ 4.6.3 was mentioned, one might expect a recent linux distro where it's easier to install the Intel64 compiler than ia32, but this is all speculation.

I don't find -fp-trap-all listed as a g++ option, so I might suspect g++ ignored it.

As I've seen log10() implemented as a macro in terms of log(), the traditional comparison between icpc and g++ pre-processed files also might be relevant, along with the traditional icpc -V and g++ -v quotations.

Bild des Benutzers Sergey Kostrov

>>...As I've seen log10() implemented as a macro in terms of log()...

I think it needs to be confirmed by 'mfactor' user if something like this
...
#define log10( x ) ( log( x ) / log( 10.0L ) )
...
is used. However, it doesn't bring clarity on all the rest our questions.

Bild des Benutzers mfactor

Hi all,

Some informations: running Ubuntu 12.10 with kernel

Linux voyager 3.5.0-25-generic #38-Ubuntu SMP Mon Feb 18 23:27:42 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

So I confirm this is a 64 bits platform. g++ -v prints out

COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper
Destino: x86_64-linux-gnu
Configurado com: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.7.2-2ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Modelo de thread: posix
versão do gcc 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1)

icpc -V prints

Intel(R) C++ Compiler XE for applications running on IA-32, Version 13.0.0.079 Build 20120731
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.

and

Intel(R) C++ Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 13.0.0.079 Build 20120731
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.

Depending the "source compilevars.sh" I use (ia32 or intel64).

And now, for the tests:

1) g++ -m32 -g log10.cxx -lm with iostream: OK

2) g++ -m64 -g log10.cxx -lm with iostream: OK

3) g++ -m32 -g log10.cxx -lm without iostream: OK

4) g++ -m64 -g log10.cxx -lm without iostream: OK

Tests with Intel compiler:

1) icpc -m64 -fp-trap-all=all -g log10.cxx with iostream: *** SIGFPE ***

2) icpc -m64 -fp-trap-all=all -g log10.cxx without iostream: OK

3) icpc -m64  -g log10.cxx with iostream: OK

4) icpc -m64  -g log10.cxx without iostream: OK

5) icpc -m32 -g log10.cxx with iostream: OK

6) icpc -m32 -g log10.cxx without iostream: OK

7) icpc -m32 -fp-trap-all=all -g log10.cxx with iostream: *** SIGFPE ***

8) icpc -m32 -fp-trap-all=all -g log10.cxx without iostream: OK

I'm not using any macros whatsoever. The test code follows:

#include <math.h>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fenv.h>
using namespace std;
int main() {
feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
double x = 0.0; 
x = log10(0.0049999999992) ;
printf("%f",x);
return 0;
}

Hope this helps.

Bild des Benutzers Sergey Kostrov

>>Tests with Intel compiler:
>>
>>1) icpc -m64 -fp-trap-all=all -g log10.cxx with iostream: *** SIGFPE ***
>>...
>>7) icpc -m32 -fp-trap-all=all -g log10.cxx with iostream: *** SIGFPE ***

Thank you for these test results.

Bild des Benutzers Sergey Kostrov

There is some inconsistency with your tests for g++ because you didn't use option fp-trap-all. If that option is not supported than another two could be used to verify that the problem with SIGFPE exception doesn't exist for g++:

-ftrapping-math - Assume floating-point operations can trap

-ftrapv - Trap for signed overflow in addition, subtraction and multiplication

Thanks in advance.

Bild des Benutzers mfactor

Hello Sergey,

The function feenableexcept should catch this kind of errors in C++, with these options:

1) g++ -m32 -ftrapping-math -ftrapv -fsignaling-nans -g log10.cxx with with iostream: OK

2) g++ -m64 -ftrapping-math -ftrapv -fsignaling-nans -g log10.cxx with with iostream: OK

3) g++ -m32 -ftrapping-math -ftrapv -fsignaling-nans -g log10.cxx with without iostream: OK

4) g++ -m64 -ftrapping-math -ftrapv -fsignaling-nans -g log10.cxx with without iostream: OK

I currently don't have another platform to do the tests. Can you compile the code that I submitted? Does it run? Does it give SIGFPE?

Cheers

Bild des Benutzers Sergey Kostrov

>>...Can you compile the code that I submitted?

Yes.

>>...Does it run? Does it give SIGFPE?

I'll provide a report for two Intel C++ compilers, versions 12 and 13 ( 32-bit and 64-bit ) on two Windows platforms ( XP and 7 ).

Bild des Benutzers Sergey Kostrov

Here are results for 32-bit test application on Windows XP:

[ Windows XP 32-bit - Debug - with 'iostream' ]

..\FpTrapAll>icl /MDd /Qfp-trap-all=all /D_DEBUG Main.cpp
Intel(R) C++ Compiler XE for applications running on IA-32, Version 12.1.3.300 Build 20120130
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
Main.cpp
Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.
-out:Main.exe
Main.obj

..\FpTrapAll>Main.exe
-2.301030

Note: No Exceptions

[ Windows XP 32-bit - Debug - without 'iostream' ]

..\FpTrapAll>icl /MDd /Qfp-trap-all=all /D_DEBUG Main.cpp
Intel(R) C++ Compiler XE for applications running on IA-32, Version 12.1.3.300 Build 20120130
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
Main.cpp
Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.
-out:Main.exe
Main.obj

..\FpTrapAll>Main.exe
-2.301030

Note: No Exceptions

[ Windows XP 32-bit - Release - with 'iostream' ]

..\FpTrapAll>icl /MD /Qfp-trap-all=all /DNDEBUG Main.cpp
Intel(R) C++ Compiler XE for applications running on IA-32, Version 12.1.3.300 Build
20120130
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
Main.cpp
Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.
-out:Main.exe
Main.obj

..\FpTrapAll>Main.exe
-2.301030

Note: No Exceptions

[ Windows XP 32-bit - Release - without 'iostream' ]

..\FpTrapAll>icl /MD /Qfp-trap-all=all /DNDEBUG Main.cpp
Intel(R) C++ Compiler XE for applications running on IA-32, Version 12.1.3.300 Build 20120130
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
Main.cpp
Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.
-out:Main.exe
Main.obj

..\FpTrapAll>Main.exe
-2.301030

Note: No Exceptions

Bild des Benutzers Sergey Kostrov

I'll continue investigation with Intel C++ compiler ( v13 / 32-bit and 64-bit ) on Windows 7 Professional ( 64-bit ) some time later this week.

Bild des Benutzers Sergey Kostrov

Could you upload cstdio, cstdlib and iostream header files ( of course GCC versions ) for review?

Bild des Benutzers mfactor
Bild des Benutzers mfactor

I posted the links, put it appeared that my comment was flagged for review. 

Bild des Benutzers Sergey Kostrov

Here are results for a 32-bit test application on Windows 7 Professional ( 64-bit ):

[ Windows 7 Professional - 32-bit application - Debug - with 'iostream' ]

..\FpTrapAll>icl /MDd /Qfp-trap-all=all /D_DEBUG Main.cpp
Intel(R) C++ Compiler XE for applications running on IA-32, Version 13.0.0.089 Build 20120731
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
Main.cpp
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
-out:Main.exe
Main.obj

..\FpTrapAll>Main.exe
-2.301030

Note: No Exceptions

[ Windows 7 Professional - 32-bit application - Debug - without 'iostream' ]

..\FpTrapAll>icl /MDd /Qfp-trap-all=all /D_DEBUG Main.cpp
Intel(R) C++ Compiler XE for applications running on IA-32, Version 13.0.0.089 Build 20120731
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
Main.cpp
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
-out:Main.exe
Main.obj

..\FpTrapAll>Main.exe
-2.301030

Note: No Exceptions

[ Windows 7 Professional - 32-bit application - Release - with 'iostream' ]

..\FpTrapAll>icl /MD /Qfp-trap-all=all /DNDEBUG Main.cpp
Intel(R) C++ Compiler XE for applications running on IA-32, Version 13.0.0.089 Build 20120731
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
Main.cpp
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
-out:Main.exe
Main.obj

..\FpTrapAll>Main.exe
-2.301030

Note: No Exceptions

[ Windows 7 Professional - 32-bit application - Release - without 'iostream' ]

..\FpTrapAll>icl /MD /Qfp-trap-all=all /DNDEBUG Main.cpp
Intel(R) C++ Compiler XE for applications running on IA-32, Version 13.0.0.089 Build 20120731
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
Main.cpp
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
-out:Main.exe
Main.obj

..\FpTrapAll>Main.exe
-2.301030

Note: No Exceptions

Bild des Benutzers Sergey Kostrov

Here are results for a 64-bit test application on Windows 7 Professional ( 64-bit ):

[ Windows 7 Professional - 64-bit application - Debug - with 'iostream' ]

..\FpTrapAll>icl /MDd /Qfp-trap-all=all /D_DEBUG Main.cpp
Intel(R) C++ Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 13.0.0.089 Build 20120731
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
Main.cpp
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
-out:Main.exe
Main.obj

..\FpTrapAll>Main.exe
-2.301030

Note: No Exceptions

[ Windows 7 Professional - 64-bit application - Debug - without 'iostream' ]

..\FpTrapAll>icl /MDd /Qfp-trap-all=all /D_DEBUG Main.cpp
Intel(R) C++ Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 13.0.0.089 Build 20120731
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
Main.cpp
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
-out:Main.exe
Main.obj

..\FpTrapAll>Main.exe
-2.301030

Note: No Exceptions

[ Windows 7 Professional - 64-bit application - Release - with 'iostream' ]

..\FpTrapAll>icl /MD /Qfp-trap-all=all /DNDEBUG Main.cpp
Intel(R) C++ Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 13.0.0.089 Build 20120731
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
Main.cpp
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
-out:Main.exe
Main.obj

..\FpTrapAll>Main.exe
-2.301030

Note: No Exceptions

[ Windows 7 Professional - 64-bit application - Release - without 'iostream' ]

..\FpTrapAll>icl /MD /Qfp-trap-all=all /DNDEBUG Main.cpp
Intel(R) C++ Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 13.0.0.089 Build 20120731
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
Main.cpp
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
-out:Main.exe
Main.obj

..\FpTrapAll>Main.exe
-2.301030

Note: No Exceptions

Bild des Benutzers Sergey Kostrov

My conclusion:

I couldn't reproduce the problem with SIGFPE exception on Windows 32-bit and 64-bit platforms with Intel C++ compilers ( v12 and v13 ). It would be nice to have additional verification by Intel software engineers.

[ Source code of All tests ]

#include "math.h"
#include "cstdio"
#include "cstdlib"
#include "iostream"
#include "fenv.h"

using namespace std;

int main( void )
{
feenableexcept( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
double x = 0.0L;
x = log10( 0.0049999999992 );
printf( "%f", x );
return ( int )0;
}

Note: I'll take a look at sources for the STL header files you've provided. Thank you.

Bild des Benutzers mfactor

Hello Sergey,

Thanks for your time. I'll wait the answer from the Intel Engineers. 

Cheers

Bild des Benutzers Sergey Kostrov

>>...
>>gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-3.4/iostream-source.html
>>gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-3.4/classstd_1_1basic__iostream.html
>>gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-3.3/cstdlib-source.html

I didn't find anything that could control a state of Floating-Point Unit or possibly related to SIGFPE exception. While we're waiting for a response from Intel I'll think what else could be done.

Bild des Benutzers Sergey Kostrov

Here are a couple of notes:

- SIGFPE exception has to be raised by CRT-function signal

- If you have a complete set of sources of STL and CRT libraries for GCC you need to find all calls to signal function ( I don't expect too many ) and you could be closer to understanding what is wrong

- These calls could look like:
...
if( signal( SIGFPE, ( void ( cdecl * )( int ) )SignalHandler ) == SIGERR )
{
...
printf( "Failed to Set a Handler for Detection of a Floating-Point Error\n" );
...
}
...
and SignalHandler could look like:
...
void cdecl SignalHandler( int iSignalCode, int iSignalExtCode )
{
...
g_iSignalCode = iSignalCode; // Saves the Signal & Signal Extended Codes
g_iSignalExtCode = iSignalExtCode;

_reset87(); // Resets FPU
longjmp( jmpbuf, -1 ); // Restores calling environment, returns to 'setjump' with a code -1
...
}
...

- Take into account that processing of exceptions with signal is a Very Old Technology and it was replaced by a modern Try-Catch exceptions handling.

Melden Sie sich an, um einen Kommentar zu hinterlassen.