View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0029171 | Open CASCADE | OCCT:Foundation Classes | public | 2017-10-01 19:40 | 2018-06-29 21:19 |
Reporter | Assigned To | bugmaster | |||
Priority | normal | Severity | minor | ||
Status | closed | Resolution | fixed | ||
Target Version | 7.3.0 | Fixed in Version | 7.3.0 | ||
Summary | 0029171: Foundation Classes - C signal handler does not work on MinGW | ||||
Description | When OCCT is built with MinGW, C signal handling apparently does not work. This can be seen by running tests: about 40 of them fail with segmentation violation. Here is (incomplete) list of tests failed in my experiment: Failed boolean bfuse_complex C4 C5 bugs fclasses bug6143 bug23497 bug28829 bugs iges bug133_1 bugs modalg_6 bug26938_1 bug26938_2 bug26938_3 bug27021 bug27033 bugs modalg_7 bug25939 bugs moddata_1 bug22165 bugs step bug11856 bug26451 bugs xde bug22898 de iges_2 E4 de step_3 F3 offset wire_closed_inside_0_005 H6 offset wire_closed_inside_0_025 H6 offset wire_closed_inside_0_075 H6 offset wire_closed_outside_0_005 H6 offset wire_closed_outside_0_025 H6 offset wire_closed_outside_0_075 H6 tools dfbrowser A1 A2 A3 A4 A5 A6 tools shapeview A1 A2 tools vinspector A1 A2 Improvements bugs modalg_7 bug25879 bug27784 de step_3 D8 | ||||
Steps To Reproduce | test bugs fclasses bug6143 test bugs fclasses bug28829 | ||||
Tags | No tags attached. | ||||
Test case number | Not required | ||||
|
MinGw is known to have no support of Windows structural excpetions (SEH), thus we cannot use the same method of converting signals to exceptions as with MSVC (code is compiled with option /EHa to support SEH, and C++ exceptions are thrown directly from low-level handler). Nevertheless, formally MinGw supports standard C/C++ signal() function, as well as setjmp()/longjmp() functions, so we should be able to use the same approach as on Linux (C signal handler function uses longjump() to get to the context of the current thread, where C++ exception gets thown -- see macro OCC_CATCH_SIGNALS). Alas, this does not work. The behavior of MinGw with respect to signals is really weird. In the distilled environment signal() seems to work properly, at least the handler gets called on access violation (tested by writing to Null pointer) and integer division by zero (even if FPE signal is generated in that case). However, generation of signals gets totally broken after any non-empty try{} block... Here is minimal reproducer: @code #include <signal.h> #include <stdio> int iii = 0; static void SIGWntHandler (int signum)//sub_code) { cout << "In SIGWntHandler, signum = " << signum << std::endl; } int main (void) { std::cout << "Entered main(), arming signals..." << std::endl; if (signal (SIGSEGV, (void(*)(int))SIGWntHandler) == SIG_ERR) cout << "signal(OSD::SetSignal) error\n"; if (signal (SIGFPE, (void(*)(int))SIGWntHandler) == SIG_ERR) cout << "signal(OSD::SetSignal) error\n"; if (signal (SIGILL, (void(*)(int))SIGWntHandler) == SIG_ERR) cout << "signal(OSD::SetSignal) error\n"; try { std::cout << "In try{} block..." << std::endl; } catch(char*) {} std::cout << "Doing bad things to cause signal..." << std::endl; iii = 1 / iii; char*p = 0; p[0] = '\0'; std::cout << "We are too lucky..." << std::endl; return 0; } @endcode Commenting out try block makes handler working. Resetting signals after catch() does not help; location of the bad code (inside or outside of the try block) makes no difference. In my case, I experimented with DRAW main, thus the code was built with standard options for OCCT: CXX_FLAGS = -std=gnu++0x -fexceptions -fPIC -Wall -Wextra -O2 I have Windows 10 Pro 64-bit; MinGW-W64-builds-4.3.3 with GCC 7.1 (x86_64-win32-sjlj-rev2) |
|
It should be noted that with MSVC 10 it seems to be not possible to get handler set by signal() executed. I have tried this in the past, and now trying to run the above code (with or without try) I never get handler called (tried both /EHa and /EHsc). This does not cause much problems since we use SEH for error handling. |
|
The only method that seems to work for handling access violation under MinGW is vectored exception handler that can be set using AddVectoredExceptionHandler(). However, throwing C++ exception from it leads to immediate abort; longjump works but seems to not clear exception sttaus so that the same handler gets invoked again and / or process hangs. |
|
Here the guy describes implementation of __try / __catch with MinGW: https://habrahabr.ru/post/280304/ |
|
I discovered that GCC supports different methods of exception handling, and MinGW-64 binaries I have been using so far are built with option "sjlj", which stands for "setjmp/longjmp". When using build "seh", the problem described in 0029171:0071278 disappears. |
|
Branch CR29171 has been created by abv. SHA-1: 688e3a8cdfc96f9df842cadaef1614f732ba9c9a Detailed log of new commits: Author: abv Date: Sat Oct 7 19:26:38 2017 +0300 0029171: Foundation Classes - C signal handler does not work on MinGW Setting signal handler is enabled in OSD::SetSignal() for MinGW (works only for SEH builds of MinGW, not for SJLJ builds). Due to absence of function _set_se_translator(), handler is set using C signal() function and thus is called asynchronously. Macro OCC_CONVERT_SIGNALS is enabled for MinGW build to support converting signals to C++ exceptions using long jumps (the same as on Linux). Code raising exceptions in OSD::SetSignal() is corrected to use method Jump() instead of C++ throw. |
|
Fix is pushed to CR29171 and tested (see Jenkins job CR29171-master-abv); please review. Note that it will work only if MinGW is built with SEH exceptions (not SJLJ). |
|
- throw Standard_NumericError(msg); + Standard_NumericError::NewInstance (msg)->Jump(); this change affects MSVC builds as well - introducing extra dynamic allocation and transient Jump() call instead of direct throw. It would be better avoiding this. |
|
Remarks are accounted for, please confirm |
|
Please test the patch. |
|
Jenkins tests passed, see job CR29171-master-abv |
|
Combination - OCCT branch :CR29171 SHA-1: 4106626299ee6144f72e403688f5f9191aa4c34a Products branch : master was compiled on Linux, MacOS and Windows platforms and tested on optimize mode. Number of compiler warnings: No new/fixed warnings Regressions/Differences/Improvements: No regressions/differences CPU differences: No differences that require special attention Image differences : No differences that require special attention Memory differences : No differences that require special attention |
|
Branch CR29171 has been deleted by kgv. SHA-1: 4106626299ee6144f72e403688f5f9191aa4c34a |
occt: master 9e479117 2017-10-07 16:26:38
Committer: bugmaster Details Diff |
0029171: Foundation Classes - C signal handler does not work on MinGW Setting signal handler is enabled in OSD::SetSignal() for MinGW (works only for SEH builds of MinGW, not for SJLJ builds). Due to absence of function _set_se_translator(), handler is set using C signal() function and thus is called asynchronously. Macro OCC_CONVERT_SIGNALS is enabled for MinGW build to support converting signals to C++ exceptions using long jumps (the same as on Linux). Code raising exceptions in OSD::SetSignal() is corrected to use method Jump() instead of C++ throw. |
Affected Issues 0029171 |
|
mod - adm/cmake/occt_defs_flags.cmake | Diff File | ||
mod - src/OSD/OSD_signal.cxx | Diff File |
Date Modified | Username | Field | Change |
---|---|---|---|
2017-10-01 19:40 |
|
New Issue | |
2017-10-01 19:40 |
|
Assigned To | => abv |
2017-10-07 10:52 |
|
Note Added: 0071278 | |
2017-10-07 10:52 |
|
Target Version | 7.4.0 => Unscheduled |
2017-10-07 11:45 |
|
Note Added: 0071279 | |
2017-10-07 13:49 |
|
Note Added: 0071280 | |
2017-10-07 14:59 |
|
Note Added: 0071281 | |
2017-10-07 23:01 |
|
Note Edited: 0071278 | |
2017-10-07 23:14 |
|
Note Added: 0071282 | |
2017-10-08 19:42 | git | Note Added: 0071283 | |
2017-10-09 09:33 |
|
Note Added: 0071288 | |
2017-10-09 09:33 |
|
Status | new => resolved |
2017-10-09 09:33 |
|
Target Version | Unscheduled => 7.3.0 |
2017-10-09 09:33 |
|
Steps to Reproduce Updated | |
2017-10-09 10:39 |
|
Assigned To | abv => kgv |
2017-10-09 10:52 | kgv | Note Added: 0071293 | |
2017-10-09 12:19 | kgv | Assigned To | kgv => abv |
2017-10-09 12:19 | kgv | Status | resolved => assigned |
2017-10-09 21:48 |
|
Note Added: 0071311 | |
2017-10-09 21:48 |
|
Status | assigned => resolved |
2017-10-09 21:48 |
|
Assigned To | abv => kgv |
2017-10-09 22:08 | kgv | Note Added: 0071312 | |
2017-10-09 22:08 | kgv | Assigned To | kgv => bugmaster |
2017-10-09 22:08 | kgv | Status | resolved => reviewed |
2017-10-10 08:43 |
|
Note Added: 0071315 | |
2017-10-10 10:57 | bugmaster | Test case number | => Not required |
2017-10-10 10:58 | bugmaster | Note Added: 0071327 | |
2017-10-10 10:58 | bugmaster | Status | reviewed => tested |
2017-10-12 19:00 | bugmaster | Changeset attached | => occt master 9e479117 |
2017-10-12 19:00 | bugmaster | Status | tested => verified |
2017-10-12 19:00 | bugmaster | Resolution | open => fixed |
2017-10-14 12:20 | git | Note Added: 0071477 | |
2018-06-29 21:15 |
|
Fixed in Version | => 7.3.0 |
2018-06-29 21:19 |
|
Status | verified => closed |