forked from qt-creator/qt-creator
Debugger: map reported breakpoint file locations
Fixes: QTCREATORBUG-28521 Change-Id: I8229483df7fb0c51750e19d4558e81f5320e7f33 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -2872,6 +2872,56 @@ static void formatCdbBreakPointResponse(int modelId, const QString &responseId,
|
||||
str << '\n';
|
||||
}
|
||||
|
||||
|
||||
// Helper to retrieve an int child from GDBMI
|
||||
static inline std::optional<int> gdbmiChildToInt(const GdbMi &parent, const char *childName)
|
||||
{
|
||||
const GdbMi childBA = parent[childName];
|
||||
if (childBA.isValid()) {
|
||||
bool ok;
|
||||
const int v = childBA.data().toInt(&ok);
|
||||
if (ok)
|
||||
return v;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Helper to retrieve an bool child from GDBMI
|
||||
static inline std::optional<bool> gdbmiChildToBool(const GdbMi &parent, const char *childName)
|
||||
{
|
||||
const GdbMi childBA = parent[childName];
|
||||
return childBA.isValid() ? std::make_optional(childBA.data() == "true") : std::nullopt;
|
||||
}
|
||||
|
||||
// Parse extension command listing breakpoints.
|
||||
// Note that not all fields are returned, since file, line, function are encoded
|
||||
// in the expression (that is in addition deleted on resolving for a bp-type breakpoint).
|
||||
BreakpointParameters CdbEngine::parseBreakPoint(const GdbMi &gdbmi)
|
||||
{
|
||||
BreakpointParameters result;
|
||||
result.enabled = gdbmiChildToBool(gdbmi, "enabled").value_or(result.enabled);
|
||||
result.pending = gdbmiChildToBool(gdbmi, "deferred").value_or(result.pending);
|
||||
const GdbMi moduleG = gdbmi["module"];
|
||||
if (moduleG.isValid())
|
||||
result.module = moduleG.data();
|
||||
const GdbMi sourceFileName = gdbmi["srcfile"];
|
||||
if (sourceFileName.isValid()) {
|
||||
NormalizedSourceFileName mappedFile = sourceMapNormalizeFileNameFromDebugger(
|
||||
sourceFileName.data());
|
||||
result.fileName = Utils::FilePath::fromUserInput(mappedFile.fileName);
|
||||
const GdbMi lineNumber = gdbmi["srcline"];
|
||||
if (lineNumber.isValid())
|
||||
result.lineNumber = lineNumber.data().toULongLong(nullptr, 0);
|
||||
}
|
||||
const GdbMi addressG = gdbmi["address"];
|
||||
if (addressG.isValid())
|
||||
result.address = addressG.data().toULongLong(nullptr, 0);
|
||||
if (const std::optional<int> ignoreCount = gdbmiChildToInt(gdbmi, "passcount"))
|
||||
result.ignoreCount = *ignoreCount - 1;
|
||||
result.threadSpec = gdbmiChildToInt(gdbmi, "thread").value_or(result.threadSpec);
|
||||
return result;
|
||||
}
|
||||
|
||||
void CdbEngine::handleBreakPoints(const DebuggerResponse &response)
|
||||
{
|
||||
if (debugBreakpoints) {
|
||||
@@ -2897,8 +2947,7 @@ void CdbEngine::handleBreakPoints(const DebuggerResponse &response)
|
||||
for (const GdbMi &breakPointG : response.data) {
|
||||
// Might not be valid if there is not id
|
||||
const QString responseId = breakPointG["id"].data();
|
||||
BreakpointParameters reportedResponse;
|
||||
parseBreakPoint(breakPointG, &reportedResponse);
|
||||
BreakpointParameters reportedResponse = parseBreakPoint(breakPointG);
|
||||
if (debugBreakpoints)
|
||||
qDebug(" Parsed %s: pending=%d %s\n", qPrintable(responseId),
|
||||
reportedResponse.pending,
|
||||
|
@@ -168,6 +168,7 @@ private:
|
||||
unsigned parseStackTrace(const GdbMi &data, bool sourceStepInto);
|
||||
void mergeStartParametersSourcePathMap();
|
||||
void checkQtSdkPdbFiles(const QString &module);
|
||||
BreakpointParameters parseBreakPoint(const GdbMi &gdbmi);
|
||||
|
||||
const QString m_tokenPrefix;
|
||||
void handleSetupFailure(const QString &errorMessage);
|
||||
|
@@ -189,64 +189,6 @@ QString cdbClearBreakpointCommand(const Breakpoint &bp)
|
||||
return "bc " + QString::number(firstBreakPoint) + '-' + QString::number(lastBreakPoint);
|
||||
}
|
||||
|
||||
// Helper to retrieve an int child from GDBMI
|
||||
static inline bool gdbmiChildToInt(const GdbMi &parent, const char *childName, int *target)
|
||||
{
|
||||
const GdbMi childBA = parent[childName];
|
||||
if (childBA.isValid()) {
|
||||
bool ok;
|
||||
const int v = childBA.data().toInt(&ok);
|
||||
if (ok) {
|
||||
*target = v;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Helper to retrieve an bool child from GDBMI
|
||||
static inline bool gdbmiChildToBool(const GdbMi &parent, const char *childName, bool *target)
|
||||
{
|
||||
const GdbMi childBA = parent[childName];
|
||||
if (childBA.isValid()) {
|
||||
*target = childBA.data() == "true";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse extension command listing breakpoints.
|
||||
// Note that not all fields are returned, since file, line, function are encoded
|
||||
// in the expression (that is in addition deleted on resolving for a bp-type breakpoint).
|
||||
void parseBreakPoint(const GdbMi &gdbmi, BreakpointParameters *r,
|
||||
QString *expression /* = 0 */)
|
||||
{
|
||||
gdbmiChildToBool(gdbmi, "enabled", &(r->enabled));
|
||||
gdbmiChildToBool(gdbmi, "deferred", &(r->pending));
|
||||
const GdbMi moduleG = gdbmi["module"];
|
||||
if (moduleG.isValid())
|
||||
r->module = moduleG.data();
|
||||
const GdbMi sourceFileName = gdbmi["srcfile"];
|
||||
if (sourceFileName.isValid()) {
|
||||
r->fileName = Utils::FilePath::fromUserInput(
|
||||
Utils::FileUtils::normalizedPathName(sourceFileName.data()));
|
||||
const GdbMi lineNumber = gdbmi["srcline"];
|
||||
if (lineNumber.isValid())
|
||||
r->lineNumber = lineNumber.data().toULongLong(nullptr, 0);
|
||||
}
|
||||
if (expression) {
|
||||
const GdbMi expressionG = gdbmi["expression"];
|
||||
if (expressionG.isValid())
|
||||
*expression = expressionG.data();
|
||||
}
|
||||
const GdbMi addressG = gdbmi["address"];
|
||||
if (addressG.isValid())
|
||||
r->address = addressG.data().toULongLong(nullptr, 0);
|
||||
if (gdbmiChildToInt(gdbmi, "passcount", &(r->ignoreCount)))
|
||||
r->ignoreCount--;
|
||||
gdbmiChildToInt(gdbmi, "thread", &(r->threadSpec));
|
||||
}
|
||||
|
||||
QString cdbWriteMemoryCommand(quint64 addr, const QByteArray &data)
|
||||
{
|
||||
QString cmd;
|
||||
|
@@ -38,10 +38,6 @@ QString cdbAddBreakpointCommand(const BreakpointParameters &d,
|
||||
const QList<QPair<QString, QString> > &sourcePathMapping,
|
||||
const QString &responseId = QString());
|
||||
QString cdbClearBreakpointCommand(const Breakpoint &bp);
|
||||
// Parse extension command listing breakpoints.
|
||||
// Note that not all fields are returned, since file, line, function are encoded
|
||||
// in the expression (that is in addition deleted on resolving for a bp-type breakpoint).
|
||||
void parseBreakPoint(const GdbMi &gdbmi, BreakpointParameters *r, QString *expression = nullptr);
|
||||
|
||||
// Write memory (f ...).
|
||||
QString cdbWriteMemoryCommand(quint64 addr, const QByteArray &data);
|
||||
|
Reference in New Issue
Block a user