rework error handling mechanism
This commit is contained in:
@@ -171,7 +171,8 @@ MESSAGE(STATUS "cmake: ${CMAKE_VERSION}")
|
||||
# ==============================================================================
|
||||
# == Win32 is default behaviour use the LibPack copied in Source tree ==========
|
||||
if(MSVC)
|
||||
OPTION(FREECAD_RELEASE_PDB "Create PDB file for Release version." ON)
|
||||
OPTION(FREECAD_RELEASE_PDB "Create PDB files for Release version." ON)
|
||||
OPTION(FREECAD_RELEASE_SEH "Enable Structured Exception Handling for Release version." ON)
|
||||
OPTION(FREECAD_LIBPACK_USE "Use the LibPack to Build FreeCAD (only Win32 so far)." ON)
|
||||
OPTION(FREECAD_LIBPACK_USEPYSIDE "Use PySide in LibPack rather to PyQt and Swig." ON)
|
||||
set(FREECAD_LIBPACK_DIR ${CMAKE_SOURCE_DIR} CACHE PATH "Directory of the FreeCAD LibPack")
|
||||
@@ -1098,8 +1099,8 @@ ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
|
||||
IF(MSVC)
|
||||
# set default compiler settings
|
||||
SET (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /EHa /Zm128")
|
||||
SET (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DFC_DEBUG /Zm128")
|
||||
SET (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zm150")
|
||||
SET (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DFC_DEBUG /Zm150")
|
||||
# set default libs
|
||||
SET (CMAKE_C_STANDARD_LIBRARIES "kernel32.lib user32.lib gdi32.lib winspool.lib SHFolder.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib winmm.lib comsupp.lib Ws2_32.lib dbghelp.lib ")
|
||||
set (CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES}")
|
||||
@@ -1111,6 +1112,9 @@ IF(MSVC)
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
|
||||
set (CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG")
|
||||
ENDIF(FREECAD_RELEASE_PDB)
|
||||
IF(FREECAD_RELEASE_SEH)
|
||||
SET (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /EHa")
|
||||
ENDIF(FREECAD_RELEASE_SEH)
|
||||
|
||||
# Mark 32 bit executables large address aware so they can use > 2GB address space
|
||||
# NOTE: This setting only has an effect on machines with at least 3GB of RAM, although it sets the linker option it doesn't set the linker switch 'Enable Large Addresses'
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user