From: abv Date: Thu, 29 Dec 2016 11:37:42 +0000 (+0300) Subject: 0028217: Error handling is not thread safe and causing memory corruption and sporadic... X-Git-Tag: V_01_2017_06_30~65 X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=b3d20c7f4680751875562503e4ff485b2e59f141;p=occt-copy.git 0028217: Error handling is not thread safe and causing memory corruption and sporadic crashes Static variable holding handle to the last raised exception is made thread-local on compilers that support C++11 keyword thread_local (MCVC++ 14+, GCC 4.8+, ICC 14+, CLang). Test bugs fclasses bug28217 is added (BAD on vc < 14 and gcc < 4.8). Test case tuning bugs/fclasses/bug28217 --- diff --git a/src/QABugs/QABugs_20.cxx b/src/QABugs/QABugs_20.cxx index ffe937e785..2b88cf893e 100644 --- a/src/QABugs/QABugs_20.cxx +++ b/src/QABugs/QABugs_20.cxx @@ -2140,6 +2140,48 @@ static Standard_Integer OCC27875(Draw_Interpretor& theDI, return 0; } +#include + +namespace { + struct ExceptionRaiser + { + void operator () (int i) const + { + try + { + f (i); + } + catch (Standard_ProgramError) + { + strlen (Standard_Failure::Caught()->GetMessageString()); + } + } + + void f(int i) const; + }; + + void ExceptionRaiser::f (int i) const + { + const char str[] = "0123456789"; + Standard_ProgramError::Raise (str + i % 10); + } +}; + +static Standard_Integer OCC28217(Draw_Interpretor& theDI, + Standard_Integer /*theNArg*/, + const char ** /*theArgVal*/) +{ + NCollection_Array1 aVec (1, 10000); + for (int i=1; i < aVec.Length(); i++) + aVec(i) = i; + + ExceptionRaiser aProc; + OSD_Parallel::For (1, aVec.Length(), aProc); + + theDI << "OCC28217: OK"; + return 0; +} + void QABugs::Commands_20(Draw_Interpretor& theCommands) { const char *group = "QABugs"; @@ -2160,6 +2202,7 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) { theCommands.Add("OCC26270", "OCC26270 shape result", __FILE__, OCC26270, group); theCommands.Add ("OCC27552", "OCC27552", __FILE__, OCC27552, group); theCommands.Add("OCC27875", "OCC27875 curve", __FILE__, OCC27875, group); + theCommands.Add("OCC28217", "OCC28217", __FILE__, OCC28217, group); return; } diff --git a/src/Standard/Standard_Failure.cxx b/src/Standard/Standard_Failure.cxx index 07ecbcc4e1..2e9c8a9b77 100644 --- a/src/Standard/Standard_Failure.cxx +++ b/src/Standard/Standard_Failure.cxx @@ -58,12 +58,22 @@ static void deallocate_message(Standard_CString aMessage) } } +// Define Standard_THREADLOCAL modifier as C++11 thread_local keyword +// where it is available. +#if (defined(__INTEL_COMPILER) && __INTEL_COMPILER > 1400) || \ + (defined(__clang__)) /* assume standard CLang > 3.3 or XCode >= 8 */ || \ + (defined(_MSC_VER) && _MSC_VER >= 1800) /* MSVC++ >= 14 */ || \ + (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) /* GCC >= 4.8 */ + #define Standard_THREADLOCAL thread_local +#else + #define Standard_THREADLOCAL +#endif // ****************************************************************** // Standard_Failure * // ****************************************************************** #ifndef NO_CXX_EXCEPTION -static Handle(Standard_Failure) RaisedError; +static Standard_THREADLOCAL Handle(Standard_Failure) RaisedError; #endif // ------------------------------------------------------------------ // diff --git a/tests/bugs/fclasses/bug28217 b/tests/bugs/fclasses/bug28217 new file mode 100644 index 0000000000..8d5fe26f0b --- /dev/null +++ b/tests/bugs/fclasses/bug28217 @@ -0,0 +1,17 @@ +puts "Testing intensive raising exceptions in parallel threads" +puts "0028217: E r r o r handling is not thread safe and causing memory corruption and sporadic crashes" + +# this test will fail on vc10-13 and gcc less than 4.8 +set dver [dversion] +if { ( [regexp {Compiler: MS Visual C[+][+] ([0-9]+)} $dver res ver] && $ver < 14 ) || + ( [regexp {Compiler: GCC ([0-9]+[.][0-9]+)} $dver res ver] && $ver < 4.8 ) } { + puts "TODO OCC28217 ALL: TEST INCOMPLETE" + puts "TODO OCC28217 Windows: An exception was caught" + puts "TODO OCC28217 Windows: \\*\\* Exception \\*\\*.*" + puts "TODO ?OCC28217 Linux: An exception was caught" + puts "TODO ?OCC28217 Linux: \\*\\* Exception \\*\\*.*" + puts "TODO ?OCC28217 Linux: \\*\\*\\* Abort" + puts "TODO ?OCC28217 Linux: ... The exception is" +} +pload QAcommands +OCC28217