From eb61373b697be35753b7fa6f46215ff7fe81e72d Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 8 Nov 2016 10:49:32 +0100 Subject: [PATCH] Compilation with an environment variable SLIC3R_HAS_BROKEN_CROAK set will force the perl confess / croak called from a C++ code to print an error message and exit. There is a bug in some Strawberry Perl instalations leading to an interpreter hang up and an exit with a reasonable message is better than that. --- xs/Build.PL | 8 ++++++++ xs/src/libslic3r/utils.cpp | 36 ++++++++++++++++++++++++++++++++++++ xs/src/xsinit.h | 9 +++++++++ 3 files changed, 53 insertions(+) diff --git a/xs/Build.PL b/xs/Build.PL index 08988a859..9accef39d 100644 --- a/xs/Build.PL +++ b/xs/Build.PL @@ -42,6 +42,14 @@ if ($ENV{SLIC3R_GUI}) # push @early_includes, qw(slic3r/GUI/wxinit.h); } +if ($ENV{SLIC3R_HAS_BROKEN_CROAK}) +{ + # Some Strawberry Perl builds (mainly the latest 64bit builds) have a broken mechanism + # for emiting Perl exception after handling a C++ exception. Perl interpreter + # simply hangs. Better to show a message box in that case and stop the application. + push @cflags, qw(-DSLIC3R_HAS_BROKEN_CROAK) +} + # search for Boost in a number of places my @boost_include = (); if (defined $ENV{BOOST_INCLUDEDIR}) { diff --git a/xs/src/libslic3r/utils.cpp b/xs/src/libslic3r/utils.cpp index 3f3ed326b..fa34be416 100644 --- a/xs/src/libslic3r/utils.cpp +++ b/xs/src/libslic3r/utils.cpp @@ -1,3 +1,37 @@ +#ifdef SLIC3R_HAS_BROKEN_CROAK + +// Some Strawberry Perl builds (mainly the latest 64bit builds) have a broken mechanism +// for emiting Perl exception after handling a C++ exception. Perl interpreter +// simply hangs. Better to show a message box in that case and stop the application. + +#include +#include +#include + +#ifdef WIN32 +#include +#endif + +void confess_at(const char *file, int line, const char *func, const char *format, ...) +{ + char dest[1024*8]; + va_list argptr; + va_start(argptr, format); + vsprintf(dest, format, argptr); + va_end(argptr); + + strcat(dest, "\r\n Closing the application.\r\n"); + #ifdef WIN32 + ::MessageBoxA(NULL, dest, "Slic3r Prusa Edition", MB_OK | MB_ICONERROR); + #endif; + + // Give up. + printf(dest); + exit(-1); +} + +#else + #include void @@ -26,3 +60,5 @@ confess_at(const char *file, int line, const char *func, LEAVE; #endif } + +#endif diff --git a/xs/src/xsinit.h b/xs/src/xsinit.h index 99b0e8f6a..c88d27e65 100644 --- a/xs/src/xsinit.h +++ b/xs/src/xsinit.h @@ -153,4 +153,13 @@ SV* polynode2perl(const ClipperLib::PolyNode& node); } +#ifdef SLIC3R_HAS_BROKEN_CROAK +#undef croak +#ifdef _MSC_VER + #define croak(...) confess_at(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__) +#else + #define croak(...) confess_at(__FILE__, __LINE__, __func__, __VA_ARGS__) +#endif +#endif + #endif