qFatal: Prevent deadlocks on Windows
We began using abort() on 25d6f312ac
(5.8), which improved since we stopped using exit() with MSVC. However,
abort() with MinGW and on debug-mode MSVC's CRT calls _exit(), which
attempts to cleanly unload the DLLs, which in turn may run global
destructors.
[ChangeLog][QtCore][Important behavior changes] qFatal() no longer uses
std::abort() on Windows, as there are circumstances where global
destructors are still run after that call, leading to possible
deadlocks.
Task-number: QTBUG-34460
Change-Id: I2bec439d0e9841f58c7ffffd152200e45f1df982
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Kai Koehne <kai.koehne@qt.io>
bb10
parent
f240efaa35
commit
f4394c86b6
|
|
@ -2,7 +2,7 @@
|
|||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
|
||||
** Copyright (C) 2016 Intel Corporation.
|
||||
** Copyright (C) 2018 Intel Corporation.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
|
|
@ -61,6 +61,9 @@
|
|||
#ifdef Q_OS_WIN
|
||||
#include <qt_windows.h>
|
||||
#endif
|
||||
#ifdef Q_CC_MSVC
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
#if QT_CONFIG(slog2)
|
||||
#include <sys/slog2.h>
|
||||
#endif
|
||||
|
|
@ -1839,7 +1842,31 @@ 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.
|
||||
|
||||
# ifdef 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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue