From 8f13af5d7b9b659208a8a93e6581d30b434dae1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 20 Sep 2021 15:38:27 +0200 Subject: [PATCH] Add private qAbort helper function Used from qt_message_fatal(), but is useful in other situations too. Change-Id: I3c0e438536d40271061c76d954c7878abfe37b8e Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.cpp | 29 +++++++++++++++++++++++++++++ src/corelib/global/qglobal_p.h | 5 +++++ src/corelib/global/qlogging.cpp | 26 +------------------------- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 49d8bbeb85a..e900d808d1a 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -3359,6 +3359,35 @@ time_t qMkTime(struct tm *when) return mktime(when); } +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) && !defined(Q_CC_INTEL) + 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 +} + // Also specified to behave as if they call tzset(): // localtime() -- but not localtime_r(), which we use when threaded // strftime() -- not used (except in tests) diff --git a/src/corelib/global/qglobal_p.h b/src/corelib/global/qglobal_p.h index 5ab84fa8be8..49927ef30f0 100644 --- a/src/corelib/global/qglobal_p.h +++ b/src/corelib/global/qglobal_p.h @@ -72,6 +72,11 @@ QT_BEGIN_NAMESPACE Q_CORE_EXPORT void qTzSet(); Q_CORE_EXPORT time_t qMkTime(struct tm *when); +#if !defined(Q_CC_MSVC) +Q_NORETURN +#endif +Q_CORE_EXPORT void qAbort(); + QT_END_NAMESPACE #if !__has_builtin(__builtin_available) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index dc28680bc77..0298ec7c4d3 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1872,31 +1872,7 @@ static void qt_message_fatal(QtMsgType, const QMessageLogContext &context, const Q_UNUSED(message); #endif -#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) && !defined(Q_CC_INTEL) - 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 + qAbort(); }