summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qlogging.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/global/qlogging.cpp')
-rw-r--r--src/corelib/global/qlogging.cpp85
1 files changed, 72 insertions, 13 deletions
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 71579ca08a..efeec37094 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -69,17 +69,19 @@
extern char *__progname;
#endif
-#ifndef QT_BOOTSTRAPPED
-#if __has_include(<cxxabi.h>) && QT_CONFIG(backtrace) && QT_CONFIG(regularexpression)
+#ifdef QLOGGING_HAVE_BACKTRACE
# include <qregularexpression.h>
+#endif
+
+#ifdef QLOGGING_USE_EXECINFO_BACKTRACE
# if QT_CONFIG(dladdr)
# include <dlfcn.h>
# endif
# include BACKTRACE_HEADER
# include <cxxabi.h>
-# define QLOGGING_HAVE_BACKTRACE
-#endif
+#endif // QLOGGING_USE_EXECINFO_BACKTRACE
+#ifndef QT_BOOTSTRAPPED
#if defined(Q_OS_LINUX) && (defined(__GLIBC__) || __has_include(<sys/syscall.h>))
# include <sys/syscall.h>
@@ -832,7 +834,7 @@ void QMessageLogger::fatal(const QLoggingCategory &cat, const char *msg, ...) co
va_list ap;
va_start(ap, msg); // use variable arg list
- QT_TERMINATE_ON_EXCEPTION(qt_message(QtFatalMsg, ctxt, msg, ap));
+ qt_message(QtFatalMsg, ctxt, msg, ap);
va_end(ap);
#ifndef Q_CC_MSVC_ONLY
@@ -856,7 +858,7 @@ void QMessageLogger::fatal(QMessageLogger::CategoryFunction catFunc,
va_list ap;
va_start(ap, msg); // use variable arg list
- QT_TERMINATE_ON_EXCEPTION(qt_message(QtFatalMsg, ctxt, msg, ap));
+ qt_message(QtFatalMsg, ctxt, msg, ap);
va_end(ap);
#ifndef Q_CC_MSVC_ONLY
@@ -875,7 +877,7 @@ void QMessageLogger::fatal(const char *msg, ...) const noexcept
QInternalMessageLogContext ctxt(context);
va_list ap;
va_start(ap, msg); // use variable arg list
- QT_TERMINATE_ON_EXCEPTION(qt_message(QtFatalMsg, ctxt, msg, ap));
+ qt_message(QtFatalMsg, ctxt, msg, ap);
va_end(ap);
#ifndef Q_CC_MSVC_ONLY
@@ -1343,6 +1345,52 @@ void QMessagePattern::setPattern(const QString &pattern)
Unfortunately, we can't know for sure if it has been.
*/
static constexpr int TypicalBacktraceFrameCount = 3;
+static constexpr const char *QtCoreLibraryName = "Qt" QT_STRINGIFY(QT_VERSION_MAJOR) "Core";
+
+#if defined(QLOGGING_USE_STD_BACKTRACE)
+Q_NEVER_INLINE void QInternalMessageLogContext::populateBacktrace(int frameCount)
+{
+ assert(frameCount >= 0);
+ backtrace = std::stacktrace::current(0, TypicalBacktraceFrameCount + frameCount);
+}
+
+static QStringList
+backtraceFramesForLogMessage(int frameCount,
+ const QInternalMessageLogContext::BacktraceStorage &buffer)
+{
+ QStringList result;
+ result.reserve(buffer.size());
+
+ const auto shouldSkipFrame = [](QByteArrayView description)
+ {
+#if defined(_MSVC_STL_VERSION)
+ const auto libraryNameEnd = description.indexOf('!');
+ if (libraryNameEnd != -1) {
+ const auto libraryName = description.first(libraryNameEnd);
+ if (!libraryName.contains(QtCoreLibraryName))
+ return false;
+ }
+#endif
+ if (description.contains("populateBacktrace"))
+ return true;
+ if (description.contains("QInternalMessageLogContext"))
+ return true;
+ if (description.contains("~QDebug"))
+ return true;
+ return false;
+ };
+
+ for (const auto &entry : buffer) {
+ const std::string description = entry.description();
+ if (result.isEmpty() && shouldSkipFrame(description))
+ continue;
+ result.append(QString::fromStdString(description));
+ }
+
+ return result;
+}
+
+#elif defined(QLOGGING_USE_EXECINFO_BACKTRACE)
Q_NEVER_INLINE void QInternalMessageLogContext::populateBacktrace(int frameCount)
{
@@ -1369,7 +1417,7 @@ backtraceFramesForLogMessage(int frameCount,
return result;
auto shouldSkipFrame = [&result](const auto &library, const auto &function) {
- if (!result.isEmpty() || !library.contains("Qt6Core"_L1))
+ if (!result.isEmpty() || !library.contains(QLatin1StringView(QtCoreLibraryName)))
return false;
if (function.isEmpty())
return true;
@@ -1476,6 +1524,9 @@ backtraceFramesForLogMessage(int frameCount,
}
return result;
}
+#else
+#error "Internal error: backtrace enabled, but no way to gather backtraces available"
+#endif // QLOGGING_USE_..._BACKTRACE
static QString formatBacktraceForLogMessage(const QMessagePattern::BacktraceParams backtraceParams,
const QMessageLogContext &ctx)
@@ -2213,8 +2264,18 @@ void qErrnoWarning(int code, const char *msg, ...)
specified by the optional \c depth parameter (defaults to 5), and separated by the optional
\c separator parameter (defaults to "|").
- This expansion is available only on some platforms (currently only platfoms using glibc).
- Names are only known for exported functions. If you want to see the name of every function
+ This expansion is available only on some platforms:
+
+ \list
+ \li platforms using glibc;
+ \li platforms shipping C++23's \c{<stacktrace>} header (requires compiling Qt in C++23 mode).
+ \endlist
+
+ Depending on the platform, there are some restrictions on the function
+ names printed by this expansion.
+
+ On some platforms,
+ names are only known for exported functions. If you want to see the name of every function
in your application, make sure your application is compiled and linked with \c{-rdynamic},
or an equivalent of it.
@@ -2560,7 +2621,7 @@ QMessageLogContext &QMessageLogContext::copyContextFrom(const QMessageLogContext
This enum describes the messages that can be sent to a message
handler (QtMessageHandler). You can use the enum to identify and
associate the various message types with the appropriate
- actions.
+ actions. Its values are, in order of increasing severity:
\value QtDebugMsg
A message generated by the qDebug() function.
@@ -2574,8 +2635,6 @@ QMessageLogContext &QMessageLogContext::copyContextFrom(const QMessageLogContext
A message generated by the qFatal() function.
\omitvalue QtSystemMsg
- \c QtInfoMsg was added in Qt 5.5.
-
\sa QtMessageHandler, qInstallMessageHandler()
*/