From 0076ef4be6771d0e51a0e15154b73710cf8ea0a9 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 19 Sep 2024 14:38:32 +0200 Subject: [PATCH] Debugger: Reverse gdb stack traces when creating full back traces By default, threads are sorted in descending order. This change brings thread 1, which is ususally the most interesting frame, to the front. Change-Id: Ie8b0d6b849da8b8d816bca907e5a8efa7e46c473 Reviewed-by: hjk --- src/plugins/debugger/gdb/gdbengine.cpp | 32 +++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 2be678120d6..24214212241 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -4235,13 +4235,43 @@ void GdbEngine::notifyInferiorSetupFailedHelper(const QString &msg) notifyEngineSetupFailed(); } +static QString reverseBacktrace(const QString &trace) +{ + static const QRegularExpression threadPattern(R"(Thread \d+ \(Thread )"); + Q_ASSERT(threadPattern.isValid()); + + if (!trace.contains(threadPattern)) // Pattern mismatch fallback + return trace; + + const QStringView traceView{trace}; + QList threadTraces; + const auto traceSize = traceView.size(); + for (qsizetype pos = 0; pos < traceSize; ) { + auto nextThreadPos = traceView.indexOf(threadPattern, pos + 1); + if (nextThreadPos == -1) + nextThreadPos = traceSize; + threadTraces.append(traceView.sliced(pos, nextThreadPos - pos)); + pos = nextThreadPos; + } + + QString result; + result.reserve(traceSize); + for (auto it = threadTraces.crbegin(), end = threadTraces.crend(); it != end; ++it) { + result += *it; + if (result.endsWith('\n')) + result += '\n'; + } + return result; +} + void GdbEngine::createFullBacktrace() { DebuggerCommand cmd("thread apply all bt full", NeedsTemporaryStop | ConsoleCommand); cmd.callback = [](const DebuggerResponse &response) { if (response.resultClass == ResultDone) { Internal::openTextEditor("Backtrace$", - response.consoleStreamOutput + response.logStreamOutput); + reverseBacktrace(response.consoleStreamOutput) + + response.logStreamOutput); } }; runCommand(cmd);