From 10c9227136c7a60188fb693858fc27d9d5c7887e Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Mon, 23 Apr 2018 15:06:43 +0300 Subject: [PATCH] core: CV_Error with set_terminate() on Windows To dump contents of the last OpenCV error --- modules/core/src/system.cpp | 77 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 15 deletions(-) diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index eddb11f..f2f5f85 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -71,12 +71,26 @@ static bool param_dumpErrors = utils::getConfigurationParameterBool("OPENCV_DUMP } // namespace cv +#ifndef CV_ERROR_SET_TERMINATE_HANDLER // build config option +# if defined(_WIN32) +# define CV_ERROR_SET_TERMINATE_HANDLER 1 +# endif +#endif +#if CV_ERROR_SET_TERMINATE_HANDLER == 0 +# undef CV_ERROR_SET_TERMINATE_HANDLER +#endif + #ifdef _MSC_VER # if _MSC_VER >= 1700 # pragma warning(disable:4447) // Disable warning 'main' signature found without threading model # endif #endif +#ifdef CV_ERROR_SET_TERMINATE_HANDLER +#include // std::set_terminate +#include // std::abort +#endif + #if defined __ANDROID__ || defined __linux__ || defined __FreeBSD__ || defined __HAIKU__ # include # include @@ -925,28 +939,61 @@ int cv_vsnprintf(char* buf, int len, const char* fmt, va_list args) #endif } +static void dumpException(const Exception& exc) +{ + const char* errorStr = cvErrorStr(exc.code); + char buf[1 << 12]; + + cv_snprintf(buf, sizeof(buf), + "OpenCV(%s) Error: %s (%s) in %s, file %s, line %d", + CV_VERSION, + errorStr, exc.err.c_str(), exc.func.size() > 0 ? + exc.func.c_str() : "unknown function", exc.file.c_str(), exc.line); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_ERROR, "cv::error()", "%s", buf); +#else + fflush(stdout); fflush(stderr); + fprintf(stderr, "%s\n", buf); + fflush(stderr); +#endif +} + +#ifdef CV_ERROR_SET_TERMINATE_HANDLER +static bool cv_terminate_handler_installed = false; +static std::terminate_handler cv_old_terminate_handler; +static cv::Exception cv_terminate_handler_exception; +static bool param_setupTerminateHandler = utils::getConfigurationParameterBool("OPENCV_SETUP_TERMINATE_HANDLER", true); +static void cv_terminate_handler() { + std::cerr << "OpenCV: terminate handler is called! The last OpenCV error is:\n"; + dumpException(cv_terminate_handler_exception); + if (false /*cv_old_terminate_handler*/) // buggy behavior is observed with doubled "abort/retry/ignore" windows + cv_old_terminate_handler(); + abort(); +} + +#endif + void error( const Exception& exc ) { +#ifdef CV_ERROR_SET_TERMINATE_HANDLER + { + cv::AutoLock lock(getInitializationMutex()); + if (!cv_terminate_handler_installed) + { + if (param_setupTerminateHandler) + cv_old_terminate_handler = std::set_terminate(cv_terminate_handler); + cv_terminate_handler_installed = true; + } + cv_terminate_handler_exception = exc; + } +#endif + if (customErrorCallback != 0) customErrorCallback(exc.code, exc.func.c_str(), exc.err.c_str(), exc.file.c_str(), exc.line, customErrorCallbackData); else if (param_dumpErrors) { - const char* errorStr = cvErrorStr(exc.code); - char buf[1 << 12]; - - cv_snprintf(buf, sizeof(buf), - "OpenCV(%s) Error: %s (%s) in %s, file %s, line %d", - CV_VERSION, - errorStr, exc.err.c_str(), exc.func.size() > 0 ? - exc.func.c_str() : "unknown function", exc.file.c_str(), exc.line); -#ifdef __ANDROID__ - __android_log_print(ANDROID_LOG_ERROR, "cv::error()", "%s", buf); -#else - fflush(stdout); fflush(stderr); - fprintf(stderr, "%s\n", buf); - fflush(stderr); -#endif + dumpException(exc); } if(breakOnError) -- 2.7.4