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 <hjk@qt.io>
This commit is contained in:
Friedemann Kleint
2024-09-19 14:38:32 +02:00
parent 26dcf27f4f
commit 0076ef4be6

View File

@@ -4235,13 +4235,43 @@ void GdbEngine::notifyInferiorSetupFailedHelper(const QString &msg)
notifyEngineSetupFailed(); 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<QStringView> 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() void GdbEngine::createFullBacktrace()
{ {
DebuggerCommand cmd("thread apply all bt full", NeedsTemporaryStop | ConsoleCommand); DebuggerCommand cmd("thread apply all bt full", NeedsTemporaryStop | ConsoleCommand);
cmd.callback = [](const DebuggerResponse &response) { cmd.callback = [](const DebuggerResponse &response) {
if (response.resultClass == ResultDone) { if (response.resultClass == ResultDone) {
Internal::openTextEditor("Backtrace$", Internal::openTextEditor("Backtrace$",
response.consoleStreamOutput + response.logStreamOutput); reverseBacktrace(response.consoleStreamOutput)
+ response.logStreamOutput);
} }
}; };
runCommand(cmd); runCommand(cmd);