View Issue Details

IDProjectCategoryView StatusLast Update
0029171Open CASCADEOCCT:Foundation Classespublic2018-06-29 21:19
ReporterabvAssigned Tobugmaster  
PrioritynormalSeverityminor 
Status closedResolutionfixed 
Target Version7.3.0Fixed in Version7.3.0 
Summary0029171: Foundation Classes - C signal handler does not work on MinGW
DescriptionWhen 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 Reproducetest bugs fclasses bug6143
test bugs fclasses bug28829
TagsNo tags attached.
Test case numberNot required

Activities

abv

2017-10-07 10:52

manager   ~0071278

Last edited: 2017-10-07 23:01

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)

abv

2017-10-07 11:45

manager   ~0071279

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.

abv

2017-10-07 13:49

manager   ~0071280

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.

abv

2017-10-07 14:59

manager   ~0071281

Here the guy describes implementation of __try / __catch with MinGW:
https://habrahabr.ru/post/280304/

abv

2017-10-07 23:14

manager   ~0071282

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.

git

2017-10-08 19:42

administrator   ~0071283

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.

abv

2017-10-09 09:33

manager   ~0071288

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).

kgv

2017-10-09 10:52

developer   ~0071293

-      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.

abv

2017-10-09 21:48

manager   ~0071311

Remarks are accounted for, please confirm

kgv

2017-10-09 22:08

developer   ~0071312

Please test the patch.

abv

2017-10-10 08:43

manager   ~0071315

Jenkins tests passed, see job CR29171-master-abv

bugmaster

2017-10-10 10:58

administrator   ~0071327

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

git

2017-10-14 12:20

administrator   ~0071477

Branch CR29171 has been deleted by kgv.

SHA-1: 4106626299ee6144f72e403688f5f9191aa4c34a

Related Changesets

occt: master 9e479117

2017-10-07 16:26:38

abv


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

Issue History

Date Modified Username Field Change
2017-10-01 19:40 abv New Issue
2017-10-01 19:40 abv Assigned To => abv
2017-10-07 10:52 abv Note Added: 0071278
2017-10-07 10:52 abv Target Version 7.4.0 => Unscheduled
2017-10-07 11:45 abv Note Added: 0071279
2017-10-07 13:49 abv Note Added: 0071280
2017-10-07 14:59 abv Note Added: 0071281
2017-10-07 23:01 abv Note Edited: 0071278
2017-10-07 23:14 abv Note Added: 0071282
2017-10-08 19:42 git Note Added: 0071283
2017-10-09 09:33 abv Note Added: 0071288
2017-10-09 09:33 abv Status new => resolved
2017-10-09 09:33 abv Target Version Unscheduled => 7.3.0
2017-10-09 09:33 abv Steps to Reproduce Updated
2017-10-09 10:39 abv 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 abv Note Added: 0071311
2017-10-09 21:48 abv Status assigned => resolved
2017-10-09 21:48 abv 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 abv 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 aiv Fixed in Version => 7.3.0
2018-06-29 21:19 aiv Status verified => closed