message: core: CV_Error with set_terminate() on Windows
  To dump contents of the last OpenCV error
diff: @@ -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 <exception> // std::set_terminate
  +#include <cstdlib> // std::abort
  +#endif
  +
  #if defined __ANDROID__ || defined __linux__ || defined __FreeBSD__ || defined __HAIKU__
  # include <unistd.h>
  # include <fcntl.h>
  @@ -925,12 +939,7 @@ int cv_vsnprintf(char* buf, int len, const char* fmt, va_list args)
  #endif
  }
  -void error( const Exception& exc )
  -{
  - 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)
  +static void dumpException(const Exception& exc)
  {
  const char* errorStr = cvErrorStr(exc.code);
  char buf[1 << 12];
  @@ -949,6 +958,44 @@ void error( const Exception& exc )
  #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)
  + {
  + dumpException(exc);
  + }
  +
  if(breakOnError)
  {
  static volatile int* p = 0;
  