Why was the division by zero float exception not detected in a function, even an installed handler?

I tried to study signal processing in C when I discovered strange behavior.
When x / = y; performed in the context of the main function performed by the signal handler. But when the same function executable in some handler (bad_func) is ignored, however, the signal handler for SIGFPE is already installed.

Q: Why was SIGFPE not captured by the function of my global signal handler, even _control87 was called?

(MS VC 2010):

#include "stdafx.h" #include <stdlib.h> #include <stdio.h> #include <signal.h> #include <setjmp.h> #include <float.h> jmp_buf g_jb_MainFunc; void hook_zd (int i) { printf("Result :%i\n",i); longjmp(g_jb_MainFunc, 5); } void bad_func(void) { double x = 0., y = 0.; puts("hello1"); //abort(); x /= y; puts("bye1"); } int main(int argc, char* argv[]) { double x = 0., y = 0.; signal(SIGFPE, hook_zd); signal(SIGABRT, hook_zd); puts("hello"); _control87(0, _MCW_EM ); int res; if (! (res = setjmp(g_jb_MainFunc))) { //abort(); //x /= y; bad_func(); } else { printf("Jumped here from: %i\n",res); } puts("bye"); return 0; } 
+1
source share
1 answer

It works for me if I do not compile with optimizations enabled. For example, if I compile it from the command line as cl mysigtest.cpp , exceptions work as expected. But if I compile it cl /O1 mysigtest.cpp , then it will not show an exception.

The parsed code displays the problem:

 ?bad_func@ @YAXXZ (void __cdecl bad_func(void)): 00000000: 68 00 00 00 00 push offset ??_C@ _06CKBHOFLC@hello1 ?$AA@ 00000005: E8 00 00 00 00 call _puts 0000000A: 68 00 00 00 00 push offset ??_C@ _04EEFJMNKA@bye1 ?$AA@ 0000000F: E8 00 00 00 00 call _puts 00000014: 83 C4 08 add esp,8 00000017: C3 ret 

Separation has been optimized. Try it with optimizations turned off or change bad_func to the following. For me, he "defeated" the optimizer:

 double bad_func(double y) { double x = 0.; puts("hello1"); //abort(); x /= y; puts("bye1"); return x; } 

And change the call to it:

 bad_func( 0.0 ); 
+2
source

Source: https://habr.com/ru/post/1313702/


All Articles