Catching of sigsegv and sigfpe with structured exceptions on win
This commit is contained in:
parent
a5529aff1e
commit
976dd72b8b
@ -284,7 +284,8 @@ cmake_policy(SET CMP0011 NEW)
|
||||
find_package(CGAL REQUIRED)
|
||||
cmake_policy(POP)
|
||||
|
||||
add_library(libslic3r_cgal STATIC MeshBoolean.cpp MeshBoolean.hpp)
|
||||
add_library(libslic3r_cgal STATIC MeshBoolean.cpp MeshBoolean.hpp TryCatchSignal.hpp
|
||||
TryCatchSignal.cpp)
|
||||
target_include_directories(libslic3r_cgal PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# Reset compile options of libslic3r_cgal. Despite it being linked privately, CGAL options
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "Exception.hpp"
|
||||
#include "MeshBoolean.hpp"
|
||||
#include "libslic3r/TriangleMesh.hpp"
|
||||
#include "libslic3r/TryCatchSignal.hpp"
|
||||
#undef PI
|
||||
|
||||
// Include igl first. It defines "L" macro which then clashes with our localization
|
||||
@ -209,7 +210,9 @@ template<class Op> void _cgal_do(Op &&op, CGALMesh &A, CGALMesh &B)
|
||||
bool success = false;
|
||||
try {
|
||||
CGALMesh result;
|
||||
try_catch_signal({SIGSEGV, SIGFPE}, [&success, &A, &B, &result, &op] {
|
||||
success = op(A, B, result);
|
||||
}, [&] { success = false; });
|
||||
A = std::move(result); // In-place operation does not work
|
||||
} catch (...) {
|
||||
success = false;
|
||||
@ -264,6 +267,11 @@ bool does_self_intersect(const TriangleMesh &mesh)
|
||||
|
||||
void CGALMeshDeleter::operator()(CGALMesh *ptr) { delete ptr; }
|
||||
|
||||
bool does_bound_a_volume(const CGALMesh &mesh)
|
||||
{
|
||||
return CGALProc::does_bound_a_volume(mesh.m);
|
||||
}
|
||||
|
||||
} // namespace cgal
|
||||
|
||||
} // namespace MeshBoolean
|
||||
|
@ -54,6 +54,8 @@ void intersect(CGALMesh &A, CGALMesh &B);
|
||||
bool does_self_intersect(const TriangleMesh &mesh);
|
||||
bool does_self_intersect(const CGALMesh &mesh);
|
||||
|
||||
bool does_bound_a_volume(const CGALMesh &mesh);
|
||||
|
||||
}
|
||||
|
||||
} // namespace MeshBoolean
|
||||
|
@ -428,6 +428,18 @@ void SLAPrint::Steps::drill_holes(SLAPrintObject &po)
|
||||
|
||||
auto hollowed_mesh_cgal = MeshBoolean::cgal::triangle_mesh_to_cgal(hollowed_mesh);
|
||||
|
||||
if (!MeshBoolean::cgal::does_bound_a_volume(*hollowed_mesh_cgal)) {
|
||||
po.active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL,
|
||||
L("Mesh to be hollowed is not suitable for hollowing (does not "
|
||||
"bound a volume)."));
|
||||
}
|
||||
|
||||
if (!MeshBoolean::cgal::does_bound_a_volume(*holes_mesh_cgal)) {
|
||||
po.active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL,
|
||||
L("Unable to drill the current configuration of holes into the "
|
||||
"model."));
|
||||
}
|
||||
|
||||
try {
|
||||
MeshBoolean::cgal::minus(*hollowed_mesh_cgal, *holes_mesh_cgal);
|
||||
|
||||
@ -749,43 +761,6 @@ void SLAPrint::Steps::slice_supports(SLAPrintObject &po) {
|
||||
report_status(-2, "", SlicingStatus::RELOAD_SLA_PREVIEW);
|
||||
}
|
||||
|
||||
//static ClipperPolygons polyunion(const ClipperPolygons &subjects)
|
||||
//{
|
||||
// ClipperLib::Clipper clipper;
|
||||
|
||||
// bool closed = true;
|
||||
|
||||
// for(auto& path : subjects) {
|
||||
// clipper.AddPath(path.Contour, ClipperLib::ptSubject, closed);
|
||||
// clipper.AddPaths(path.Holes, ClipperLib::ptSubject, closed);
|
||||
// }
|
||||
|
||||
// auto mode = ClipperLib::pftPositive;
|
||||
|
||||
// return libnest2d::clipper_execute(clipper, ClipperLib::ctUnion, mode, mode);
|
||||
//}
|
||||
|
||||
//static ClipperPolygons polydiff(const ClipperPolygons &subjects, const ClipperPolygons& clips)
|
||||
//{
|
||||
// ClipperLib::Clipper clipper;
|
||||
|
||||
// bool closed = true;
|
||||
|
||||
// for(auto& path : subjects) {
|
||||
// clipper.AddPath(path.Contour, ClipperLib::ptSubject, closed);
|
||||
// clipper.AddPaths(path.Holes, ClipperLib::ptSubject, closed);
|
||||
// }
|
||||
|
||||
// for(auto& path : clips) {
|
||||
// clipper.AddPath(path.Contour, ClipperLib::ptClip, closed);
|
||||
// clipper.AddPaths(path.Holes, ClipperLib::ptClip, closed);
|
||||
// }
|
||||
|
||||
// auto mode = ClipperLib::pftPositive;
|
||||
|
||||
// return libnest2d::clipper_execute(clipper, ClipperLib::ctDifference, mode, mode);
|
||||
//}
|
||||
|
||||
// get polygons for all instances in the object
|
||||
static ExPolygons get_all_polygons(const SliceRecord& record, SliceOrigin o)
|
||||
{
|
||||
|
5
src/libslic3r/TryCatchSignal.cpp
Normal file
5
src/libslic3r/TryCatchSignal.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "TryCatchSignal.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include "TryCatchSignalSEH.cpp"
|
||||
#endif
|
15
src/libslic3r/TryCatchSignal.hpp
Normal file
15
src/libslic3r/TryCatchSignal.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef TRY_CATCH_SIGNAL_HPP
|
||||
#define TRY_CATCH_SIGNAL_HPP
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include "TryCatchSignalSEH.hpp"
|
||||
#else
|
||||
template<class TryFn, class CatchFn, int N>
|
||||
void try_catch_signal(const SignalT (&/*sigs*/)[N], TryFn &&/*fn*/, CatchFn &&/*cfn*/)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TRY_CATCH_SIGNAL_HPP
|
||||
|
43
src/libslic3r/TryCatchSignalSEH.cpp
Normal file
43
src/libslic3r/TryCatchSignalSEH.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include "TryCatchSignalSEH.hpp"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
static int signal_seh_filter(int sigcnt, const Slic3r::SignalT *sigs,
|
||||
unsigned long seh_code)
|
||||
{
|
||||
int ret = EXCEPTION_CONTINUE_SEARCH;
|
||||
|
||||
for (int s = 0; s < sigcnt && ret != EXCEPTION_EXECUTE_HANDLER; ++s)
|
||||
switch (sigs[s]) {
|
||||
case SIGSEGV:
|
||||
if (seh_code == STATUS_ACCESS_VIOLATION)
|
||||
ret = EXCEPTION_EXECUTE_HANDLER;
|
||||
break;
|
||||
case SIGILL:
|
||||
if (seh_code == STATUS_ILLEGAL_INSTRUCTION)
|
||||
ret = EXCEPTION_EXECUTE_HANDLER;
|
||||
break;
|
||||
case SIGFPE:
|
||||
if (seh_code == STATUS_FLOAT_DIVIDE_BY_ZERO ||
|
||||
seh_code == STATUS_FLOAT_OVERFLOW ||
|
||||
seh_code == STATUS_FLOAT_UNDERFLOW ||
|
||||
seh_code == STATUS_INTEGER_DIVIDE_BY_ZERO)
|
||||
ret = EXCEPTION_EXECUTE_HANDLER;
|
||||
break;
|
||||
default: ret = EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Slic3r::detail::try_catch_signal_seh(int sigcnt, const SignalT *sigs,
|
||||
std::function<void()> &&fn,
|
||||
std::function<void()> &&cfn)
|
||||
{
|
||||
__try {
|
||||
fn();
|
||||
}
|
||||
__except(signal_seh_filter(sigcnt, sigs, GetExceptionCode())) {
|
||||
cfn();
|
||||
}
|
||||
}
|
27
src/libslic3r/TryCatchSignalSEH.hpp
Normal file
27
src/libslic3r/TryCatchSignalSEH.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef TRY_CATCH_SIGNAL_SEH_HPP
|
||||
#define TRY_CATCH_SIGNAL_SEH_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <csignal>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
using SignalT = decltype (SIGSEGV);
|
||||
|
||||
namespace detail {
|
||||
|
||||
void try_catch_signal_seh(int sigcnt, const SignalT *sigs,
|
||||
std::function<void()> &&fn,
|
||||
std::function<void()> &&cfn);
|
||||
|
||||
}
|
||||
|
||||
template<class TryFn, class CatchFn, int N>
|
||||
void try_catch_signal(const SignalT (&sigs)[N], TryFn &&fn, CatchFn &&cfn)
|
||||
{
|
||||
detail::try_catch_signal_seh(N, sigs, fn, cfn);
|
||||
}
|
||||
|
||||
} // Slic3r
|
||||
|
||||
#endif // TRY_CATCH_SIGNAL_SEH_HPP
|
Loading…
Reference in New Issue
Block a user