diff options
Diffstat (limited to 'src/corelib/global/qlogging.cpp')
-rw-r--r-- | src/corelib/global/qlogging.cpp | 78 |
1 files changed, 70 insertions, 8 deletions
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 7444145e82..9f47b8eb98 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -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 @@ -91,6 +94,10 @@ # include "private/qcore_unix_p.h" #endif +#ifdef Q_OS_WASM +#include <emscripten/emscripten.h> +#endif + #if QT_CONFIG(regularexpression) # ifdef __UCLIBC__ # if __UCLIBC_HAS_BACKTRACE__ @@ -240,7 +247,7 @@ static bool systemHasStderr() \internal \sa systemHasStderr() */ -bool stderrHasConsoleAttached() +static bool stderrHasConsoleAttached() { static const bool stderrHasConsoleAttached = []() -> bool { if (!systemHasStderr()) @@ -1208,8 +1215,8 @@ void QMessagePattern::setPattern(const QString &pattern) tokens[i] = backtraceTokenC; QString backtraceSeparator = QStringLiteral("|"); int backtraceDepth = 5; - QRegularExpression depthRx(QStringLiteral(" depth=(?|\"([^\"]*)\"|([^ }]*))")); - QRegularExpression separatorRx(QStringLiteral(" separator=(?|\"([^\"]*)\"|([^ }]*))")); + static const QRegularExpression depthRx(QStringLiteral(" depth=(?|\"([^\"]*)\"|([^ }]*))")); + static const QRegularExpression separatorRx(QStringLiteral(" separator=(?|\"([^\"]*)\"|([^ }]*))")); QRegularExpressionMatch m = depthRx.match(lexeme); if (m.hasMatch()) { int depth = m.capturedRef(1).toInt(); @@ -1295,8 +1302,7 @@ static QStringList backtraceFramesForLogMessage(int frameCount) // The offset and function name are optional. // This regexp tries to extract the library name (without the path) and the function name. // This code is protected by QMessagePattern::mutex so it is thread safe on all compilers - static QRegularExpression rx(QStringLiteral("^(?:[^(]*/)?([^(/]+)\\(([^+]*)(?:[\\+[a-f0-9x]*)?\\) \\[[a-f0-9x]*\\]$"), - QRegularExpression::OptimizeOnFirstUsageOption); + static const QRegularExpression rx(QStringLiteral("^(?:[^(]*/)?([^(/]+)\\(([^+]*)(?:[\\+[a-f0-9x]*)?\\) \\[[a-f0-9x]*\\]$")); QVarLengthArray<void*, 32> buffer(8 + frameCount); int n = backtrace(buffer.data(), buffer.size()); @@ -1688,6 +1694,37 @@ static bool win_message_handler(QtMsgType type, const QMessageLogContext &contex } #endif +#ifdef Q_OS_WASM +static bool wasm_default_message_handler(QtMsgType type, + const QMessageLogContext &context, + const QString &message) +{ + if (shouldLogToStderr()) + return false; // Leave logging up to stderr handler + + QString formattedMessage = qFormatLogMessage(type, context, message); + int emOutputFlags = (EM_LOG_CONSOLE | EM_LOG_DEMANGLE); + QByteArray localMsg = message.toLocal8Bit(); + switch (type) { + case QtDebugMsg: + break; + case QtInfoMsg: + break; + case QtWarningMsg: + emOutputFlags |= EM_LOG_WARN; + break; + case QtCriticalMsg: + emOutputFlags |= EM_LOG_ERROR; + break; + case QtFatalMsg: + emOutputFlags |= EM_LOG_ERROR; + } + emscripten_log(emOutputFlags, "%s\n", qPrintable(formattedMessage)); + + return true; // Prevent further output to stderr +} +#endif + #endif // Bootstrap check // -------------------------------------------------------------------------- @@ -1731,8 +1768,9 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con # elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) handledStderr |= android_default_message_handler(type, context, message); # elif defined(QT_USE_APPLE_UNIFIED_LOGGING) - if (__builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *)) - handledStderr |= AppleUnifiedLogger::messageHandler(type, context, message); + handledStderr |= AppleUnifiedLogger::messageHandler(type, context, message); +# elif defined Q_OS_WASM + handledStderr |= wasm_default_message_handler(type, context, message); # endif #endif @@ -1839,7 +1877,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 } |