Debugger: use FilePath in stack frames

Change-Id: I98b6aa60e1b72be3482916446b87cee89e6cf2a4
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
David Schulz
2021-10-26 10:48:43 +02:00
parent 67607e4bc6
commit bc55c7cc70
12 changed files with 55 additions and 50 deletions

View File

@@ -1079,7 +1079,7 @@ void CdbEngine::activateFrame(int index)
if (debug || debugLocals)
qDebug("activateFrame idx=%d '%s' %d", index,
qPrintable(frame.file), frame.line);
qPrintable(frame.file.toUserOutput()), frame.line);
stackHandler()->setCurrentIndex(index);
gotoLocation(frame);
if (m_pythonVersion > 0x030000)
@@ -2615,7 +2615,7 @@ static StackFrames parseFrames(const GdbMi &gdbmi, bool *incomplete = nullptr)
frame.level = QString::number(i);
const GdbMi fullName = frameMi["fullname"];
if (fullName.isValid()) {
frame.file = Utils::FileUtils::normalizedPathName(fullName.data());
frame.file = Utils::FilePath::fromString(fullName.data()).normalizedPathName();
frame.line = frameMi["line"].data().toInt();
frame.usable = false; // To be decided after source path mapping.
const GdbMi languageMi = frameMi["language"];
@@ -2661,12 +2661,12 @@ unsigned CdbEngine::parseStackTrace(const GdbMi &data, bool sourceStepInto)
return ParseStackStepOut;
}
if (hasFile) {
const NormalizedSourceFileName fileName = sourceMapNormalizeFileNameFromDebugger(frames.at(i).file);
const NormalizedSourceFileName fileName = sourceMapNormalizeFileNameFromDebugger(frames.at(i).file.toString());
if (!fileName.exists && i == 0 && sourceStepInto) {
showMessage("Step into: Hit frame with no source, step out...", LogMisc);
return ParseStackStepOut;
}
frames[i].file = fileName.fileName;
frames[i].file = FilePath::fromString(fileName.fileName);
frames[i].usable = fileName.exists;
if (current == -1 && frames[i].usable)
current = i;

View File

@@ -161,7 +161,7 @@ static bool debuggerActionsEnabledHelper(DebuggerState state)
Location::Location(const StackFrame &frame, bool marker)
{
m_fileName = Utils::FilePath::fromString(frame.file);
m_fileName = frame.file;
m_lineNumber = frame.line;
m_needsMarker = marker;
m_functionName = frame.function;

View File

@@ -718,10 +718,9 @@ DebuggerToolTipContext::DebuggerToolTipContext()
{
}
static bool filesMatch(const QString &file1, const QString &file2)
static bool filesMatch(const FilePath &file1, const FilePath &file2)
{
return FilePath::fromString(QFileInfo(file1).canonicalFilePath())
== FilePath::fromString(QFileInfo(file2).canonicalFilePath());
return file1.canonicalPath() == file2.canonicalPath();
}
bool DebuggerToolTipContext::matchesFrame(const StackFrame &frame) const
@@ -945,7 +944,7 @@ void DebuggerToolTipHolder::saveSessionData(QXmlStreamWriter &w) const
w.writeStartElement(toolTipElementC);
QXmlStreamAttributes attributes;
// attributes.append(toolTipClassAttributeC, QString::fromLatin1(metaObject()->className()));
attributes.append(fileNameAttributeC, context.fileName);
attributes.append(fileNameAttributeC, context.fileName.toString());
if (!context.function.isEmpty())
attributes.append(functionAttributeC, context.function);
attributes.append(textPositionAttributeC, QString::number(context.position));
@@ -1019,15 +1018,15 @@ void DebuggerToolTipManagerPrivate::updateVisibleToolTips()
return;
}
const QString fileName = toolTipEditor->textDocument()->filePath().toString();
if (fileName.isEmpty()) {
const FilePath filePath = toolTipEditor->textDocument()->filePath();
if (filePath.isEmpty()) {
hideAllToolTips();
return;
}
// Reposition and show all tooltips of that file.
for (DebuggerToolTipHolder *tooltip : qAsConst(m_tooltips)) {
if (tooltip->context.fileName == fileName)
if (tooltip->context.fileName == filePath)
tooltip->positionShow(toolTipEditor->editorWidget());
else
tooltip->widget->hide();
@@ -1085,7 +1084,8 @@ void DebuggerToolTipManagerPrivate::loadSessionData()
if (readStartElement(r, toolTipElementC)) {
const QXmlStreamAttributes attributes = r.attributes();
DebuggerToolTipContext context;
context.fileName = attributes.value(fileNameAttributeC).toString();
context.fileName = FilePath::fromString(
attributes.value(fileNameAttributeC).toString());
context.position = attributes.value(textPositionAttributeC).toString().toInt();
context.line = attributes.value(textLineAttributeC).toString().toInt();
context.column = attributes.value(textColumnAttributeC).toString().toInt();
@@ -1197,7 +1197,7 @@ void DebuggerToolTipManagerPrivate::slotTooltipOverrideRequested
DebuggerToolTipContext context;
context.engineType = m_engine->objectName();
context.fileName = document->filePath().toString();
context.fileName = document->filePath();
context.position = pos;
editorWidget->convertPosition(pos, &context.line, &context.column);
QString raw = cppExpressionAt(editorWidget, context.position, &context.line, &context.column,

View File

@@ -27,6 +27,8 @@
#include "debuggerconstants.h"
#include <utils/filepath.h>
#include <QCoreApplication>
#include <QDate>
#include <QPoint>
@@ -46,7 +48,7 @@ public:
bool isSame(const DebuggerToolTipContext &other) const;
QString toolTip() const;
QString fileName;
Utils::FilePath fileName;
int position;
int line;
int column;

View File

@@ -346,11 +346,11 @@ void PdbEngine::refreshState(const GdbMi &reportedState)
void PdbEngine::refreshLocation(const GdbMi &reportedLocation)
{
StackFrame frame;
frame.file = reportedLocation["file"].data();
frame.file = Utils::FilePath::fromString(reportedLocation["file"].data());
frame.line = reportedLocation["line"].toInt();
frame.usable = QFileInfo(frame.file).isReadable();
frame.usable = frame.file.isReadableFile();
if (state() == InferiorRunOk) {
showMessage(QString("STOPPED AT: %1:%2").arg(frame.file).arg(frame.line));
showMessage(QString("STOPPED AT: %1:%2").arg(frame.file.toUserOutput()).arg(frame.line));
gotoLocation(frame);
notifyInferiorSpontaneousStop();
updateAll();
@@ -535,7 +535,7 @@ void PdbEngine::refreshStack(const GdbMi &stack)
for (const GdbMi &item : stack["frames"]) {
StackFrame frame;
frame.level = item["level"].data();
frame.file = item["file"].data();
frame.file = Utils::FilePath::fromString(item["file"].data());
frame.function = item["function"].data();
frame.module = item["function"].data();
frame.line = item["line"].toInt();
@@ -544,7 +544,7 @@ void PdbEngine::refreshStack(const GdbMi &stack)
if (usable.isValid())
frame.usable = usable.data().toInt();
else
frame.usable = QFileInfo(frame.file).isReadable();
frame.usable = frame.file.isReadableFile();
frames.append(frame);
}
bool canExpand = stack["hasmore"].toInt();

View File

@@ -2036,8 +2036,9 @@ StackFrame QmlEnginePrivate::extractStackFrame(const QVariant &bodyVal)
stackFrame.function = extractString(body.value("func"));
if (stackFrame.function.isEmpty())
stackFrame.function = QCoreApplication::translate("QmlEngine", "Anonymous Function");
stackFrame.file = engine->toFileInProject(extractString(body.value("script")));
stackFrame.usable = QFileInfo(stackFrame.file).isReadable();
stackFrame.file = FilePath::fromString(
engine->toFileInProject(extractString(body.value("script"))));
stackFrame.usable = stackFrame.file.isReadableFile();
stackFrame.receiver = extractString(body.value("receiver"));
stackFrame.line = body.value("line").toInt() + 1;

View File

@@ -134,7 +134,7 @@ void SourceAgent::updateLocationMarker()
d->editor->textDocument()->removeMark(d->locationMark);
delete d->locationMark;
d->locationMark = nullptr;
if (d->engine->stackHandler()->currentFrame().file == d->path) {
if (d->engine->stackHandler()->currentFrame().file == Utils::FilePath::fromString(d->path)) {
int lineNumber = d->engine->stackHandler()->currentFrame().line;
d->locationMark = new TextMark(Utils::FilePath(), lineNumber,

View File

@@ -190,7 +190,7 @@ static void blockRecursion(const Overview &overview,
QStringList getUninitializedVariables(const Snapshot &snapshot,
const QString &functionName,
const QString &file,
const FilePath &file,
int line)
{
QStringList result;

View File

@@ -33,6 +33,7 @@ class TextDocument;
class TextEditorWidget;
}
namespace Utils { class FilePath; }
namespace CPlusPlus { class Snapshot; }
namespace Debugger {
@@ -52,7 +53,7 @@ QString cppFunctionAt(const QString &fileName, int line, int column = 0);
// of a function from the code model. Shadowed variables will
// be reported using the debugger naming conventions '<shadowed n>'
QStringList getUninitializedVariables(const CPlusPlus::Snapshot &snapshot,
const QString &function, const QString &file, int line);
const QString &function, const Utils::FilePath &file, int line);
ContextData getLocationContext(TextEditor::TextDocument *document, int lineNumber);

View File

@@ -35,6 +35,8 @@
#include <utils/hostosinfo.h>
using namespace Utils;
namespace Debugger {
namespace Internal {
@@ -93,7 +95,7 @@ StackFrame StackFrame::parseFrame(const GdbMi &frameMi, const DebuggerRunParamet
frame.level = frameMi["level"].data();
frame.function = frameMi["function"].data();
frame.module = frameMi["module"].data();
frame.file = frameMi["file"].data();
frame.file = FilePath::fromString(frameMi["file"].data());
frame.line = frameMi["line"].toInt();
frame.address = frameMi["address"].toAddress();
frame.context = frameMi["context"].data();
@@ -107,13 +109,13 @@ StackFrame StackFrame::parseFrame(const GdbMi &frameMi, const DebuggerRunParamet
if (usable.isValid())
frame.usable = usable.data().toInt();
else
frame.usable = QFileInfo(frame.file).isReadable();
frame.usable = frame.file.isReadableFile();
return frame;
}
QString StackFrame::toToolTip() const
{
const QString filePath = QDir::toNativeSeparators(file);
const QString filePath = file.toUserOutput();
QString res;
QTextStream str(&res);
str << "<html><body><table>";
@@ -150,7 +152,7 @@ QString StackFrame::toToolTip() const
"frame. However, matching sources have not been found.");
showDistributionNote = true;
}
if (!Utils::HostOsInfo::isWindowsHost() && showDistributionNote) {
if (!HostOsInfo::isWindowsHost() && showDistributionNote) {
str << ' ' << tr("Note that most distributions ship debug information "
"in separate packages.");
}
@@ -159,19 +161,14 @@ QString StackFrame::toToolTip() const
return res;
}
static QString findFile(const QString &baseDir, const QString &relativeFile)
static FilePath findFile(const FilePath &baseDir, const FilePath &relativeFile)
{
QDir dir(baseDir);
while (true) {
const QString path = dir.absoluteFilePath(relativeFile);
const QFileInfo fi(path);
if (fi.isFile())
return path;
if (dir.isRoot())
break;
dir.cdUp();
for (FilePath dir(baseDir); !dir.isEmpty(); dir = dir.parentDir()) {
const FilePath absolutePath = dir.resolvePath(relativeFile);
if (absolutePath.isFile())
return absolutePath;
}
return QString();
return {};
}
// Try to resolve files coming from resource files.
@@ -179,21 +176,23 @@ void StackFrame::fixQrcFrame(const DebuggerRunParameters &rp)
{
if (language != QmlLanguage)
return;
QFileInfo aFi(file);
if (aFi.isAbsolute()) {
usable = aFi.isFile();
if (file.isAbsolutePath()) {
usable = file.isFile();
return;
}
if (!file.startsWith("qrc:/"))
return;
QString relativeFile = file.right(file.size() - 5);
while (relativeFile.startsWith('/'))
relativeFile = relativeFile.mid(1);
FilePath relativeFile = file;
QString relativePath = file.path();
relativePath = relativePath.right(relativePath.size() - 5);
while (relativePath.startsWith('/'))
relativePath = relativePath.mid(1);
relativeFile.setPath(relativePath);
QString absFile = findFile(rp.projectSourceDirectory.toString(), relativeFile);
FilePath absFile = findFile(rp.projectSourceDirectory, relativeFile);
if (absFile.isEmpty())
absFile = findFile(QDir::currentPath(), relativeFile);
absFile = findFile(FilePath::fromString(QDir::currentPath()), relativeFile);
if (absFile.isEmpty())
return;

View File

@@ -27,6 +27,8 @@
#include "debuggerconstants.h"
#include <utils/filepath.h>
#include <QCoreApplication>
#include <QMetaType>
@@ -56,7 +58,7 @@ public:
DebuggerLanguage language = CppLanguage;
QString level;
QString function;
QString file; // We try to put an absolute file name in there.
Utils::FilePath file;// We try to put an absolute file name in there.
QString module; // Sometimes something like "/usr/lib/libstdc++.so.6"
QString receiver; // Used in ScriptEngine only.
qint32 line = -1;

View File

@@ -101,7 +101,7 @@ QVariant StackFrameItem::data(int column, int role) const
case StackFunctionNameColumn:
return simplifyType(frame.function);
case StackFileNameColumn:
return frame.file.isEmpty() ? frame.module : FilePath::fromString(frame.file).fileName();
return frame.file.isEmpty() ? frame.module : frame.file.fileName();
case StackLineNumberColumn:
return frame.line > 0 ? QVariant(frame.line) : QVariant();
case StackAddressColumn: