forked from qt-creator/qt-creator
Debugger: use FilePath in stack frames
Change-Id: I98b6aa60e1b72be3482916446b87cee89e6cf2a4 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -1079,7 +1079,7 @@ void CdbEngine::activateFrame(int index)
|
|||||||
|
|
||||||
if (debug || debugLocals)
|
if (debug || debugLocals)
|
||||||
qDebug("activateFrame idx=%d '%s' %d", index,
|
qDebug("activateFrame idx=%d '%s' %d", index,
|
||||||
qPrintable(frame.file), frame.line);
|
qPrintable(frame.file.toUserOutput()), frame.line);
|
||||||
stackHandler()->setCurrentIndex(index);
|
stackHandler()->setCurrentIndex(index);
|
||||||
gotoLocation(frame);
|
gotoLocation(frame);
|
||||||
if (m_pythonVersion > 0x030000)
|
if (m_pythonVersion > 0x030000)
|
||||||
@@ -2615,7 +2615,7 @@ static StackFrames parseFrames(const GdbMi &gdbmi, bool *incomplete = nullptr)
|
|||||||
frame.level = QString::number(i);
|
frame.level = QString::number(i);
|
||||||
const GdbMi fullName = frameMi["fullname"];
|
const GdbMi fullName = frameMi["fullname"];
|
||||||
if (fullName.isValid()) {
|
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.line = frameMi["line"].data().toInt();
|
||||||
frame.usable = false; // To be decided after source path mapping.
|
frame.usable = false; // To be decided after source path mapping.
|
||||||
const GdbMi languageMi = frameMi["language"];
|
const GdbMi languageMi = frameMi["language"];
|
||||||
@@ -2661,12 +2661,12 @@ unsigned CdbEngine::parseStackTrace(const GdbMi &data, bool sourceStepInto)
|
|||||||
return ParseStackStepOut;
|
return ParseStackStepOut;
|
||||||
}
|
}
|
||||||
if (hasFile) {
|
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) {
|
if (!fileName.exists && i == 0 && sourceStepInto) {
|
||||||
showMessage("Step into: Hit frame with no source, step out...", LogMisc);
|
showMessage("Step into: Hit frame with no source, step out...", LogMisc);
|
||||||
return ParseStackStepOut;
|
return ParseStackStepOut;
|
||||||
}
|
}
|
||||||
frames[i].file = fileName.fileName;
|
frames[i].file = FilePath::fromString(fileName.fileName);
|
||||||
frames[i].usable = fileName.exists;
|
frames[i].usable = fileName.exists;
|
||||||
if (current == -1 && frames[i].usable)
|
if (current == -1 && frames[i].usable)
|
||||||
current = i;
|
current = i;
|
||||||
|
@@ -161,7 +161,7 @@ static bool debuggerActionsEnabledHelper(DebuggerState state)
|
|||||||
|
|
||||||
Location::Location(const StackFrame &frame, bool marker)
|
Location::Location(const StackFrame &frame, bool marker)
|
||||||
{
|
{
|
||||||
m_fileName = Utils::FilePath::fromString(frame.file);
|
m_fileName = frame.file;
|
||||||
m_lineNumber = frame.line;
|
m_lineNumber = frame.line;
|
||||||
m_needsMarker = marker;
|
m_needsMarker = marker;
|
||||||
m_functionName = frame.function;
|
m_functionName = frame.function;
|
||||||
|
@@ -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())
|
return file1.canonicalPath() == file2.canonicalPath();
|
||||||
== FilePath::fromString(QFileInfo(file2).canonicalFilePath());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DebuggerToolTipContext::matchesFrame(const StackFrame &frame) const
|
bool DebuggerToolTipContext::matchesFrame(const StackFrame &frame) const
|
||||||
@@ -945,7 +944,7 @@ void DebuggerToolTipHolder::saveSessionData(QXmlStreamWriter &w) const
|
|||||||
w.writeStartElement(toolTipElementC);
|
w.writeStartElement(toolTipElementC);
|
||||||
QXmlStreamAttributes attributes;
|
QXmlStreamAttributes attributes;
|
||||||
// attributes.append(toolTipClassAttributeC, QString::fromLatin1(metaObject()->className()));
|
// attributes.append(toolTipClassAttributeC, QString::fromLatin1(metaObject()->className()));
|
||||||
attributes.append(fileNameAttributeC, context.fileName);
|
attributes.append(fileNameAttributeC, context.fileName.toString());
|
||||||
if (!context.function.isEmpty())
|
if (!context.function.isEmpty())
|
||||||
attributes.append(functionAttributeC, context.function);
|
attributes.append(functionAttributeC, context.function);
|
||||||
attributes.append(textPositionAttributeC, QString::number(context.position));
|
attributes.append(textPositionAttributeC, QString::number(context.position));
|
||||||
@@ -1019,15 +1018,15 @@ void DebuggerToolTipManagerPrivate::updateVisibleToolTips()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString fileName = toolTipEditor->textDocument()->filePath().toString();
|
const FilePath filePath = toolTipEditor->textDocument()->filePath();
|
||||||
if (fileName.isEmpty()) {
|
if (filePath.isEmpty()) {
|
||||||
hideAllToolTips();
|
hideAllToolTips();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reposition and show all tooltips of that file.
|
// Reposition and show all tooltips of that file.
|
||||||
for (DebuggerToolTipHolder *tooltip : qAsConst(m_tooltips)) {
|
for (DebuggerToolTipHolder *tooltip : qAsConst(m_tooltips)) {
|
||||||
if (tooltip->context.fileName == fileName)
|
if (tooltip->context.fileName == filePath)
|
||||||
tooltip->positionShow(toolTipEditor->editorWidget());
|
tooltip->positionShow(toolTipEditor->editorWidget());
|
||||||
else
|
else
|
||||||
tooltip->widget->hide();
|
tooltip->widget->hide();
|
||||||
@@ -1085,7 +1084,8 @@ void DebuggerToolTipManagerPrivate::loadSessionData()
|
|||||||
if (readStartElement(r, toolTipElementC)) {
|
if (readStartElement(r, toolTipElementC)) {
|
||||||
const QXmlStreamAttributes attributes = r.attributes();
|
const QXmlStreamAttributes attributes = r.attributes();
|
||||||
DebuggerToolTipContext context;
|
DebuggerToolTipContext context;
|
||||||
context.fileName = attributes.value(fileNameAttributeC).toString();
|
context.fileName = FilePath::fromString(
|
||||||
|
attributes.value(fileNameAttributeC).toString());
|
||||||
context.position = attributes.value(textPositionAttributeC).toString().toInt();
|
context.position = attributes.value(textPositionAttributeC).toString().toInt();
|
||||||
context.line = attributes.value(textLineAttributeC).toString().toInt();
|
context.line = attributes.value(textLineAttributeC).toString().toInt();
|
||||||
context.column = attributes.value(textColumnAttributeC).toString().toInt();
|
context.column = attributes.value(textColumnAttributeC).toString().toInt();
|
||||||
@@ -1197,7 +1197,7 @@ void DebuggerToolTipManagerPrivate::slotTooltipOverrideRequested
|
|||||||
|
|
||||||
DebuggerToolTipContext context;
|
DebuggerToolTipContext context;
|
||||||
context.engineType = m_engine->objectName();
|
context.engineType = m_engine->objectName();
|
||||||
context.fileName = document->filePath().toString();
|
context.fileName = document->filePath();
|
||||||
context.position = pos;
|
context.position = pos;
|
||||||
editorWidget->convertPosition(pos, &context.line, &context.column);
|
editorWidget->convertPosition(pos, &context.line, &context.column);
|
||||||
QString raw = cppExpressionAt(editorWidget, context.position, &context.line, &context.column,
|
QString raw = cppExpressionAt(editorWidget, context.position, &context.line, &context.column,
|
||||||
|
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include "debuggerconstants.h"
|
#include "debuggerconstants.h"
|
||||||
|
|
||||||
|
#include <utils/filepath.h>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDate>
|
#include <QDate>
|
||||||
#include <QPoint>
|
#include <QPoint>
|
||||||
@@ -46,7 +48,7 @@ public:
|
|||||||
bool isSame(const DebuggerToolTipContext &other) const;
|
bool isSame(const DebuggerToolTipContext &other) const;
|
||||||
QString toolTip() const;
|
QString toolTip() const;
|
||||||
|
|
||||||
QString fileName;
|
Utils::FilePath fileName;
|
||||||
int position;
|
int position;
|
||||||
int line;
|
int line;
|
||||||
int column;
|
int column;
|
||||||
|
@@ -346,11 +346,11 @@ void PdbEngine::refreshState(const GdbMi &reportedState)
|
|||||||
void PdbEngine::refreshLocation(const GdbMi &reportedLocation)
|
void PdbEngine::refreshLocation(const GdbMi &reportedLocation)
|
||||||
{
|
{
|
||||||
StackFrame frame;
|
StackFrame frame;
|
||||||
frame.file = reportedLocation["file"].data();
|
frame.file = Utils::FilePath::fromString(reportedLocation["file"].data());
|
||||||
frame.line = reportedLocation["line"].toInt();
|
frame.line = reportedLocation["line"].toInt();
|
||||||
frame.usable = QFileInfo(frame.file).isReadable();
|
frame.usable = frame.file.isReadableFile();
|
||||||
if (state() == InferiorRunOk) {
|
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);
|
gotoLocation(frame);
|
||||||
notifyInferiorSpontaneousStop();
|
notifyInferiorSpontaneousStop();
|
||||||
updateAll();
|
updateAll();
|
||||||
@@ -535,7 +535,7 @@ void PdbEngine::refreshStack(const GdbMi &stack)
|
|||||||
for (const GdbMi &item : stack["frames"]) {
|
for (const GdbMi &item : stack["frames"]) {
|
||||||
StackFrame frame;
|
StackFrame frame;
|
||||||
frame.level = item["level"].data();
|
frame.level = item["level"].data();
|
||||||
frame.file = item["file"].data();
|
frame.file = Utils::FilePath::fromString(item["file"].data());
|
||||||
frame.function = item["function"].data();
|
frame.function = item["function"].data();
|
||||||
frame.module = item["function"].data();
|
frame.module = item["function"].data();
|
||||||
frame.line = item["line"].toInt();
|
frame.line = item["line"].toInt();
|
||||||
@@ -544,7 +544,7 @@ void PdbEngine::refreshStack(const GdbMi &stack)
|
|||||||
if (usable.isValid())
|
if (usable.isValid())
|
||||||
frame.usable = usable.data().toInt();
|
frame.usable = usable.data().toInt();
|
||||||
else
|
else
|
||||||
frame.usable = QFileInfo(frame.file).isReadable();
|
frame.usable = frame.file.isReadableFile();
|
||||||
frames.append(frame);
|
frames.append(frame);
|
||||||
}
|
}
|
||||||
bool canExpand = stack["hasmore"].toInt();
|
bool canExpand = stack["hasmore"].toInt();
|
||||||
|
@@ -2036,8 +2036,9 @@ StackFrame QmlEnginePrivate::extractStackFrame(const QVariant &bodyVal)
|
|||||||
stackFrame.function = extractString(body.value("func"));
|
stackFrame.function = extractString(body.value("func"));
|
||||||
if (stackFrame.function.isEmpty())
|
if (stackFrame.function.isEmpty())
|
||||||
stackFrame.function = QCoreApplication::translate("QmlEngine", "Anonymous Function");
|
stackFrame.function = QCoreApplication::translate("QmlEngine", "Anonymous Function");
|
||||||
stackFrame.file = engine->toFileInProject(extractString(body.value("script")));
|
stackFrame.file = FilePath::fromString(
|
||||||
stackFrame.usable = QFileInfo(stackFrame.file).isReadable();
|
engine->toFileInProject(extractString(body.value("script"))));
|
||||||
|
stackFrame.usable = stackFrame.file.isReadableFile();
|
||||||
stackFrame.receiver = extractString(body.value("receiver"));
|
stackFrame.receiver = extractString(body.value("receiver"));
|
||||||
stackFrame.line = body.value("line").toInt() + 1;
|
stackFrame.line = body.value("line").toInt() + 1;
|
||||||
|
|
||||||
|
@@ -134,7 +134,7 @@ void SourceAgent::updateLocationMarker()
|
|||||||
d->editor->textDocument()->removeMark(d->locationMark);
|
d->editor->textDocument()->removeMark(d->locationMark);
|
||||||
delete d->locationMark;
|
delete d->locationMark;
|
||||||
d->locationMark = nullptr;
|
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;
|
int lineNumber = d->engine->stackHandler()->currentFrame().line;
|
||||||
|
|
||||||
d->locationMark = new TextMark(Utils::FilePath(), lineNumber,
|
d->locationMark = new TextMark(Utils::FilePath(), lineNumber,
|
||||||
|
@@ -190,7 +190,7 @@ static void blockRecursion(const Overview &overview,
|
|||||||
|
|
||||||
QStringList getUninitializedVariables(const Snapshot &snapshot,
|
QStringList getUninitializedVariables(const Snapshot &snapshot,
|
||||||
const QString &functionName,
|
const QString &functionName,
|
||||||
const QString &file,
|
const FilePath &file,
|
||||||
int line)
|
int line)
|
||||||
{
|
{
|
||||||
QStringList result;
|
QStringList result;
|
||||||
|
@@ -33,6 +33,7 @@ class TextDocument;
|
|||||||
class TextEditorWidget;
|
class TextEditorWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Utils { class FilePath; }
|
||||||
namespace CPlusPlus { class Snapshot; }
|
namespace CPlusPlus { class Snapshot; }
|
||||||
|
|
||||||
namespace Debugger {
|
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
|
// of a function from the code model. Shadowed variables will
|
||||||
// be reported using the debugger naming conventions '<shadowed n>'
|
// be reported using the debugger naming conventions '<shadowed n>'
|
||||||
QStringList getUninitializedVariables(const CPlusPlus::Snapshot &snapshot,
|
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);
|
ContextData getLocationContext(TextEditor::TextDocument *document, int lineNumber);
|
||||||
|
|
||||||
|
@@ -35,6 +35,8 @@
|
|||||||
|
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -93,7 +95,7 @@ StackFrame StackFrame::parseFrame(const GdbMi &frameMi, const DebuggerRunParamet
|
|||||||
frame.level = frameMi["level"].data();
|
frame.level = frameMi["level"].data();
|
||||||
frame.function = frameMi["function"].data();
|
frame.function = frameMi["function"].data();
|
||||||
frame.module = frameMi["module"].data();
|
frame.module = frameMi["module"].data();
|
||||||
frame.file = frameMi["file"].data();
|
frame.file = FilePath::fromString(frameMi["file"].data());
|
||||||
frame.line = frameMi["line"].toInt();
|
frame.line = frameMi["line"].toInt();
|
||||||
frame.address = frameMi["address"].toAddress();
|
frame.address = frameMi["address"].toAddress();
|
||||||
frame.context = frameMi["context"].data();
|
frame.context = frameMi["context"].data();
|
||||||
@@ -107,13 +109,13 @@ StackFrame StackFrame::parseFrame(const GdbMi &frameMi, const DebuggerRunParamet
|
|||||||
if (usable.isValid())
|
if (usable.isValid())
|
||||||
frame.usable = usable.data().toInt();
|
frame.usable = usable.data().toInt();
|
||||||
else
|
else
|
||||||
frame.usable = QFileInfo(frame.file).isReadable();
|
frame.usable = frame.file.isReadableFile();
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString StackFrame::toToolTip() const
|
QString StackFrame::toToolTip() const
|
||||||
{
|
{
|
||||||
const QString filePath = QDir::toNativeSeparators(file);
|
const QString filePath = file.toUserOutput();
|
||||||
QString res;
|
QString res;
|
||||||
QTextStream str(&res);
|
QTextStream str(&res);
|
||||||
str << "<html><body><table>";
|
str << "<html><body><table>";
|
||||||
@@ -150,7 +152,7 @@ QString StackFrame::toToolTip() const
|
|||||||
"frame. However, matching sources have not been found.");
|
"frame. However, matching sources have not been found.");
|
||||||
showDistributionNote = true;
|
showDistributionNote = true;
|
||||||
}
|
}
|
||||||
if (!Utils::HostOsInfo::isWindowsHost() && showDistributionNote) {
|
if (!HostOsInfo::isWindowsHost() && showDistributionNote) {
|
||||||
str << ' ' << tr("Note that most distributions ship debug information "
|
str << ' ' << tr("Note that most distributions ship debug information "
|
||||||
"in separate packages.");
|
"in separate packages.");
|
||||||
}
|
}
|
||||||
@@ -159,19 +161,14 @@ QString StackFrame::toToolTip() const
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString findFile(const QString &baseDir, const QString &relativeFile)
|
static FilePath findFile(const FilePath &baseDir, const FilePath &relativeFile)
|
||||||
{
|
{
|
||||||
QDir dir(baseDir);
|
for (FilePath dir(baseDir); !dir.isEmpty(); dir = dir.parentDir()) {
|
||||||
while (true) {
|
const FilePath absolutePath = dir.resolvePath(relativeFile);
|
||||||
const QString path = dir.absoluteFilePath(relativeFile);
|
if (absolutePath.isFile())
|
||||||
const QFileInfo fi(path);
|
return absolutePath;
|
||||||
if (fi.isFile())
|
|
||||||
return path;
|
|
||||||
if (dir.isRoot())
|
|
||||||
break;
|
|
||||||
dir.cdUp();
|
|
||||||
}
|
}
|
||||||
return QString();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to resolve files coming from resource files.
|
// Try to resolve files coming from resource files.
|
||||||
@@ -179,21 +176,23 @@ void StackFrame::fixQrcFrame(const DebuggerRunParameters &rp)
|
|||||||
{
|
{
|
||||||
if (language != QmlLanguage)
|
if (language != QmlLanguage)
|
||||||
return;
|
return;
|
||||||
QFileInfo aFi(file);
|
if (file.isAbsolutePath()) {
|
||||||
if (aFi.isAbsolute()) {
|
usable = file.isFile();
|
||||||
usable = aFi.isFile();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!file.startsWith("qrc:/"))
|
if (!file.startsWith("qrc:/"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString relativeFile = file.right(file.size() - 5);
|
FilePath relativeFile = file;
|
||||||
while (relativeFile.startsWith('/'))
|
QString relativePath = file.path();
|
||||||
relativeFile = relativeFile.mid(1);
|
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())
|
if (absFile.isEmpty())
|
||||||
absFile = findFile(QDir::currentPath(), relativeFile);
|
absFile = findFile(FilePath::fromString(QDir::currentPath()), relativeFile);
|
||||||
|
|
||||||
if (absFile.isEmpty())
|
if (absFile.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include "debuggerconstants.h"
|
#include "debuggerconstants.h"
|
||||||
|
|
||||||
|
#include <utils/filepath.h>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
|
|
||||||
@@ -56,7 +58,7 @@ public:
|
|||||||
DebuggerLanguage language = CppLanguage;
|
DebuggerLanguage language = CppLanguage;
|
||||||
QString level;
|
QString level;
|
||||||
QString function;
|
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 module; // Sometimes something like "/usr/lib/libstdc++.so.6"
|
||||||
QString receiver; // Used in ScriptEngine only.
|
QString receiver; // Used in ScriptEngine only.
|
||||||
qint32 line = -1;
|
qint32 line = -1;
|
||||||
|
@@ -101,7 +101,7 @@ QVariant StackFrameItem::data(int column, int role) const
|
|||||||
case StackFunctionNameColumn:
|
case StackFunctionNameColumn:
|
||||||
return simplifyType(frame.function);
|
return simplifyType(frame.function);
|
||||||
case StackFileNameColumn:
|
case StackFileNameColumn:
|
||||||
return frame.file.isEmpty() ? frame.module : FilePath::fromString(frame.file).fileName();
|
return frame.file.isEmpty() ? frame.module : frame.file.fileName();
|
||||||
case StackLineNumberColumn:
|
case StackLineNumberColumn:
|
||||||
return frame.line > 0 ? QVariant(frame.line) : QVariant();
|
return frame.line > 0 ? QVariant(frame.line) : QVariant();
|
||||||
case StackAddressColumn:
|
case StackAddressColumn:
|
||||||
|
Reference in New Issue
Block a user