rework error handling mechanism

This commit is contained in:
wmayer
2018-10-24 19:38:43 +02:00
parent ea4fb69e4e
commit a53027342e
5 changed files with 92 additions and 45 deletions

View File

@@ -138,6 +138,10 @@ using namespace boost::program_options;
#include <App/CMakeScript.h>
#ifdef _MSC_VER // New handler for Microsoft Visual C++ compiler
# if !defined(_DEBUG) && defined(HAVE_SEH)
# define FC_SE_TRANSLATOR
# endif
# include <new.h>
# include <eh.h> // VC exception handling
#else // Ansi C/C++ new handler
@@ -1226,7 +1230,7 @@ void segmentation_fault_handler(int sig)
}
}
void my_terminate_handler()
void unhandled_exception_handler()
{
std::cerr << "Terminating..." << std::endl;
}
@@ -1242,23 +1246,28 @@ void unexpection_error_handler()
#endif
}
#ifdef _MSC_VER // Microsoft compiler
void my_trans_func( unsigned int code, EXCEPTION_POINTERS* pExp )
#if defined(FC_SE_TRANSLATOR) // Microsoft compiler
void my_se_translator_filter(unsigned int code, EXCEPTION_POINTERS* pExp)
{
Q_UNUSED(pExp)
switch (code)
{
case EXCEPTION_ACCESS_VIOLATION:
throw Base::AccessViolation();
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
case EXCEPTION_INT_DIVIDE_BY_ZERO:
throw Base::DivisionByZeroError("Division by zero!");
break;
}
//switch (code)
//{
// case FLT_DIVIDE_BY_ZERO :
// //throw CMyFunkyDivideByZeroException(code, pExp);
// throw Base::DivisionByZeroError("Division by zero!");
// break;
//}
// general C++ SEH exception for things we don't need to handle separately....
throw Base::RuntimeError("my_trans_func()");
std::stringstream str;
str << "SEH exception of type: " << code;
// general C++ SEH exception for things we don't need to handle separately....
throw Base::RuntimeError(str.str());
}
#endif
void Application::init(int argc, char ** argv)
{
try {
@@ -1274,13 +1283,14 @@ void Application::init(int argc, char ** argv)
#if defined (_MSC_VER) // Microsoft compiler
std::signal(SIGSEGV,segmentation_fault_handler);
std::signal(SIGABRT,segmentation_fault_handler);
std::set_terminate(my_terminate_handler);
std::set_terminate(unhandled_exception_handler);
std::set_unexpected(unexpection_error_handler);
// _set_se_translator(my_trans_func);
#elif defined(FC_OS_LINUX)
std::signal(SIGSEGV,segmentation_fault_handler);
#endif
#if defined(FC_SE_TRANSLATOR)
_set_se_translator(my_se_translator_filter);
#endif
initTypes();
#if (BOOST_VERSION < 104600) || (BOOST_FILESYSTEM_VERSION == 2)

View File

@@ -3,6 +3,10 @@ if(WIN32)
add_definitions(-DBOOST_DYN_LINK)
endif(WIN32)
if(FREECAD_RELEASE_SEH)
add_definitions(-DHAVE_SEH)
endif(FREECAD_RELEASE_SEH)
# This causes some problems with the resource files to be found, especially with the StartPage
IF(RESOURCEDIR)
add_definitions(-DRESOURCEDIR="${RESOURCEDIR}")

View File

@@ -131,29 +131,59 @@ short FeatureTest::mustExecute(void) const
DocumentObjectExecReturn *FeatureTest::execute(void)
{
/*
doc=App.newDocument()
obj=doc.addObject("App::FeatureTest")
int *i=0,j;
float f;
void *s;
obj.ExceptionType=0 # good
doc.recompute()
// Code analyzers may complain about some errors. This can be ignored
// because this is done on purpose to test the error handling mechanism
switch(ExceptionType.getValue())
{
case 0: break;
case 1: throw "Test Exception";
case 2: throw Base::RuntimeError("FeatureTestException::execute(): Testexception");
case 3: *i=0;printf("%i",*i);break; // seg-vault
case 4: j=0; printf("%i",1/j); break; // int division by zero
case 5: f=0.0; printf("%f",1/f); break; // float division by zero
case 6: s = malloc(3600000000ul); free(s); break; // out-of-memory
}
ExecCount.setValue(ExecCount.getValue() + 1);
obj.ExceptionType=1 # unknown exception
doc.recompute()
ExecResult.setValue("Exec");
obj.ExceptionType=2 # Runtime error
doc.recompute()
return DocumentObject::StdReturn;
obj.ExceptionType=3 # segfault
doc.recompute()
obj.ExceptionType=4 # segfault
doc.recompute()
obj.ExceptionType=5 # int division by zero
doc.recompute()
obj.ExceptionType=6 # float division by zero
doc.recompute()
*/
int *i=0,j;
float f;
void *s;
std::string t;
// Code analyzers may complain about some errors. This can be ignored
// because this is done on purpose to test the error handling mechanism
switch(ExceptionType.getValue())
{
case 0: break;
case 1: throw "Test Exception";
case 2: throw Base::RuntimeError("FeatureTestException::execute(): Testexception");
#if 0 // only allow these error types on purpose
case 3: *i=0;printf("%i",*i);break; // seg-fault
case 4: t = nullptr; break; // seg-fault
case 5: j=0; printf("%i",1/j); break; // int division by zero
case 6: f=0.0; printf("%f",1/f); break; // float division by zero
case 7: s = malloc(3600000000ul); free(s); break; // out-of-memory
#else
default: (void)i; (void)j; (void)f; (void)s; (void)t; break;
#endif
}
ExecCount.setValue(ExecCount.getValue() + 1);
ExecResult.setValue("Exec");
return DocumentObject::StdReturn;
}
@@ -162,14 +192,13 @@ PROPERTY_SOURCE(App::FeatureTestException, App::FeatureTest)
FeatureTestException::FeatureTestException()
{
ADD_PROPERTY(ExceptionType,(Base::Exception::getClassTypeId().getKey()) );
ADD_PROPERTY(ExceptionType,(Base::Exception::getClassTypeId().getKey()) );
}
DocumentObjectExecReturn *FeatureTestException::execute(void)
{
//ExceptionType;
//ExceptionType;
throw Base::RuntimeError("FeatureTestException::execute(): Testexception ;-)");
throw Base::RuntimeError("FeatureTestException::execute(): Testexception ;-)");
return 0;
return 0;
}

View File

@@ -237,7 +237,7 @@ PyMOD_INIT_FUNC(Part)
// Python's cmath module.
// For Linux use segmentation_fault_handler in Application.cpp
#if !defined(_DEBUG) && !defined(FC_OS_LINUX)
OSD::SetSignal(Standard_False);
//OSD::SetSignal(Standard_False);
#endif
PyObject* partModule = Part::initModule();