1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-09-13 14:27:08 +03:00

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
This commit is contained in:
abv
2016-12-29 14:37:42 +03:00
committed by apn
parent 96fffdc609
commit b3d20c7f46
3 changed files with 71 additions and 1 deletions

View File

@@ -2140,6 +2140,48 @@ static Standard_Integer OCC27875(Draw_Interpretor& theDI,
return 0;
}
#include <OSD_Parallel.hxx>
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<int> 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;
}

View File

@@ -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
// ------------------------------------------------------------------
//

View File

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