forked from qt-creator/qt-creator
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:
@@ -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);
|
||||||
|
Reference in New Issue
Block a user