Debugger: Introduce BreakpointParameters as base struct.

For Breakpoint data manipulation.

Reviewed-by: hjk
This commit is contained in:
Friedemann Kleint
2010-11-15 17:04:29 +01:00
parent 50dc4d8664
commit 9fc5970bdb
10 changed files with 201 additions and 195 deletions

View File

@@ -97,26 +97,26 @@ static bool isSimilarTo(const BreakpointData &data, const BreakpointResponse &ne
{ {
// Clear hit. // Clear hit.
// Clear miss. // Clear miss.
if (needle.bpType != UnknownType && data.type() != UnknownType if (needle.type != UnknownType && data.type() != UnknownType
&& data.type() != needle.bpType) && data.type() != needle.type)
return false; return false;
// Clear hit. // Clear hit.
if (data.address() && data.address() == needle.bpAddress) if (data.address() && data.address() == needle.address)
return true; return true;
// At least at a position we were looking for. // At least at a position we were looking for.
// FIXME: breaks multiple breakpoints at the same location // FIXME: breaks multiple breakpoints at the same location
if (!data.fileName().isEmpty() if (!data.fileName().isEmpty()
&& fileNameMatch(data.fileName(), needle.bpFileName) && fileNameMatch(data.fileName(), needle.fileName)
&& data.lineNumber() == needle.bpLineNumber) && data.lineNumber() == needle.lineNumber)
return true; return true;
// At least at a position we were looking for. // At least at a position we were looking for.
// FIXME: breaks multiple breakpoints at the same location // FIXME: breaks multiple breakpoints at the same location
if (!data.fileName().isEmpty() if (!data.fileName().isEmpty()
&& fileNameMatch(data.fileName(), needle.bpFileName) && fileNameMatch(data.fileName(), needle.fileName)
&& data.lineNumber() == needle.bpLineNumber) && data.lineNumber() == needle.lineNumber)
return true; return true;
return false; return false;
@@ -131,7 +131,7 @@ BreakpointId BreakHandler::findSimilarBreakpoint(const BreakpointResponse &needl
const BreakpointData &data = it->data; const BreakpointData &data = it->data;
const BreakpointResponse &response = it->response; const BreakpointResponse &response = it->response;
qDebug() << "COMPARING " << data.toString() << " WITH " << needle.toString(); qDebug() << "COMPARING " << data.toString() << " WITH " << needle.toString();
if (response.bpNumber && response.bpNumber == needle.bpNumber) if (response.number && response.number == needle.number)
return id; return id;
if (isSimilarTo(data, needle)) if (isSimilarTo(data, needle))
@@ -144,7 +144,7 @@ BreakpointId BreakHandler::findBreakpointByNumber(int bpNumber) const
{ {
ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd(); ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
for ( ; it != et; ++it) for ( ; it != et; ++it)
if (it->response.bpNumber == bpNumber) if (it->response.number == bpNumber)
return it.key(); return it.key();
return BreakpointId(-1); return BreakpointId(-1);
} }
@@ -377,7 +377,7 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
case 0: case 0:
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
return QString::number(id); return QString::number(id);
//return QString("%1 - %2").arg(id).arg(response.bpNumber); //return QString("%1 - %2").arg(id).arg(response.number);
} }
if (role == Qt::DecorationRole) { if (role == Qt::DecorationRole) {
if (data.isWatchpoint()) if (data.isWatchpoint())
@@ -390,14 +390,14 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
case 1: case 1:
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
const QString str = it->isPending() const QString str = it->isPending()
? data.functionName() : response.bpFuncName; ? data.functionName() : response.functionName;
return str.isEmpty() ? empty : str; return str.isEmpty() ? empty : str;
} }
break; break;
case 2: case 2:
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
QString str = it->isPending() QString str = it->isPending()
? data.fileName() : response.bpFileName; ? data.fileName() : response.fileName;
str = QFileInfo(str).fileName(); str = QFileInfo(str).fileName();
// FIXME: better? // FIXME: better?
//if (data.bpMultiple && str.isEmpty() && !data.markerFileName.isEmpty()) //if (data.bpMultiple && str.isEmpty() && !data.markerFileName.isEmpty())
@@ -414,7 +414,7 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
//if (data.bpMultiple && str.isEmpty() && !data.markerFileName.isEmpty()) //if (data.bpMultiple && str.isEmpty() && !data.markerFileName.isEmpty())
// str = data.markerLineNumber; // str = data.markerLineNumber;
const int nr = it->isPending() const int nr = it->isPending()
? data.lineNumber() : response.bpLineNumber; ? data.lineNumber() : response.lineNumber;
return nr ? QString::number(nr) : empty; return nr ? QString::number(nr) : empty;
} }
if (role == Qt::UserRole + 1) if (role == Qt::UserRole + 1)
@@ -422,7 +422,7 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
break; break;
case 4: case 4:
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
return it->isPending() ? data.condition() : response.bpCondition; return it->isPending() ? data.condition() : response.condition;
if (role == Qt::ToolTipRole) if (role == Qt::ToolTipRole)
return tr("Breakpoint will only be hit if this condition is met."); return tr("Breakpoint will only be hit if this condition is met.");
if (role == Qt::UserRole + 1) if (role == Qt::UserRole + 1)
@@ -431,7 +431,7 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
case 5: case 5:
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
const int ignoreCount = const int ignoreCount =
it->isPending() ? data.ignoreCount() : response.bpIgnoreCount; it->isPending() ? data.ignoreCount() : response.ignoreCount;
return ignoreCount ? QVariant(ignoreCount) : QVariant(QString()); return ignoreCount ? QVariant(ignoreCount) : QVariant(QString());
} }
if (role == Qt::ToolTipRole) if (role == Qt::ToolTipRole)
@@ -444,7 +444,7 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
if (it->isPending()) if (it->isPending())
return !data.threadSpec().isEmpty() ? data.threadSpec() : tr("(all)"); return !data.threadSpec().isEmpty() ? data.threadSpec() : tr("(all)");
else else
return !response.bpThreadSpec.isEmpty() ? response.bpThreadSpec : tr("(all)"); return !response.threadSpec.isEmpty() ? response.threadSpec : tr("(all)");
} }
if (role == Qt::ToolTipRole) if (role == Qt::ToolTipRole)
return tr("Breakpoint will only be hit in the specified thread(s)."); return tr("Breakpoint will only be hit in the specified thread(s).");
@@ -455,13 +455,13 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
QString displayValue; QString displayValue;
const quint64 address = const quint64 address =
data.isWatchpoint() ? data.address() : response.bpAddress; data.isWatchpoint() ? data.address() : response.address;
if (address) if (address)
displayValue += QString::fromAscii("0x%1").arg(address, 0, 16); displayValue += QString::fromAscii("0x%1").arg(address, 0, 16);
if (!response.bpState.isEmpty()) { if (!response.state.isEmpty()) {
if (!displayValue.isEmpty()) if (!displayValue.isEmpty())
displayValue += QLatin1Char(' '); displayValue += QLatin1Char(' ');
displayValue += QString::fromAscii(response.bpState); displayValue += QString::fromAscii(response.state);
} }
return displayValue; return displayValue;
} }
@@ -516,7 +516,7 @@ PROPERTY(int, ignoreCount, setIgnoreCount)
bool BreakHandler::isEnabled(BreakpointId id) const bool BreakHandler::isEnabled(BreakpointId id) const
{ {
ConstIterator it = m_storage.find(id); ConstIterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return BreakpointDead); QTC_ASSERT(it != m_storage.end(), return false);
return it->data.isEnabled(); return it->data.isEnabled();
} }
@@ -576,7 +576,7 @@ void BreakHandler::ackCondition(BreakpointId id)
{ {
Iterator it = m_storage.find(id); Iterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return); QTC_ASSERT(it != m_storage.end(), return);
it->response.bpCondition = it->data.condition(); it->response.condition = it->data.condition();
updateMarker(id); updateMarker(id);
} }
@@ -584,7 +584,7 @@ void BreakHandler::ackIgnoreCount(BreakpointId id)
{ {
Iterator it = m_storage.find(id); Iterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return); QTC_ASSERT(it != m_storage.end(), return);
it->response.bpIgnoreCount = it->data.ignoreCount(); it->response.ignoreCount = it->data.ignoreCount();
updateMarker(id); updateMarker(id);
} }
@@ -592,7 +592,7 @@ void BreakHandler::ackEnabled(BreakpointId id)
{ {
Iterator it = m_storage.find(id); Iterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return); QTC_ASSERT(it != m_storage.end(), return);
it->response.bpEnabled = it->data.isEnabled(); it->response.enabled = it->data.isEnabled();
updateMarker(id); updateMarker(id);
} }
@@ -751,7 +751,7 @@ void BreakHandler::updateLineNumberFromMarker(BreakpointId id, int lineNumber)
// running, as this can be triggered by moving the breakpoint to // running, as this can be triggered by moving the breakpoint to
// the next line that generated code. // the next line that generated code.
// FIXME: Do we need yet another data member? // FIXME: Do we need yet another data member?
if (it->response.bpNumber == 0) { if (it->response.number == 0) {
it->data.setLineNumber(lineNumber); it->data.setLineNumber(lineNumber);
updateMarker(id); updateMarker(id);
} }
@@ -925,36 +925,36 @@ QString BreakHandler::BreakpointItem::toToolTip() const
<< "<tr><td>" << tr("Marker Line:") << "<tr><td>" << tr("Marker Line:")
<< "</td><td>" << data.m_markerLineNumber << "</td></tr>" << "</td><td>" << data.m_markerLineNumber << "</td></tr>"
<< "<tr><td>" << tr("Breakpoint Number:") << "<tr><td>" << tr("Breakpoint Number:")
<< "</td><td>" << response.bpNumber << "</td></tr>" << "</td><td>" << response.number << "</td></tr>"
<< "<tr><td>" << tr("Breakpoint Type:") << "<tr><td>" << tr("Breakpoint Type:")
<< "</td><td>" << t << "</td></tr>" << "</td><td>" << t << "</td></tr>"
<< "<tr><td>" << tr("State:") << "<tr><td>" << tr("State:")
<< "</td><td>" << response.bpState << "</td></tr>" << "</td><td>" << response.state << "</td></tr>"
<< "</table><br><hr><table>" << "</table><br><hr><table>"
<< "<tr><th>" << tr("Property") << "<tr><th>" << tr("Property")
<< "</th><th>" << tr("Requested") << "</th><th>" << tr("Requested")
<< "</th><th>" << tr("Obtained") << "</th></tr>" << "</th><th>" << tr("Obtained") << "</th></tr>"
<< "<tr><td>" << tr("Internal Number:") << "<tr><td>" << tr("Internal Number:")
<< "</td><td>&mdash;</td><td>" << response.bpNumber << "</td></tr>" << "</td><td>&mdash;</td><td>" << response.number << "</td></tr>"
<< "<tr><td>" << tr("File Name:") << "<tr><td>" << tr("File Name:")
<< "</td><td>" << QDir::toNativeSeparators(data.m_fileName) << "</td><td>" << QDir::toNativeSeparators(data.fileName())
<< "</td><td>" << QDir::toNativeSeparators(response.bpFileName) << "</td><td>" << QDir::toNativeSeparators(response.fileName)
<< "</td></tr>" << "</td></tr>"
<< "<tr><td>" << tr("Function Name:") << "<tr><td>" << tr("Function Name:")
<< "</td><td>" << data.m_functionName << "</td><td>" << data.functionName()
<< "</td><td>" << response.bpFuncName << "</td></tr>" << "</td><td>" << response.functionName << "</td></tr>"
<< "<tr><td>" << tr("Line Number:") << "</td><td>"; << "<tr><td>" << tr("Line Number:") << "</td><td>";
if (data.m_lineNumber) if (data.lineNumber())
str << data.m_lineNumber; str << data.lineNumber();
str << "</td><td>"; str << "</td><td>";
if (response.bpLineNumber) if (response.lineNumber)
str << response.bpLineNumber; str << response.lineNumber;
str << "</td></tr>" str << "</td></tr>"
<< "<tr><td>" << tr("Breakpoint Address:") << "<tr><td>" << tr("Breakpoint Address:")
<< "</td><td>"; << "</td><td>";
formatAddress(str, data.m_address); formatAddress(str, data.address());
str << "</td><td>"; str << "</td><td>";
formatAddress(str, response.bpAddress); formatAddress(str, response.address);
//str << "</td></tr>" //str << "</td></tr>"
// << "<tr><td>" << tr("Corrected Line Number:") // << "<tr><td>" << tr("Corrected Line Number:")
// << "</td><td>-</td><td>"; // << "</td><td>-</td><td>";
@@ -964,18 +964,18 @@ QString BreakHandler::BreakpointItem::toToolTip() const
// str << '-'; // str << '-';
str << "</td></tr>" str << "</td></tr>"
<< "<tr><td>" << tr("Condition:") << "<tr><td>" << tr("Condition:")
<< "</td><td>" << data.m_condition << "</td><td>" << data.condition()
<< "</td><td>" << response.bpCondition << "</td></tr>" << "</td><td>" << response.condition << "</td></tr>"
<< "<tr><td>" << tr("Ignore Count:") << "</td><td>"; << "<tr><td>" << tr("Ignore Count:") << "</td><td>";
if (data.m_ignoreCount) if (data.ignoreCount())
str << data.m_ignoreCount; str << data.ignoreCount();
str << "</td><td>"; str << "</td><td>";
if (response.bpIgnoreCount) if (response.ignoreCount)
str << response.bpIgnoreCount; str << response.ignoreCount;
str << "</td></tr>" str << "</td></tr>"
<< "<tr><td>" << tr("Thread Specification:") << "<tr><td>" << tr("Thread Specification:")
<< "</td><td>" << data.m_threadSpec << "</td><td>" << data.threadSpec()
<< "</td><td>" << response.bpThreadSpec << "</td></tr>" << "</td><td>" << response.threadSpec << "</td></tr>"
<< "</table></body></html>"; << "</table></body></html>";
return rc; return rc;
} }

View File

@@ -44,32 +44,36 @@ namespace Internal {
const char *BreakpointData::throwFunction = "throw"; const char *BreakpointData::throwFunction = "throw";
const char *BreakpointData::catchFunction = "catch"; const char *BreakpointData::catchFunction = "catch";
BreakpointData::BreakpointData(BreakpointType type) BreakpointParameters::BreakpointParameters(BreakpointType t) :
type(t), enabled(type), useFullPath(false),
ignoreCount(0), lineNumber(0)
{ {
m_type = type;
m_enabled = true;
m_ignoreCount = 0;
m_lineNumber = 0;
m_address = 0;
m_useFullPath = false;
m_markerLineNumber = 0;
} }
BreakpointResponse::BreakpointResponse() bool BreakpointParameters::equals(const BreakpointParameters &rhs) const
{
return type != rhs.type && enabled == rhs.enabled
&& useFullPath == rhs.useFullPath
&& fileName == rhs.fileName && condition == rhs.condition
&& ignoreCount == rhs.ignoreCount && lineNumber == rhs.lineNumber
&& address == rhs.address && threadSpec == rhs.threadSpec
&& functionName == rhs.functionName;
}
BreakpointData::BreakpointData(BreakpointType type) :
m_parameters(type), m_markerLineNumber(0)
{
}
BreakpointResponse::BreakpointResponse() :
number(0), multiple(false)
{ {
bpNumber = 0;
bpIgnoreCount = 0;
bpLineNumber = 0;
//bpCorrectedLineNumber = 0;
bpAddress = 0;
bpMultiple = false;
bpEnabled = true;
} }
#define SETIT(var, value) return (var != value) && (var = value, true) #define SETIT(var, value) return (var != value) && (var = value, true)
bool BreakpointData::setUseFullPath(bool on) bool BreakpointData::setUseFullPath(bool on)
{ SETIT(m_useFullPath, on); } { SETIT(m_parameters.useFullPath, on); }
bool BreakpointData::setMarkerFileName(const QString &file) bool BreakpointData::setMarkerFileName(const QString &file)
{ SETIT(m_markerFileName, file); } { SETIT(m_markerFileName, file); }
@@ -78,31 +82,31 @@ bool BreakpointData::setMarkerLineNumber(int line)
{ SETIT(m_markerLineNumber, line); } { SETIT(m_markerLineNumber, line); }
bool BreakpointData::setFileName(const QString &file) bool BreakpointData::setFileName(const QString &file)
{ SETIT(m_fileName, file); } { SETIT(m_parameters.fileName, file); }
bool BreakpointData::setEnabled(bool on) bool BreakpointData::setEnabled(bool on)
{ SETIT(m_enabled, on); } { SETIT(m_parameters.enabled, on); }
bool BreakpointData::setIgnoreCount(int count) bool BreakpointData::setIgnoreCount(int count)
{ SETIT(m_ignoreCount, count); } { SETIT(m_parameters.ignoreCount, count); }
bool BreakpointData::setFunctionName(const QString &name) bool BreakpointData::setFunctionName(const QString &name)
{ SETIT(m_functionName, name); } { SETIT(m_parameters.functionName, name); }
bool BreakpointData::setLineNumber(int line) bool BreakpointData::setLineNumber(int line)
{ SETIT(m_lineNumber, line); } { SETIT(m_parameters.lineNumber, line); }
bool BreakpointData::setAddress(quint64 address) bool BreakpointData::setAddress(quint64 address)
{ SETIT(m_address, address); } { SETIT(m_parameters.address, address); }
bool BreakpointData::setThreadSpec(const QByteArray &spec) bool BreakpointData::setThreadSpec(const QByteArray &spec)
{ SETIT(m_threadSpec, spec); } { SETIT(m_parameters.threadSpec, spec); }
bool BreakpointData::setType(BreakpointType type) bool BreakpointData::setType(BreakpointType type)
{ SETIT(m_type, type); } { SETIT(m_parameters.type, type); }
bool BreakpointData::setCondition(const QByteArray &cond) bool BreakpointData::setCondition(const QByteArray &cond)
{ SETIT(m_condition, cond); } { SETIT(m_parameters.condition, cond); }
#undef SETIT #undef SETIT
@@ -120,14 +124,14 @@ static inline bool fileNameMatch(const QString &f1, const QString &f2)
bool BreakpointData::isLocatedAt(const QString &fileName, int lineNumber, bool BreakpointData::isLocatedAt(const QString &fileName, int lineNumber,
bool useMarkerPosition) const bool useMarkerPosition) const
{ {
int line = useMarkerPosition ? m_markerLineNumber : m_lineNumber; int line = useMarkerPosition ? m_markerLineNumber : m_parameters.lineNumber;
return lineNumber == line && fileNameMatch(fileName, m_markerFileName); return lineNumber == line && fileNameMatch(fileName, m_markerFileName);
} }
bool BreakpointData::conditionsMatch(const QByteArray &other) const bool BreakpointData::conditionsMatch(const QByteArray &other) const
{ {
// Some versions of gdb "beautify" the passed condition. // Some versions of gdb "beautify" the passed condition.
QByteArray s1 = m_condition; QByteArray s1 = m_parameters.condition;
s1.replace(' ', ""); s1.replace(' ', "");
QByteArray s2 = other; QByteArray s2 = other;
s2.replace(' ', ""); s2.replace(' ', "");
@@ -152,15 +156,15 @@ QString BreakpointResponse::toString() const
{ {
QString result; QString result;
QTextStream ts(&result); QTextStream ts(&result);
ts << bpNumber; ts << number;
ts << bpCondition; ts << condition;
ts << bpIgnoreCount; ts << ignoreCount;
ts << bpFileName; ts << fileName;
ts << bpFullName; ts << fullName;
ts << bpLineNumber; ts << lineNumber;
ts << bpThreadSpec; ts << threadSpec;
ts << bpFuncName; ts << functionName;
ts << bpAddress; ts << address;
return result; return result;
} }

View File

@@ -81,6 +81,28 @@ enum BreakpointState
BreakpointDead, BreakpointDead,
}; };
class BreakpointParameters {
public:
explicit BreakpointParameters(BreakpointType = UnknownType);
bool equals(const BreakpointParameters &rhs) const;
BreakpointType type; // Type of breakpoint.
bool enabled; // Should we talk to the debugger engine?
bool useFullPath; // Should we use the full path when setting the bp?
QString fileName; // Short name of source file.
QByteArray condition; // Condition associated with breakpoint.
int ignoreCount; // Ignore count associated with breakpoint.
int lineNumber; // Line in source file.
quint64 address; // Address for watchpoints.
QByteArray threadSpec; // Thread specification.
QString functionName;
};
inline bool operator==(const BreakpointParameters &p1, const BreakpointParameters &p2)
{ return p1.equals(p2); }
inline bool operator!=(const BreakpointParameters &p1, const BreakpointParameters &p2)
{ return !p1.equals(p2); }
class BreakpointData class BreakpointData
{ {
private: private:
@@ -92,26 +114,27 @@ private:
public: public:
explicit BreakpointData(BreakpointType = UnknownType); explicit BreakpointData(BreakpointType = UnknownType);
BreakpointType type() const { return m_type; } BreakpointType type() const { return m_parameters.type; }
quint64 address() const { return m_address; } quint64 address() const { return m_parameters.address; }
bool useFullPath() const { return m_useFullPath; } bool useFullPath() const { return m_parameters.useFullPath; }
QString toString() const; QString toString() const;
bool isLocatedAt(const QString &fileName, int lineNumber, bool isLocatedAt(const QString &fileName, int lineNumber,
bool useMarkerPosition) const; bool useMarkerPosition) const;
bool conditionsMatch(const QByteArray &other) const; bool conditionsMatch(const QByteArray &other) const;
QString functionName() const { return m_functionName; } QString functionName() const { return m_parameters.functionName; }
QString markerFileName() const { return m_markerFileName; } QString markerFileName() const { return m_markerFileName; }
QString fileName() const { return m_fileName; } QString fileName() const { return m_parameters.fileName; }
int markerLineNumber() const { return m_markerLineNumber; } int markerLineNumber() const { return m_markerLineNumber; }
int lineNumber() const { return m_lineNumber; } int lineNumber() const { return m_parameters.lineNumber; }
int ignoreCount() const { return m_ignoreCount; } int ignoreCount() const { return m_parameters.ignoreCount; }
bool isEnabled() const { return m_enabled; } bool isEnabled() const { return m_parameters.enabled; }
QByteArray threadSpec() const { return m_threadSpec; } QByteArray threadSpec() const { return m_parameters.threadSpec; }
QByteArray condition() const { return m_condition; } QByteArray condition() const { return m_parameters.condition; }
const BreakpointParameters &parameters() const { return m_parameters; }
bool isWatchpoint() const { return m_type == Watchpoint; } bool isWatchpoint() const { return type() == Watchpoint; }
bool isBreakpoint() const { return m_type != Watchpoint; } // Enough for now. bool isBreakpoint() const { return type() != Watchpoint; } // Enough for now.
// Generic name for function to break on 'throw' // Generic name for function to break on 'throw'
static const char *throwFunction; static const char *throwFunction;
static const char *catchFunction; static const char *catchFunction;
@@ -133,18 +156,7 @@ private:
private: private:
// This "user requested information" will get stored in the session. // This "user requested information" will get stored in the session.
BreakpointType m_type; // Type of breakpoint. BreakpointParameters m_parameters;
bool m_enabled; // Should we talk to the debugger engine?
bool m_useFullPath; // Should we use the full path when setting the bp?
QString m_fileName; // Short name of source file.
QByteArray m_condition; // Condition associated with breakpoint.
int m_ignoreCount; // Ignore count associated with breakpoint.
int m_lineNumber; // Line in source file.
quint64 m_address; // Address for watchpoints.
QByteArray m_threadSpec; // Thread specification.
// Name of containing function, special values:
// BreakpointData::throwFunction, BreakpointData::catchFunction
QString m_functionName;
QString m_markerFileName; // Used to locate the marker. QString m_markerFileName; // Used to locate the marker.
int m_markerLineNumber; int m_markerLineNumber;
@@ -154,27 +166,17 @@ public:
// This is what debuggers produced in response to the attempt to // This is what debuggers produced in response to the attempt to
// insert a breakpoint. The data might differ from the requested bits. // insert a breakpoint. The data might differ from the requested bits.
class BreakpointResponse class BreakpointResponse : public BreakpointParameters
{ {
public: public:
BreakpointResponse(); BreakpointResponse();
QString toString() const; QString toString() const;
public: public:
int bpNumber; // Breakpoint number assigned by the debugger engine. int number; // Breakpoint number assigned by the debugger engine.
BreakpointType bpType; // Breakpoint type used by debugger engine. QString fullName; // Full file name acknowledged by the debugger engine.
QByteArray bpCondition; // Condition acknowledged by the debugger engine. bool multiple; // Happens in constructors/gdb.
int bpIgnoreCount; // Ignore count acknowledged by the debugger engine. QByteArray state; // gdb: <PENDING>, <MULTIPLE>
QString bpFileName; // File name acknowledged by the debugger engine.
QString bpFullName; // Full file name acknowledged by the debugger engine.
int bpLineNumber; // Line number acknowledged by the debugger engine.
//int bpCorrectedLineNumber; // Acknowledged by the debugger engine.
QByteArray bpThreadSpec; // Thread spec acknowledged by the debugger engine.
QString bpFuncName; // Function name acknowledged by the debugger engine.
quint64 bpAddress; // Address acknowledged by the debugger engine.
bool bpMultiple; // Happens in constructors/gdb.
bool bpEnabled; // Enable/disable command sent.
QByteArray bpState; // gdb: <PENDING>, <MULTIPLE>
}; };
typedef QList<BreakpointId> BreakpointIds; typedef QList<BreakpointId> BreakpointIds;

View File

@@ -71,16 +71,16 @@ static inline QString msgCannotSetBreakAtFunction(const QString &func, const QSt
void setBreakpointResponse(const BreakpointData *nbd, int number, BreakpointResponse *response) void setBreakpointResponse(const BreakpointData *nbd, int number, BreakpointResponse *response)
{ {
response->bpAddress = nbd->address(); response->address = nbd->address();
response->bpNumber = number; response->number = number;
response->bpFuncName = nbd->functionName(); response->functionName = nbd->functionName();
response->bpType = nbd->type(); response->type = nbd->type();
response->bpCondition = nbd->condition(); response->condition = nbd->condition();
response->bpIgnoreCount = nbd->ignoreCount(); response->ignoreCount = nbd->ignoreCount();
response->bpFullName = response->bpFileName = nbd->fileName(); response->fullName = response->fileName = nbd->fileName();
response->bpLineNumber = nbd->lineNumber(); response->lineNumber = nbd->lineNumber();
response->bpThreadSpec = nbd->threadSpec(); response->threadSpec = nbd->threadSpec();
response->bpEnabled = nbd->isEnabled(); response->enabled = nbd->isEnabled();
} }
bool addCdbBreakpoint(CIDebugControl* debugControl, bool addCdbBreakpoint(CIDebugControl* debugControl,
@@ -116,8 +116,8 @@ bool addCdbBreakpoint(CIDebugControl* debugControl,
if (debugBreakpoints) if (debugBreakpoints)
qDebug("Added %lu at 0x%lx %s", id, address, qPrintable(ncdbbp.toString())); qDebug("Added %lu at 0x%lx %s", id, address, qPrintable(ncdbbp.toString()));
setBreakpointResponse(nbd, id, response); setBreakpointResponse(nbd, id, response);
response->bpAddress = address; response->address = address;
response->bpFuncName = resolvedFunction; response->functionName = resolvedFunction;
return true; return true;
} }

View File

@@ -2293,8 +2293,8 @@ void DebuggerPluginPrivate::requestContextMenu(TextEditor::ITextEditor *editor,
QString line = editor->contents() QString line = editor->contents()
.section('\n', lineNumber - 1, lineNumber - 1); .section('\n', lineNumber - 1, lineNumber - 1);
BreakpointResponse needle; BreakpointResponse needle;
needle.bpAddress = DisassemblerViewAgent::addressFromDisassemblyLine(line); needle.address = DisassemblerViewAgent::addressFromDisassemblyLine(line);
needle.bpLineNumber = -1; needle.lineNumber = -1;
id = breakHandler()->findSimilarBreakpoint(needle); id = breakHandler()->findSimilarBreakpoint(needle);
} else { } else {
fileName = editor->file()->fileName(); fileName = editor->file()->fileName();

View File

@@ -136,31 +136,31 @@ QDataStream &operator>>(QDataStream &stream, StackFrames &frames)
QDataStream &operator<<(QDataStream &stream, const BreakpointResponse &s) QDataStream &operator<<(QDataStream &stream, const BreakpointResponse &s)
{ {
stream << s.bpNumber; stream << s.number;
stream << s.bpCondition; stream << s.condition;
stream << s.bpIgnoreCount; stream << s.ignoreCount;
stream << s.bpFileName; stream << s.fileName;
stream << s.bpFullName; stream << s.fullName;
stream << s.bpLineNumber; stream << s.lineNumber;
//stream << s.bpCorrectedLineNumber; //stream << s.bpCorrectedLineNumber;
stream << s.bpThreadSpec; stream << s.threadSpec;
stream << s.bpFuncName; stream << s.functionName;
stream << s.bpAddress; stream << s.address;
return stream; return stream;
} }
QDataStream &operator>>(QDataStream &stream, BreakpointResponse &s) QDataStream &operator>>(QDataStream &stream, BreakpointResponse &s)
{ {
stream >> s.bpNumber; stream >> s.number;
stream >> s.bpCondition; stream >> s.condition;
stream >> s.bpIgnoreCount; stream >> s.ignoreCount;
stream >> s.bpFileName; stream >> s.fileName;
stream >> s.bpFullName; stream >> s.fullName;
stream >> s.bpLineNumber; stream >> s.lineNumber;
//stream >> s.bpCorrectedLineNumber; //stream >> s.bpCorrectedLineNumber;
stream >> s.bpThreadSpec; stream >> s.threadSpec;
stream >> s.bpFuncName; stream >> s.functionName;
stream >> s.bpAddress; stream >> s.address;
return stream; return stream;
} }

View File

@@ -2059,24 +2059,24 @@ void GdbEngine::setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt)
BreakpointResponse response; BreakpointResponse response;
//data->pending = false; //data->pending = false;
response.bpMultiple = false; response.multiple = false;
response.bpEnabled = true; response.enabled = true;
response.bpCondition.clear(); response.condition.clear();
QByteArray file, fullName; QByteArray file, fullName;
foreach (const GdbMi &child, bkpt.children()) { foreach (const GdbMi &child, bkpt.children()) {
if (child.hasName("number")) { if (child.hasName("number")) {
response.bpNumber = child.data().toInt(); response.number = child.data().toInt();
} else if (child.hasName("func")) { } else if (child.hasName("func")) {
response.bpFuncName = _(child.data()); response.functionName = _(child.data());
} else if (child.hasName("addr")) { } else if (child.hasName("addr")) {
// <MULTIPLE> happens in constructors. In this case there are // <MULTIPLE> happens in constructors. In this case there are
// _two_ fields named "addr" in the response. On Linux that is... // _two_ fields named "addr" in the response. On Linux that is...
if (child.data().startsWith("0x")) { if (child.data().startsWith("0x")) {
response.bpAddress = child.data().mid(2).toULongLong(0, 16); response.address = child.data().mid(2).toULongLong(0, 16);
} else { } else {
response.bpState = child.data(); response.state = child.data();
if (child.data() == "<MULTIPLE>") if (child.data() == "<MULTIPLE>")
response.bpMultiple = true; response.multiple = true;
} }
} else if (child.hasName("file")) { } else if (child.hasName("file")) {
file = child.data(); file = child.data();
@@ -2085,17 +2085,17 @@ void GdbEngine::setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt)
} else if (child.hasName("line")) { } else if (child.hasName("line")) {
bool ok; bool ok;
const int lineNumber = child.data().toInt(&ok); const int lineNumber = child.data().toInt(&ok);
response.bpLineNumber = lineNumber; response.lineNumber = lineNumber;
//if (ok && response.bpCorrectedLineNumber <= 0) //if (ok && response.bpCorrectedLineNumber <= 0)
// data->setMarkerLineNumber(lineNumber); // data->setMarkerLineNumber(lineNumber);
} else if (child.hasName("cond")) { } else if (child.hasName("cond")) {
response.bpCondition = child.data(); response.condition = child.data();
// gdb 6.3 likes to "rewrite" conditions. Just accept that fact. // gdb 6.3 likes to "rewrite" conditions. Just accept that fact.
//if (response.bpCondition != data->condition() //if (response.bpCondition != data->condition()
// && data->conditionsMatch(response.bpCondition)) // && data->conditionsMatch(response.bpCondition))
// data->setCondition(response.bpCondition); // data->setCondition(response.bpCondition);
} else if (child.hasName("enabled")) { } else if (child.hasName("enabled")) {
response.bpEnabled = (child.data() == "y"); response.enabled = (child.data() == "y");
} else if (child.hasName("pending")) { } else if (child.hasName("pending")) {
//data->setState(BreakpointPending); //data->setState(BreakpointPending);
breakHandler()->setState(id, BreakpointPending); breakHandler()->setState(id, BreakpointPending);
@@ -2106,9 +2106,9 @@ void GdbEngine::setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt)
QByteArray ba = child.data(); QByteArray ba = child.data();
if (ba.startsWith('<') && ba.endsWith('>')) if (ba.startsWith('<') && ba.endsWith('>'))
ba = ba.mid(1, ba.size() - 2); ba = ba.mid(1, ba.size() - 2);
response.bpFuncName = _(ba); response.functionName = _(ba);
} else if (child.hasName("thread")) { } else if (child.hasName("thread")) {
response.bpThreadSpec = child.data(); response.threadSpec = child.data();
} else if (child.hasName("type")) { } else if (child.hasName("type")) {
// FIXME: This should not change the type. // FIXME: This should not change the type.
//if (child.data().contains("reakpoint")) // "breakpoint", "hw breakpoint" //if (child.data().contains("reakpoint")) // "breakpoint", "hw breakpoint"
@@ -2125,7 +2125,7 @@ void GdbEngine::setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt)
QString name; QString name;
if (!fullName.isEmpty()) { if (!fullName.isEmpty()) {
name = cleanupFullName(QFile::decodeName(fullName)); name = cleanupFullName(QFile::decodeName(fullName));
response.bpFileName = name; response.fileName = name;
//if (data->markerFileName().isEmpty()) //if (data->markerFileName().isEmpty())
// data->setMarkerFileName(name); // data->setMarkerFileName(name);
} else { } else {
@@ -2134,7 +2134,7 @@ void GdbEngine::setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt)
// gdb's own. No point in assigning markerFileName for now. // gdb's own. No point in assigning markerFileName for now.
} }
if (!name.isEmpty()) if (!name.isEmpty())
response.bpFileName = name; response.fileName = name;
breakHandler()->setResponse(id, response); breakHandler()->setResponse(id, response);
} }
@@ -2190,7 +2190,7 @@ void GdbEngine::handleWatchInsert(const GdbResponse &response)
if (ba.startsWith("Hardware watchpoint ")) { if (ba.startsWith("Hardware watchpoint ")) {
const int pos = ba.indexOf(':', 20); const int pos = ba.indexOf(':', 20);
BreakpointResponse response = breakHandler()->response(id); BreakpointResponse response = breakHandler()->response(id);
response.bpNumber = ba.mid(20, pos - 20).toInt(); response.number = ba.mid(20, pos - 20).toInt();
breakHandler()->setResponse(id, response); breakHandler()->setResponse(id, response);
} else { } else {
showMessage(_("CANNOT PARSE WATCHPOINT FROM" + ba)); showMessage(_("CANNOT PARSE WATCHPOINT FROM" + ba));
@@ -2278,7 +2278,7 @@ void GdbEngine::handleBreakList(const GdbMi &table)
foreach (const GdbMi &bkpt, bkpts) { foreach (const GdbMi &bkpt, bkpts) {
BreakpointResponse needle; BreakpointResponse needle;
needle.bpFileName = _("xx"); needle.fileName = _("xx");
BreakpointId id = breakHandler()->findSimilarBreakpoint(needle); BreakpointId id = breakHandler()->findSimilarBreakpoint(needle);
//qDebug() << "\n\nGOT: " << bkpt.toString() << '\n' << temp.toString(); //qDebug() << "\n\nGOT: " << bkpt.toString() << '\n' << temp.toString();
// FIXME: use setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt) // FIXME: use setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt)
@@ -2374,14 +2374,14 @@ void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointId id)
re.setMinimal(true); re.setMinimal(true);
BreakpointResponse response; BreakpointResponse response;
response.bpFileName = _("<MULTIPLE>"); response.fileName = _("<MULTIPLE>");
QString requestedFileName = breakHandler()->fileName(id); QString requestedFileName = breakHandler()->fileName(id);
if (re.indexIn(output) != -1) { if (re.indexIn(output) != -1) {
response.bpAddress = re.cap(1).toULongLong(0, 16); response.address = re.cap(1).toULongLong(0, 16);
response.bpFuncName = re.cap(2).trimmed(); response.functionName = re.cap(2).trimmed();
response.bpLineNumber = re.cap(4).toInt(); response.lineNumber = re.cap(4).toInt();
QString full = fullName(re.cap(3)); QString full = fullName(re.cap(3));
if (full.isEmpty()) { if (full.isEmpty()) {
// FIXME: This happens without UsePreciseBreakpoints regularly. // FIXME: This happens without UsePreciseBreakpoints regularly.
@@ -2405,10 +2405,10 @@ void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointId id)
// qDebug() << "111"; // qDebug() << "111";
// data->setMarkerFileName(full); // data->setMarkerFileName(full);
//} //}
response.bpFileName = full; response.fileName = full;
} else { } else {
qDebug() << "COULD NOT MATCH " << re.pattern() << " AND " << output; qDebug() << "COULD NOT MATCH " << re.pattern() << " AND " << output;
response.bpNumber = -1; // <unavailable> response.number = -1; // <unavailable>
} }
breakHandler()->setResponse(id, response); breakHandler()->setResponse(id, response);
} }
@@ -2437,7 +2437,7 @@ void GdbEngine::handleInfoLine(const GdbResponse &response)
const int line = ba.mid(5, pos - 5).toInt(); const int line = ba.mid(5, pos - 5).toInt();
const BreakpointId id = response.cookie.toInt(); const BreakpointId id = response.cookie.toInt();
BreakpointResponse br = breakHandler()->response(id); BreakpointResponse br = breakHandler()->response(id);
br.bpLineNumber = line; br.lineNumber = line;
breakHandler()->setResponse(id, br); breakHandler()->setResponse(id, br);
} }
} }
@@ -2619,28 +2619,28 @@ void GdbEngine::changeBreakpoint(BreakpointId id)
QTC_ASSERT(data0, return); QTC_ASSERT(data0, return);
const BreakpointData &data = *data0; const BreakpointData &data = *data0;
const BreakpointResponse &response = breakHandler()->response(id); const BreakpointResponse &response = breakHandler()->response(id);
QTC_ASSERT(response.bpNumber > 0, return); QTC_ASSERT(response.number > 0, return);
const QByteArray bpnr = QByteArray::number(response.bpNumber); const QByteArray bpnr = QByteArray::number(response.number);
if (data.condition() != response.bpCondition if (data.condition() != response.condition
&& !data.conditionsMatch(response.bpCondition)) { && !data.conditionsMatch(response.condition)) {
// Update conditions if needed. // Update conditions if needed.
postCommand("condition " + bpnr + ' ' + data.condition(), postCommand("condition " + bpnr + ' ' + data.condition(),
NeedsStop | RebuildBreakpointModel, NeedsStop | RebuildBreakpointModel,
CB(handleBreakCondition), id); CB(handleBreakCondition), id);
} }
if (data.ignoreCount() != response.bpIgnoreCount) { if (data.ignoreCount() != response.ignoreCount) {
// Update ignorecount if needed. // Update ignorecount if needed.
postCommand("ignore " + bpnr + ' ' + QByteArray::number(data.ignoreCount()), postCommand("ignore " + bpnr + ' ' + QByteArray::number(data.ignoreCount()),
NeedsStop | RebuildBreakpointModel, NeedsStop | RebuildBreakpointModel,
CB(handleBreakIgnore), id); CB(handleBreakIgnore), id);
} }
if (!data.isEnabled() && response.bpEnabled) { if (!data.isEnabled() && response.enabled) {
postCommand("-break-disable " + bpnr, postCommand("-break-disable " + bpnr,
NeedsStop | RebuildBreakpointModel, NeedsStop | RebuildBreakpointModel,
CB(handleBreakDisable), id); CB(handleBreakDisable), id);
} }
if (data.isEnabled() && !response.bpEnabled) { if (data.isEnabled() && !response.enabled) {
postCommand("-break-enable " + bpnr, postCommand("-break-enable " + bpnr,
NeedsStop | RebuildBreakpointModel, NeedsStop | RebuildBreakpointModel,
CB(handleBreakEnable), id); CB(handleBreakEnable), id);
@@ -2678,9 +2678,9 @@ void GdbEngine::removeBreakpoint(BreakpointId id)
QTC_ASSERT(handler->state(id) == BreakpointRemoveRequested, /**/); QTC_ASSERT(handler->state(id) == BreakpointRemoveRequested, /**/);
handler->setState(id, BreakpointRemoveProceeding); handler->setState(id, BreakpointRemoveProceeding);
BreakpointResponse br = handler->response(id); BreakpointResponse br = handler->response(id);
showMessage(_("DELETING BP %1 IN ").arg(br.bpNumber) showMessage(_("DELETING BP %1 IN ").arg(br.number)
+ handler->markerFileName(id)); + handler->markerFileName(id));
postCommand("-break-delete " + QByteArray::number(br.bpNumber), postCommand("-break-delete " + QByteArray::number(br.number),
NeedsStop | RebuildBreakpointModel); NeedsStop | RebuildBreakpointModel);
// Pretend it succeeds without waiting for response. Feels better. // Pretend it succeeds without waiting for response. Feels better.
handler->notifyBreakpointRemoveOk(id); handler->notifyBreakpointRemoveOk(id);

View File

@@ -379,9 +379,9 @@ void PdbEngine::handleBreakInsert(const PdbResponse &response)
QByteArray file = response.data.mid(pos1 + 4, pos2 - pos1 - 4); QByteArray file = response.data.mid(pos1 + 4, pos2 - pos1 - 4);
QByteArray line = response.data.mid(pos2 + 1); QByteArray line = response.data.mid(pos2 + 1);
BreakpointResponse br; BreakpointResponse br;
br.bpNumber = bpnr.toInt(); br.number = bpnr.toInt();
br.bpFileName = _(file); br.fileName = _(file);
br.bpLineNumber = line.toInt(); br.lineNumber = line.toInt();
handler->setResponse(id, br); handler->setResponse(id, br);
} }

View File

@@ -740,9 +740,9 @@ void QmlEngine::messageReceived(const QByteArray &message)
if (processedFilename == file && handler->lineNumber(id) == line) { if (processedFilename == file && handler->lineNumber(id) == line) {
handler->setState(id, BreakpointInserted); handler->setState(id, BreakpointInserted);
BreakpointResponse br = handler->response(id); BreakpointResponse br = handler->response(id);
br.bpFileName = file; br.fileName = file;
br.bpLineNumber = line; br.lineNumber = line;
br.bpFuncName = function; br.functionName = function;
handler->setResponse(id, br); handler->setResponse(id, br);
} }
} }

View File

@@ -627,9 +627,9 @@ bool ScriptEngine::checkForBreakCondition(bool byFunction)
BreakpointResponse br; BreakpointResponse br;
// We just run into a breakpoint. // We just run into a breakpoint.
//SDEBUG("RESOLVING BREAKPOINT AT " << fileName << lineNumber); //SDEBUG("RESOLVING BREAKPOINT AT " << fileName << lineNumber);
br.bpLineNumber = lineNumber; br.lineNumber = lineNumber;
br.bpFileName = fileName; br.fileName = fileName;
br.bpFuncName = functionName; br.functionName = functionName;
handler->setState(id, BreakpointInserted); handler->setState(id, BreakpointInserted);
handler->setResponse(id, br); handler->setResponse(id, br);
} }