summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qassert.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/global/qassert.cpp')
-rw-r--r--src/corelib/global/qassert.cpp37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/corelib/global/qassert.cpp b/src/corelib/global/qassert.cpp
index 462f141294..7c0064ac2f 100644
--- a/src/corelib/global/qassert.cpp
+++ b/src/corelib/global/qassert.cpp
@@ -5,14 +5,51 @@
#include <QtCore/qlogging.h>
+#include <cstdlib>
#include <cstdio>
#include <exception>
#ifndef QT_NO_EXCEPTIONS
#include <new>
#endif
+#if defined(Q_CC_MSVC)
+# include <crtdbg.h>
+#endif
+#ifdef Q_OS_WIN
+# include <qt_windows.h>
+#endif
+
QT_BEGIN_NAMESPACE
+void qAbort()
+{
+#ifdef Q_OS_WIN
+ // std::abort() in the MSVC runtime will call _exit(3) if the abort
+ // behavior is _WRITE_ABORT_MSG - see also _set_abort_behavior(). This is
+ // the default for a debug-mode build of the runtime. Worse, MinGW's
+ // std::abort() implementation (in msvcrt.dll) is basically a call to
+ // _exit(3) too. Unfortunately, _exit() and _Exit() *do* run the static
+ // destructors of objects in DLLs, a violation of the C++ standard (see
+ // [support.start.term]). So we bypass std::abort() and directly
+ // terminate the application.
+
+# if defined(Q_CC_MSVC)
+ if (IsProcessorFeaturePresent(PF_FASTFAIL_AVAILABLE))
+ __fastfail(FAST_FAIL_FATAL_APP_EXIT);
+# else
+ RaiseFailFastException(nullptr, nullptr, 0);
+# endif
+
+ // Fallback
+ TerminateProcess(GetCurrentProcess(), STATUS_FATAL_APP_EXIT);
+
+ // Tell the compiler the application has stopped.
+ Q_UNREACHABLE_IMPL();
+#else // !Q_OS_WIN
+ std::abort();
+#endif
+}
+
/*!
\macro void Q_ASSERT(bool test)
\relates <QtAssert>