diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index ca378158897..119292c959e 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -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 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 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 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, diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index 108cc64d160..89c2fd63ec9 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -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); diff --git a/src/plugins/debugger/cdb/cdbparsehelpers.cpp b/src/plugins/debugger/cdb/cdbparsehelpers.cpp index d8bf3996d8d..f9e2d371cba 100644 --- a/src/plugins/debugger/cdb/cdbparsehelpers.cpp +++ b/src/plugins/debugger/cdb/cdbparsehelpers.cpp @@ -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; diff --git a/src/plugins/debugger/cdb/cdbparsehelpers.h b/src/plugins/debugger/cdb/cdbparsehelpers.h index 75018b08714..4c6a8170c9b 100644 --- a/src/plugins/debugger/cdb/cdbparsehelpers.h +++ b/src/plugins/debugger/cdb/cdbparsehelpers.h @@ -38,10 +38,6 @@ QString cdbAddBreakpointCommand(const BreakpointParameters &d, const QList > &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);