forked from qt-creator/qt-creator
Debugger: Introduce BreakpointParameters as base struct.
For Breakpoint data manipulation. Reviewed-by: hjk
This commit is contained in:
@@ -97,26 +97,26 @@ static bool isSimilarTo(const BreakpointData &data, const BreakpointResponse &ne
|
||||
{
|
||||
// Clear hit.
|
||||
// Clear miss.
|
||||
if (needle.bpType != UnknownType && data.type() != UnknownType
|
||||
&& data.type() != needle.bpType)
|
||||
if (needle.type != UnknownType && data.type() != UnknownType
|
||||
&& data.type() != needle.type)
|
||||
return false;
|
||||
|
||||
// Clear hit.
|
||||
if (data.address() && data.address() == needle.bpAddress)
|
||||
if (data.address() && data.address() == needle.address)
|
||||
return true;
|
||||
|
||||
// At least at a position we were looking for.
|
||||
// FIXME: breaks multiple breakpoints at the same location
|
||||
if (!data.fileName().isEmpty()
|
||||
&& fileNameMatch(data.fileName(), needle.bpFileName)
|
||||
&& data.lineNumber() == needle.bpLineNumber)
|
||||
&& fileNameMatch(data.fileName(), needle.fileName)
|
||||
&& data.lineNumber() == needle.lineNumber)
|
||||
return true;
|
||||
|
||||
// At least at a position we were looking for.
|
||||
// FIXME: breaks multiple breakpoints at the same location
|
||||
if (!data.fileName().isEmpty()
|
||||
&& fileNameMatch(data.fileName(), needle.bpFileName)
|
||||
&& data.lineNumber() == needle.bpLineNumber)
|
||||
&& fileNameMatch(data.fileName(), needle.fileName)
|
||||
&& data.lineNumber() == needle.lineNumber)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -131,7 +131,7 @@ BreakpointId BreakHandler::findSimilarBreakpoint(const BreakpointResponse &needl
|
||||
const BreakpointData &data = it->data;
|
||||
const BreakpointResponse &response = it->response;
|
||||
qDebug() << "COMPARING " << data.toString() << " WITH " << needle.toString();
|
||||
if (response.bpNumber && response.bpNumber == needle.bpNumber)
|
||||
if (response.number && response.number == needle.number)
|
||||
return id;
|
||||
|
||||
if (isSimilarTo(data, needle))
|
||||
@@ -144,7 +144,7 @@ BreakpointId BreakHandler::findBreakpointByNumber(int bpNumber) const
|
||||
{
|
||||
ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
|
||||
for ( ; it != et; ++it)
|
||||
if (it->response.bpNumber == bpNumber)
|
||||
if (it->response.number == bpNumber)
|
||||
return it.key();
|
||||
return BreakpointId(-1);
|
||||
}
|
||||
@@ -377,7 +377,7 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
|
||||
case 0:
|
||||
if (role == Qt::DisplayRole) {
|
||||
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 (data.isWatchpoint())
|
||||
@@ -390,14 +390,14 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
|
||||
case 1:
|
||||
if (role == Qt::DisplayRole) {
|
||||
const QString str = it->isPending()
|
||||
? data.functionName() : response.bpFuncName;
|
||||
? data.functionName() : response.functionName;
|
||||
return str.isEmpty() ? empty : str;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (role == Qt::DisplayRole) {
|
||||
QString str = it->isPending()
|
||||
? data.fileName() : response.bpFileName;
|
||||
? data.fileName() : response.fileName;
|
||||
str = QFileInfo(str).fileName();
|
||||
// FIXME: better?
|
||||
//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())
|
||||
// str = data.markerLineNumber;
|
||||
const int nr = it->isPending()
|
||||
? data.lineNumber() : response.bpLineNumber;
|
||||
? data.lineNumber() : response.lineNumber;
|
||||
return nr ? QString::number(nr) : empty;
|
||||
}
|
||||
if (role == Qt::UserRole + 1)
|
||||
@@ -422,7 +422,7 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
|
||||
break;
|
||||
case 4:
|
||||
if (role == Qt::DisplayRole)
|
||||
return it->isPending() ? data.condition() : response.bpCondition;
|
||||
return it->isPending() ? data.condition() : response.condition;
|
||||
if (role == Qt::ToolTipRole)
|
||||
return tr("Breakpoint will only be hit if this condition is met.");
|
||||
if (role == Qt::UserRole + 1)
|
||||
@@ -431,7 +431,7 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
|
||||
case 5:
|
||||
if (role == Qt::DisplayRole) {
|
||||
const int ignoreCount =
|
||||
it->isPending() ? data.ignoreCount() : response.bpIgnoreCount;
|
||||
it->isPending() ? data.ignoreCount() : response.ignoreCount;
|
||||
return ignoreCount ? QVariant(ignoreCount) : QVariant(QString());
|
||||
}
|
||||
if (role == Qt::ToolTipRole)
|
||||
@@ -444,7 +444,7 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
|
||||
if (it->isPending())
|
||||
return !data.threadSpec().isEmpty() ? data.threadSpec() : tr("(all)");
|
||||
else
|
||||
return !response.bpThreadSpec.isEmpty() ? response.bpThreadSpec : tr("(all)");
|
||||
return !response.threadSpec.isEmpty() ? response.threadSpec : tr("(all)");
|
||||
}
|
||||
if (role == Qt::ToolTipRole)
|
||||
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) {
|
||||
QString displayValue;
|
||||
const quint64 address =
|
||||
data.isWatchpoint() ? data.address() : response.bpAddress;
|
||||
data.isWatchpoint() ? data.address() : response.address;
|
||||
if (address)
|
||||
displayValue += QString::fromAscii("0x%1").arg(address, 0, 16);
|
||||
if (!response.bpState.isEmpty()) {
|
||||
if (!response.state.isEmpty()) {
|
||||
if (!displayValue.isEmpty())
|
||||
displayValue += QLatin1Char(' ');
|
||||
displayValue += QString::fromAscii(response.bpState);
|
||||
displayValue += QString::fromAscii(response.state);
|
||||
}
|
||||
return displayValue;
|
||||
}
|
||||
@@ -516,7 +516,7 @@ PROPERTY(int, ignoreCount, setIgnoreCount)
|
||||
bool BreakHandler::isEnabled(BreakpointId id) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -576,7 +576,7 @@ void BreakHandler::ackCondition(BreakpointId id)
|
||||
{
|
||||
Iterator it = m_storage.find(id);
|
||||
QTC_ASSERT(it != m_storage.end(), return);
|
||||
it->response.bpCondition = it->data.condition();
|
||||
it->response.condition = it->data.condition();
|
||||
updateMarker(id);
|
||||
}
|
||||
|
||||
@@ -584,7 +584,7 @@ void BreakHandler::ackIgnoreCount(BreakpointId id)
|
||||
{
|
||||
Iterator it = m_storage.find(id);
|
||||
QTC_ASSERT(it != m_storage.end(), return);
|
||||
it->response.bpIgnoreCount = it->data.ignoreCount();
|
||||
it->response.ignoreCount = it->data.ignoreCount();
|
||||
updateMarker(id);
|
||||
}
|
||||
|
||||
@@ -592,7 +592,7 @@ void BreakHandler::ackEnabled(BreakpointId id)
|
||||
{
|
||||
Iterator it = m_storage.find(id);
|
||||
QTC_ASSERT(it != m_storage.end(), return);
|
||||
it->response.bpEnabled = it->data.isEnabled();
|
||||
it->response.enabled = it->data.isEnabled();
|
||||
updateMarker(id);
|
||||
}
|
||||
|
||||
@@ -751,7 +751,7 @@ void BreakHandler::updateLineNumberFromMarker(BreakpointId id, int lineNumber)
|
||||
// running, as this can be triggered by moving the breakpoint to
|
||||
// the next line that generated code.
|
||||
// FIXME: Do we need yet another data member?
|
||||
if (it->response.bpNumber == 0) {
|
||||
if (it->response.number == 0) {
|
||||
it->data.setLineNumber(lineNumber);
|
||||
updateMarker(id);
|
||||
}
|
||||
@@ -925,36 +925,36 @@ QString BreakHandler::BreakpointItem::toToolTip() const
|
||||
<< "<tr><td>" << tr("Marker Line:")
|
||||
<< "</td><td>" << data.m_markerLineNumber << "</td></tr>"
|
||||
<< "<tr><td>" << tr("Breakpoint Number:")
|
||||
<< "</td><td>" << response.bpNumber << "</td></tr>"
|
||||
<< "</td><td>" << response.number << "</td></tr>"
|
||||
<< "<tr><td>" << tr("Breakpoint Type:")
|
||||
<< "</td><td>" << t << "</td></tr>"
|
||||
<< "<tr><td>" << tr("State:")
|
||||
<< "</td><td>" << response.bpState << "</td></tr>"
|
||||
<< "</td><td>" << response.state << "</td></tr>"
|
||||
<< "</table><br><hr><table>"
|
||||
<< "<tr><th>" << tr("Property")
|
||||
<< "</th><th>" << tr("Requested")
|
||||
<< "</th><th>" << tr("Obtained") << "</th></tr>"
|
||||
<< "<tr><td>" << tr("Internal Number:")
|
||||
<< "</td><td>—</td><td>" << response.bpNumber << "</td></tr>"
|
||||
<< "</td><td>—</td><td>" << response.number << "</td></tr>"
|
||||
<< "<tr><td>" << tr("File Name:")
|
||||
<< "</td><td>" << QDir::toNativeSeparators(data.m_fileName)
|
||||
<< "</td><td>" << QDir::toNativeSeparators(response.bpFileName)
|
||||
<< "</td><td>" << QDir::toNativeSeparators(data.fileName())
|
||||
<< "</td><td>" << QDir::toNativeSeparators(response.fileName)
|
||||
<< "</td></tr>"
|
||||
<< "<tr><td>" << tr("Function Name:")
|
||||
<< "</td><td>" << data.m_functionName
|
||||
<< "</td><td>" << response.bpFuncName << "</td></tr>"
|
||||
<< "</td><td>" << data.functionName()
|
||||
<< "</td><td>" << response.functionName << "</td></tr>"
|
||||
<< "<tr><td>" << tr("Line Number:") << "</td><td>";
|
||||
if (data.m_lineNumber)
|
||||
str << data.m_lineNumber;
|
||||
if (data.lineNumber())
|
||||
str << data.lineNumber();
|
||||
str << "</td><td>";
|
||||
if (response.bpLineNumber)
|
||||
str << response.bpLineNumber;
|
||||
if (response.lineNumber)
|
||||
str << response.lineNumber;
|
||||
str << "</td></tr>"
|
||||
<< "<tr><td>" << tr("Breakpoint Address:")
|
||||
<< "</td><td>";
|
||||
formatAddress(str, data.m_address);
|
||||
formatAddress(str, data.address());
|
||||
str << "</td><td>";
|
||||
formatAddress(str, response.bpAddress);
|
||||
formatAddress(str, response.address);
|
||||
//str << "</td></tr>"
|
||||
// << "<tr><td>" << tr("Corrected Line Number:")
|
||||
// << "</td><td>-</td><td>";
|
||||
@@ -964,18 +964,18 @@ QString BreakHandler::BreakpointItem::toToolTip() const
|
||||
// str << '-';
|
||||
str << "</td></tr>"
|
||||
<< "<tr><td>" << tr("Condition:")
|
||||
<< "</td><td>" << data.m_condition
|
||||
<< "</td><td>" << response.bpCondition << "</td></tr>"
|
||||
<< "</td><td>" << data.condition()
|
||||
<< "</td><td>" << response.condition << "</td></tr>"
|
||||
<< "<tr><td>" << tr("Ignore Count:") << "</td><td>";
|
||||
if (data.m_ignoreCount)
|
||||
str << data.m_ignoreCount;
|
||||
if (data.ignoreCount())
|
||||
str << data.ignoreCount();
|
||||
str << "</td><td>";
|
||||
if (response.bpIgnoreCount)
|
||||
str << response.bpIgnoreCount;
|
||||
if (response.ignoreCount)
|
||||
str << response.ignoreCount;
|
||||
str << "</td></tr>"
|
||||
<< "<tr><td>" << tr("Thread Specification:")
|
||||
<< "</td><td>" << data.m_threadSpec
|
||||
<< "</td><td>" << response.bpThreadSpec << "</td></tr>"
|
||||
<< "</td><td>" << data.threadSpec()
|
||||
<< "</td><td>" << response.threadSpec << "</td></tr>"
|
||||
<< "</table></body></html>";
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -44,32 +44,36 @@ namespace Internal {
|
||||
const char *BreakpointData::throwFunction = "throw";
|
||||
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)
|
||||
|
||||
bool BreakpointData::setUseFullPath(bool on)
|
||||
{ SETIT(m_useFullPath, on); }
|
||||
{ SETIT(m_parameters.useFullPath, on); }
|
||||
|
||||
bool BreakpointData::setMarkerFileName(const QString &file)
|
||||
{ SETIT(m_markerFileName, file); }
|
||||
@@ -78,31 +82,31 @@ bool BreakpointData::setMarkerLineNumber(int line)
|
||||
{ SETIT(m_markerLineNumber, line); }
|
||||
|
||||
bool BreakpointData::setFileName(const QString &file)
|
||||
{ SETIT(m_fileName, file); }
|
||||
{ SETIT(m_parameters.fileName, file); }
|
||||
|
||||
bool BreakpointData::setEnabled(bool on)
|
||||
{ SETIT(m_enabled, on); }
|
||||
{ SETIT(m_parameters.enabled, on); }
|
||||
|
||||
bool BreakpointData::setIgnoreCount(int count)
|
||||
{ SETIT(m_ignoreCount, count); }
|
||||
{ SETIT(m_parameters.ignoreCount, count); }
|
||||
|
||||
bool BreakpointData::setFunctionName(const QString &name)
|
||||
{ SETIT(m_functionName, name); }
|
||||
{ SETIT(m_parameters.functionName, name); }
|
||||
|
||||
bool BreakpointData::setLineNumber(int line)
|
||||
{ SETIT(m_lineNumber, line); }
|
||||
{ SETIT(m_parameters.lineNumber, line); }
|
||||
|
||||
bool BreakpointData::setAddress(quint64 address)
|
||||
{ SETIT(m_address, address); }
|
||||
{ SETIT(m_parameters.address, address); }
|
||||
|
||||
bool BreakpointData::setThreadSpec(const QByteArray &spec)
|
||||
{ SETIT(m_threadSpec, spec); }
|
||||
{ SETIT(m_parameters.threadSpec, spec); }
|
||||
|
||||
bool BreakpointData::setType(BreakpointType type)
|
||||
{ SETIT(m_type, type); }
|
||||
{ SETIT(m_parameters.type, type); }
|
||||
|
||||
bool BreakpointData::setCondition(const QByteArray &cond)
|
||||
{ SETIT(m_condition, cond); }
|
||||
{ SETIT(m_parameters.condition, cond); }
|
||||
|
||||
#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 useMarkerPosition) const
|
||||
{
|
||||
int line = useMarkerPosition ? m_markerLineNumber : m_lineNumber;
|
||||
int line = useMarkerPosition ? m_markerLineNumber : m_parameters.lineNumber;
|
||||
return lineNumber == line && fileNameMatch(fileName, m_markerFileName);
|
||||
}
|
||||
|
||||
bool BreakpointData::conditionsMatch(const QByteArray &other) const
|
||||
{
|
||||
// Some versions of gdb "beautify" the passed condition.
|
||||
QByteArray s1 = m_condition;
|
||||
QByteArray s1 = m_parameters.condition;
|
||||
s1.replace(' ', "");
|
||||
QByteArray s2 = other;
|
||||
s2.replace(' ', "");
|
||||
@@ -152,15 +156,15 @@ QString BreakpointResponse::toString() const
|
||||
{
|
||||
QString result;
|
||||
QTextStream ts(&result);
|
||||
ts << bpNumber;
|
||||
ts << bpCondition;
|
||||
ts << bpIgnoreCount;
|
||||
ts << bpFileName;
|
||||
ts << bpFullName;
|
||||
ts << bpLineNumber;
|
||||
ts << bpThreadSpec;
|
||||
ts << bpFuncName;
|
||||
ts << bpAddress;
|
||||
ts << number;
|
||||
ts << condition;
|
||||
ts << ignoreCount;
|
||||
ts << fileName;
|
||||
ts << fullName;
|
||||
ts << lineNumber;
|
||||
ts << threadSpec;
|
||||
ts << functionName;
|
||||
ts << address;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,6 +81,28 @@ enum BreakpointState
|
||||
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
|
||||
{
|
||||
private:
|
||||
@@ -92,26 +114,27 @@ private:
|
||||
public:
|
||||
explicit BreakpointData(BreakpointType = UnknownType);
|
||||
|
||||
BreakpointType type() const { return m_type; }
|
||||
quint64 address() const { return m_address; }
|
||||
bool useFullPath() const { return m_useFullPath; }
|
||||
BreakpointType type() const { return m_parameters.type; }
|
||||
quint64 address() const { return m_parameters.address; }
|
||||
bool useFullPath() const { return m_parameters.useFullPath; }
|
||||
QString toString() const;
|
||||
|
||||
bool isLocatedAt(const QString &fileName, int lineNumber,
|
||||
bool useMarkerPosition) 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 fileName() const { return m_fileName; }
|
||||
QString fileName() const { return m_parameters.fileName; }
|
||||
int markerLineNumber() const { return m_markerLineNumber; }
|
||||
int lineNumber() const { return m_lineNumber; }
|
||||
int ignoreCount() const { return m_ignoreCount; }
|
||||
bool isEnabled() const { return m_enabled; }
|
||||
QByteArray threadSpec() const { return m_threadSpec; }
|
||||
QByteArray condition() const { return m_condition; }
|
||||
int lineNumber() const { return m_parameters.lineNumber; }
|
||||
int ignoreCount() const { return m_parameters.ignoreCount; }
|
||||
bool isEnabled() const { return m_parameters.enabled; }
|
||||
QByteArray threadSpec() const { return m_parameters.threadSpec; }
|
||||
QByteArray condition() const { return m_parameters.condition; }
|
||||
const BreakpointParameters ¶meters() const { return m_parameters; }
|
||||
|
||||
bool isWatchpoint() const { return m_type == Watchpoint; }
|
||||
bool isBreakpoint() const { return m_type != Watchpoint; } // Enough for now.
|
||||
bool isWatchpoint() const { return type() == Watchpoint; }
|
||||
bool isBreakpoint() const { return type() != Watchpoint; } // Enough for now.
|
||||
// Generic name for function to break on 'throw'
|
||||
static const char *throwFunction;
|
||||
static const char *catchFunction;
|
||||
@@ -133,18 +156,7 @@ private:
|
||||
|
||||
private:
|
||||
// This "user requested information" will get stored in the session.
|
||||
BreakpointType m_type; // Type of breakpoint.
|
||||
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;
|
||||
BreakpointParameters m_parameters;
|
||||
QString m_markerFileName; // Used to locate the marker.
|
||||
int m_markerLineNumber;
|
||||
|
||||
@@ -154,27 +166,17 @@ public:
|
||||
|
||||
// This is what debuggers produced in response to the attempt to
|
||||
// insert a breakpoint. The data might differ from the requested bits.
|
||||
class BreakpointResponse
|
||||
class BreakpointResponse : public BreakpointParameters
|
||||
{
|
||||
public:
|
||||
BreakpointResponse();
|
||||
QString toString() const;
|
||||
|
||||
public:
|
||||
int bpNumber; // Breakpoint number assigned by the debugger engine.
|
||||
BreakpointType bpType; // Breakpoint type used by debugger engine.
|
||||
QByteArray bpCondition; // Condition acknowledged by the debugger engine.
|
||||
int bpIgnoreCount; // Ignore count acknowledged by the debugger engine.
|
||||
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>
|
||||
int number; // Breakpoint number assigned by the debugger engine.
|
||||
QString fullName; // Full file name acknowledged by the debugger engine.
|
||||
bool multiple; // Happens in constructors/gdb.
|
||||
QByteArray state; // gdb: <PENDING>, <MULTIPLE>
|
||||
};
|
||||
|
||||
typedef QList<BreakpointId> BreakpointIds;
|
||||
|
||||
@@ -71,16 +71,16 @@ static inline QString msgCannotSetBreakAtFunction(const QString &func, const QSt
|
||||
|
||||
void setBreakpointResponse(const BreakpointData *nbd, int number, BreakpointResponse *response)
|
||||
{
|
||||
response->bpAddress = nbd->address();
|
||||
response->bpNumber = number;
|
||||
response->bpFuncName = nbd->functionName();
|
||||
response->bpType = nbd->type();
|
||||
response->bpCondition = nbd->condition();
|
||||
response->bpIgnoreCount = nbd->ignoreCount();
|
||||
response->bpFullName = response->bpFileName = nbd->fileName();
|
||||
response->bpLineNumber = nbd->lineNumber();
|
||||
response->bpThreadSpec = nbd->threadSpec();
|
||||
response->bpEnabled = nbd->isEnabled();
|
||||
response->address = nbd->address();
|
||||
response->number = number;
|
||||
response->functionName = nbd->functionName();
|
||||
response->type = nbd->type();
|
||||
response->condition = nbd->condition();
|
||||
response->ignoreCount = nbd->ignoreCount();
|
||||
response->fullName = response->fileName = nbd->fileName();
|
||||
response->lineNumber = nbd->lineNumber();
|
||||
response->threadSpec = nbd->threadSpec();
|
||||
response->enabled = nbd->isEnabled();
|
||||
}
|
||||
|
||||
bool addCdbBreakpoint(CIDebugControl* debugControl,
|
||||
@@ -116,8 +116,8 @@ bool addCdbBreakpoint(CIDebugControl* debugControl,
|
||||
if (debugBreakpoints)
|
||||
qDebug("Added %lu at 0x%lx %s", id, address, qPrintable(ncdbbp.toString()));
|
||||
setBreakpointResponse(nbd, id, response);
|
||||
response->bpAddress = address;
|
||||
response->bpFuncName = resolvedFunction;
|
||||
response->address = address;
|
||||
response->functionName = resolvedFunction;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -2293,8 +2293,8 @@ void DebuggerPluginPrivate::requestContextMenu(TextEditor::ITextEditor *editor,
|
||||
QString line = editor->contents()
|
||||
.section('\n', lineNumber - 1, lineNumber - 1);
|
||||
BreakpointResponse needle;
|
||||
needle.bpAddress = DisassemblerViewAgent::addressFromDisassemblyLine(line);
|
||||
needle.bpLineNumber = -1;
|
||||
needle.address = DisassemblerViewAgent::addressFromDisassemblyLine(line);
|
||||
needle.lineNumber = -1;
|
||||
id = breakHandler()->findSimilarBreakpoint(needle);
|
||||
} else {
|
||||
fileName = editor->file()->fileName();
|
||||
|
||||
@@ -136,31 +136,31 @@ QDataStream &operator>>(QDataStream &stream, StackFrames &frames)
|
||||
|
||||
QDataStream &operator<<(QDataStream &stream, const BreakpointResponse &s)
|
||||
{
|
||||
stream << s.bpNumber;
|
||||
stream << s.bpCondition;
|
||||
stream << s.bpIgnoreCount;
|
||||
stream << s.bpFileName;
|
||||
stream << s.bpFullName;
|
||||
stream << s.bpLineNumber;
|
||||
stream << s.number;
|
||||
stream << s.condition;
|
||||
stream << s.ignoreCount;
|
||||
stream << s.fileName;
|
||||
stream << s.fullName;
|
||||
stream << s.lineNumber;
|
||||
//stream << s.bpCorrectedLineNumber;
|
||||
stream << s.bpThreadSpec;
|
||||
stream << s.bpFuncName;
|
||||
stream << s.bpAddress;
|
||||
stream << s.threadSpec;
|
||||
stream << s.functionName;
|
||||
stream << s.address;
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &stream, BreakpointResponse &s)
|
||||
{
|
||||
stream >> s.bpNumber;
|
||||
stream >> s.bpCondition;
|
||||
stream >> s.bpIgnoreCount;
|
||||
stream >> s.bpFileName;
|
||||
stream >> s.bpFullName;
|
||||
stream >> s.bpLineNumber;
|
||||
stream >> s.number;
|
||||
stream >> s.condition;
|
||||
stream >> s.ignoreCount;
|
||||
stream >> s.fileName;
|
||||
stream >> s.fullName;
|
||||
stream >> s.lineNumber;
|
||||
//stream >> s.bpCorrectedLineNumber;
|
||||
stream >> s.bpThreadSpec;
|
||||
stream >> s.bpFuncName;
|
||||
stream >> s.bpAddress;
|
||||
stream >> s.threadSpec;
|
||||
stream >> s.functionName;
|
||||
stream >> s.address;
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
@@ -2059,24 +2059,24 @@ void GdbEngine::setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt)
|
||||
|
||||
BreakpointResponse response;
|
||||
//data->pending = false;
|
||||
response.bpMultiple = false;
|
||||
response.bpEnabled = true;
|
||||
response.bpCondition.clear();
|
||||
response.multiple = false;
|
||||
response.enabled = true;
|
||||
response.condition.clear();
|
||||
QByteArray file, fullName;
|
||||
foreach (const GdbMi &child, bkpt.children()) {
|
||||
if (child.hasName("number")) {
|
||||
response.bpNumber = child.data().toInt();
|
||||
response.number = child.data().toInt();
|
||||
} else if (child.hasName("func")) {
|
||||
response.bpFuncName = _(child.data());
|
||||
response.functionName = _(child.data());
|
||||
} else if (child.hasName("addr")) {
|
||||
// <MULTIPLE> happens in constructors. In this case there are
|
||||
// _two_ fields named "addr" in the response. On Linux that is...
|
||||
if (child.data().startsWith("0x")) {
|
||||
response.bpAddress = child.data().mid(2).toULongLong(0, 16);
|
||||
response.address = child.data().mid(2).toULongLong(0, 16);
|
||||
} else {
|
||||
response.bpState = child.data();
|
||||
response.state = child.data();
|
||||
if (child.data() == "<MULTIPLE>")
|
||||
response.bpMultiple = true;
|
||||
response.multiple = true;
|
||||
}
|
||||
} else if (child.hasName("file")) {
|
||||
file = child.data();
|
||||
@@ -2085,17 +2085,17 @@ void GdbEngine::setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt)
|
||||
} else if (child.hasName("line")) {
|
||||
bool ok;
|
||||
const int lineNumber = child.data().toInt(&ok);
|
||||
response.bpLineNumber = lineNumber;
|
||||
response.lineNumber = lineNumber;
|
||||
//if (ok && response.bpCorrectedLineNumber <= 0)
|
||||
// data->setMarkerLineNumber(lineNumber);
|
||||
} else if (child.hasName("cond")) {
|
||||
response.bpCondition = child.data();
|
||||
response.condition = child.data();
|
||||
// gdb 6.3 likes to "rewrite" conditions. Just accept that fact.
|
||||
//if (response.bpCondition != data->condition()
|
||||
// && data->conditionsMatch(response.bpCondition))
|
||||
// data->setCondition(response.bpCondition);
|
||||
} else if (child.hasName("enabled")) {
|
||||
response.bpEnabled = (child.data() == "y");
|
||||
response.enabled = (child.data() == "y");
|
||||
} else if (child.hasName("pending")) {
|
||||
//data->setState(BreakpointPending);
|
||||
breakHandler()->setState(id, BreakpointPending);
|
||||
@@ -2106,9 +2106,9 @@ void GdbEngine::setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt)
|
||||
QByteArray ba = child.data();
|
||||
if (ba.startsWith('<') && ba.endsWith('>'))
|
||||
ba = ba.mid(1, ba.size() - 2);
|
||||
response.bpFuncName = _(ba);
|
||||
response.functionName = _(ba);
|
||||
} else if (child.hasName("thread")) {
|
||||
response.bpThreadSpec = child.data();
|
||||
response.threadSpec = child.data();
|
||||
} else if (child.hasName("type")) {
|
||||
// FIXME: This should not change the type.
|
||||
//if (child.data().contains("reakpoint")) // "breakpoint", "hw breakpoint"
|
||||
@@ -2125,7 +2125,7 @@ void GdbEngine::setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt)
|
||||
QString name;
|
||||
if (!fullName.isEmpty()) {
|
||||
name = cleanupFullName(QFile::decodeName(fullName));
|
||||
response.bpFileName = name;
|
||||
response.fileName = name;
|
||||
//if (data->markerFileName().isEmpty())
|
||||
// data->setMarkerFileName(name);
|
||||
} else {
|
||||
@@ -2134,7 +2134,7 @@ void GdbEngine::setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt)
|
||||
// gdb's own. No point in assigning markerFileName for now.
|
||||
}
|
||||
if (!name.isEmpty())
|
||||
response.bpFileName = name;
|
||||
response.fileName = name;
|
||||
|
||||
breakHandler()->setResponse(id, response);
|
||||
}
|
||||
@@ -2190,7 +2190,7 @@ void GdbEngine::handleWatchInsert(const GdbResponse &response)
|
||||
if (ba.startsWith("Hardware watchpoint ")) {
|
||||
const int pos = ba.indexOf(':', 20);
|
||||
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);
|
||||
} else {
|
||||
showMessage(_("CANNOT PARSE WATCHPOINT FROM" + ba));
|
||||
@@ -2278,7 +2278,7 @@ void GdbEngine::handleBreakList(const GdbMi &table)
|
||||
|
||||
foreach (const GdbMi &bkpt, bkpts) {
|
||||
BreakpointResponse needle;
|
||||
needle.bpFileName = _("xx");
|
||||
needle.fileName = _("xx");
|
||||
BreakpointId id = breakHandler()->findSimilarBreakpoint(needle);
|
||||
//qDebug() << "\n\nGOT: " << bkpt.toString() << '\n' << temp.toString();
|
||||
// FIXME: use setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt)
|
||||
@@ -2374,14 +2374,14 @@ void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointId id)
|
||||
re.setMinimal(true);
|
||||
|
||||
BreakpointResponse response;
|
||||
response.bpFileName = _("<MULTIPLE>");
|
||||
response.fileName = _("<MULTIPLE>");
|
||||
|
||||
QString requestedFileName = breakHandler()->fileName(id);
|
||||
|
||||
if (re.indexIn(output) != -1) {
|
||||
response.bpAddress = re.cap(1).toULongLong(0, 16);
|
||||
response.bpFuncName = re.cap(2).trimmed();
|
||||
response.bpLineNumber = re.cap(4).toInt();
|
||||
response.address = re.cap(1).toULongLong(0, 16);
|
||||
response.functionName = re.cap(2).trimmed();
|
||||
response.lineNumber = re.cap(4).toInt();
|
||||
QString full = fullName(re.cap(3));
|
||||
if (full.isEmpty()) {
|
||||
// FIXME: This happens without UsePreciseBreakpoints regularly.
|
||||
@@ -2405,10 +2405,10 @@ void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointId id)
|
||||
// qDebug() << "111";
|
||||
// data->setMarkerFileName(full);
|
||||
//}
|
||||
response.bpFileName = full;
|
||||
response.fileName = full;
|
||||
} else {
|
||||
qDebug() << "COULD NOT MATCH " << re.pattern() << " AND " << output;
|
||||
response.bpNumber = -1; // <unavailable>
|
||||
response.number = -1; // <unavailable>
|
||||
}
|
||||
breakHandler()->setResponse(id, response);
|
||||
}
|
||||
@@ -2437,7 +2437,7 @@ void GdbEngine::handleInfoLine(const GdbResponse &response)
|
||||
const int line = ba.mid(5, pos - 5).toInt();
|
||||
const BreakpointId id = response.cookie.toInt();
|
||||
BreakpointResponse br = breakHandler()->response(id);
|
||||
br.bpLineNumber = line;
|
||||
br.lineNumber = line;
|
||||
breakHandler()->setResponse(id, br);
|
||||
}
|
||||
}
|
||||
@@ -2619,28 +2619,28 @@ void GdbEngine::changeBreakpoint(BreakpointId id)
|
||||
QTC_ASSERT(data0, return);
|
||||
const BreakpointData &data = *data0;
|
||||
const BreakpointResponse &response = breakHandler()->response(id);
|
||||
QTC_ASSERT(response.bpNumber > 0, return);
|
||||
const QByteArray bpnr = QByteArray::number(response.bpNumber);
|
||||
QTC_ASSERT(response.number > 0, return);
|
||||
const QByteArray bpnr = QByteArray::number(response.number);
|
||||
|
||||
if (data.condition() != response.bpCondition
|
||||
&& !data.conditionsMatch(response.bpCondition)) {
|
||||
if (data.condition() != response.condition
|
||||
&& !data.conditionsMatch(response.condition)) {
|
||||
// Update conditions if needed.
|
||||
postCommand("condition " + bpnr + ' ' + data.condition(),
|
||||
NeedsStop | RebuildBreakpointModel,
|
||||
CB(handleBreakCondition), id);
|
||||
}
|
||||
if (data.ignoreCount() != response.bpIgnoreCount) {
|
||||
if (data.ignoreCount() != response.ignoreCount) {
|
||||
// Update ignorecount if needed.
|
||||
postCommand("ignore " + bpnr + ' ' + QByteArray::number(data.ignoreCount()),
|
||||
NeedsStop | RebuildBreakpointModel,
|
||||
CB(handleBreakIgnore), id);
|
||||
}
|
||||
if (!data.isEnabled() && response.bpEnabled) {
|
||||
if (!data.isEnabled() && response.enabled) {
|
||||
postCommand("-break-disable " + bpnr,
|
||||
NeedsStop | RebuildBreakpointModel,
|
||||
CB(handleBreakDisable), id);
|
||||
}
|
||||
if (data.isEnabled() && !response.bpEnabled) {
|
||||
if (data.isEnabled() && !response.enabled) {
|
||||
postCommand("-break-enable " + bpnr,
|
||||
NeedsStop | RebuildBreakpointModel,
|
||||
CB(handleBreakEnable), id);
|
||||
@@ -2678,9 +2678,9 @@ void GdbEngine::removeBreakpoint(BreakpointId id)
|
||||
QTC_ASSERT(handler->state(id) == BreakpointRemoveRequested, /**/);
|
||||
handler->setState(id, BreakpointRemoveProceeding);
|
||||
BreakpointResponse br = handler->response(id);
|
||||
showMessage(_("DELETING BP %1 IN ").arg(br.bpNumber)
|
||||
showMessage(_("DELETING BP %1 IN ").arg(br.number)
|
||||
+ handler->markerFileName(id));
|
||||
postCommand("-break-delete " + QByteArray::number(br.bpNumber),
|
||||
postCommand("-break-delete " + QByteArray::number(br.number),
|
||||
NeedsStop | RebuildBreakpointModel);
|
||||
// Pretend it succeeds without waiting for response. Feels better.
|
||||
handler->notifyBreakpointRemoveOk(id);
|
||||
|
||||
@@ -379,9 +379,9 @@ void PdbEngine::handleBreakInsert(const PdbResponse &response)
|
||||
QByteArray file = response.data.mid(pos1 + 4, pos2 - pos1 - 4);
|
||||
QByteArray line = response.data.mid(pos2 + 1);
|
||||
BreakpointResponse br;
|
||||
br.bpNumber = bpnr.toInt();
|
||||
br.bpFileName = _(file);
|
||||
br.bpLineNumber = line.toInt();
|
||||
br.number = bpnr.toInt();
|
||||
br.fileName = _(file);
|
||||
br.lineNumber = line.toInt();
|
||||
handler->setResponse(id, br);
|
||||
}
|
||||
|
||||
|
||||
@@ -740,9 +740,9 @@ void QmlEngine::messageReceived(const QByteArray &message)
|
||||
if (processedFilename == file && handler->lineNumber(id) == line) {
|
||||
handler->setState(id, BreakpointInserted);
|
||||
BreakpointResponse br = handler->response(id);
|
||||
br.bpFileName = file;
|
||||
br.bpLineNumber = line;
|
||||
br.bpFuncName = function;
|
||||
br.fileName = file;
|
||||
br.lineNumber = line;
|
||||
br.functionName = function;
|
||||
handler->setResponse(id, br);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,9 +627,9 @@ bool ScriptEngine::checkForBreakCondition(bool byFunction)
|
||||
BreakpointResponse br;
|
||||
// We just run into a breakpoint.
|
||||
//SDEBUG("RESOLVING BREAKPOINT AT " << fileName << lineNumber);
|
||||
br.bpLineNumber = lineNumber;
|
||||
br.bpFileName = fileName;
|
||||
br.bpFuncName = functionName;
|
||||
br.lineNumber = lineNumber;
|
||||
br.fileName = fileName;
|
||||
br.functionName = functionName;
|
||||
handler->setState(id, BreakpointInserted);
|
||||
handler->setResponse(id, br);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user