forked from qt-creator/qt-creator
debugger: introduce watchpoint-by-expression
This commit is contained in:
@@ -114,8 +114,10 @@ static QString typeToString(BreakpointType type)
|
|||||||
return msgBreakpointAtSpecialFunc("syscall");
|
return msgBreakpointAtSpecialFunc("syscall");
|
||||||
case BreakpointAtMain:
|
case BreakpointAtMain:
|
||||||
return BreakHandler::tr("Breakpoint at Function \"main()\"");
|
return BreakHandler::tr("Breakpoint at Function \"main()\"");
|
||||||
case Watchpoint:
|
case WatchpointAtAddress:
|
||||||
return BreakHandler::tr("Watchpoint");
|
return BreakHandler::tr("Watchpoint at Address");
|
||||||
|
case WatchpointAtExpression:
|
||||||
|
return BreakHandler::tr("Watchpoint at Expression");
|
||||||
case UnknownType:
|
case UnknownType:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -517,7 +519,7 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
|
|||||||
//|| data.type == BreakpointAtVFork
|
//|| data.type == BreakpointAtVFork
|
||||||
|| data.type == BreakpointAtSysCall)
|
|| data.type == BreakpointAtSysCall)
|
||||||
return typeToString(data.type);
|
return typeToString(data.type);
|
||||||
if (data.type == Watchpoint)
|
if (data.type == WatchpointAtAddress)
|
||||||
return tr("Watchpoint at 0x%1").arg(data.address, 0, 16);
|
return tr("Watchpoint at 0x%1").arg(data.address, 0, 16);
|
||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
@@ -648,6 +650,7 @@ PROPERTY(int, threadSpec, setThreadSpec)
|
|||||||
PROPERTY(QByteArray, condition, setCondition)
|
PROPERTY(QByteArray, condition, setCondition)
|
||||||
GETTER(int, lineNumber)
|
GETTER(int, lineNumber)
|
||||||
PROPERTY(quint64, address, setAddress)
|
PROPERTY(quint64, address, setAddress)
|
||||||
|
PROPERTY(QByteArray, expression, setExpression)
|
||||||
PROPERTY(int, ignoreCount, setIgnoreCount)
|
PROPERTY(int, ignoreCount, setIgnoreCount)
|
||||||
|
|
||||||
bool BreakHandler::isEnabled(BreakpointId id) const
|
bool BreakHandler::isEnabled(BreakpointId id) const
|
||||||
@@ -673,6 +676,13 @@ void BreakHandler::setEnabled(BreakpointId id, bool on)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BreakHandler::isWatchpoint(BreakpointId id) const
|
||||||
|
{
|
||||||
|
ConstIterator it = m_storage.find(id);
|
||||||
|
BREAK_ASSERT(it != m_storage.end(), return false);
|
||||||
|
return it->data.isWatchpoint();
|
||||||
|
}
|
||||||
|
|
||||||
bool BreakHandler::isTracepoint(BreakpointId id) const
|
bool BreakHandler::isTracepoint(BreakpointId id) const
|
||||||
{
|
{
|
||||||
ConstIterator it = m_storage.find(id);
|
ConstIterator it = m_storage.find(id);
|
||||||
@@ -1195,7 +1205,7 @@ QIcon BreakHandler::BreakpointItem::icon() const
|
|||||||
// cursor is near a line with a breakpoint marker (+/- 2 lines or so).
|
// cursor is near a line with a breakpoint marker (+/- 2 lines or so).
|
||||||
if (data.isTracepoint())
|
if (data.isTracepoint())
|
||||||
return BreakHandler::tracepointIcon();
|
return BreakHandler::tracepointIcon();
|
||||||
if (data.type == Watchpoint)
|
if (data.type == WatchpointAtAddress)
|
||||||
return BreakHandler::watchpointIcon();
|
return BreakHandler::watchpointIcon();
|
||||||
if (!data.enabled)
|
if (!data.enabled)
|
||||||
return BreakHandler::disabledBreakpointIcon();
|
return BreakHandler::disabledBreakpointIcon();
|
||||||
|
|||||||
@@ -115,6 +115,8 @@ public:
|
|||||||
void setFileName(BreakpointId, const QString &fileName);
|
void setFileName(BreakpointId, const QString &fileName);
|
||||||
QString functionName(BreakpointId id) const;
|
QString functionName(BreakpointId id) const;
|
||||||
void setFunctionName(BreakpointId, const QString &functionName);
|
void setFunctionName(BreakpointId, const QString &functionName);
|
||||||
|
QByteArray expression(BreakpointId id) const;
|
||||||
|
void setExpression(BreakpointId, const QByteArray &expression);
|
||||||
BreakpointType type(BreakpointId id) const;
|
BreakpointType type(BreakpointId id) const;
|
||||||
void setType(BreakpointId id, const BreakpointType &type);
|
void setType(BreakpointId id, const BreakpointType &type);
|
||||||
quint64 address(BreakpointId id) const;
|
quint64 address(BreakpointId id) const;
|
||||||
@@ -129,6 +131,7 @@ public:
|
|||||||
void updateLineNumberFromMarker(BreakpointId id, int lineNumber);
|
void updateLineNumberFromMarker(BreakpointId id, int lineNumber);
|
||||||
void setMarkerFileAndLine(BreakpointId id,
|
void setMarkerFileAndLine(BreakpointId id,
|
||||||
const QString &fileName, int lineNumber);
|
const QString &fileName, int lineNumber);
|
||||||
|
bool isWatchpoint(BreakpointId id) const;
|
||||||
bool isTracepoint(BreakpointId id) const;
|
bool isTracepoint(BreakpointId id) const;
|
||||||
void setTracepoint(BreakpointId, bool on);
|
void setTracepoint(BreakpointId, bool on);
|
||||||
DebuggerEngine *engine(BreakpointId id) const;
|
DebuggerEngine *engine(BreakpointId id) const;
|
||||||
|
|||||||
@@ -119,9 +119,12 @@ QString BreakpointParameters::toString() const
|
|||||||
ts << " FunctionName: " << functionName;
|
ts << " FunctionName: " << functionName;
|
||||||
break;
|
break;
|
||||||
case BreakpointByAddress:
|
case BreakpointByAddress:
|
||||||
case Watchpoint:
|
case WatchpointAtAddress:
|
||||||
ts << " Address: " << address;
|
ts << " Address: " << address;
|
||||||
break;
|
break;
|
||||||
|
case WatchpointAtExpression:
|
||||||
|
ts << " Expression: " << expression;
|
||||||
|
break;
|
||||||
case BreakpointAtThrow:
|
case BreakpointAtThrow:
|
||||||
case BreakpointAtCatch:
|
case BreakpointAtCatch:
|
||||||
case BreakpointAtMain:
|
case BreakpointAtMain:
|
||||||
|
|||||||
@@ -62,7 +62,8 @@ enum BreakpointType
|
|||||||
BreakpointAtExec,
|
BreakpointAtExec,
|
||||||
//BreakpointAtVFork,
|
//BreakpointAtVFork,
|
||||||
BreakpointAtSysCall,
|
BreakpointAtSysCall,
|
||||||
Watchpoint
|
WatchpointAtAddress,
|
||||||
|
WatchpointAtExpression
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \enum Debugger::Internal::BreakpointState
|
//! \enum Debugger::Internal::BreakpointState
|
||||||
@@ -93,19 +94,21 @@ enum BreakpointParts
|
|||||||
FileAndLinePart = 0x1,
|
FileAndLinePart = 0x1,
|
||||||
FunctionPart = 0x2,
|
FunctionPart = 0x2,
|
||||||
AddressPart = 0x4,
|
AddressPart = 0x4,
|
||||||
ConditionPart = 0x8,
|
ExpressionPart = 0x8,
|
||||||
IgnoreCountPart = 0x10,
|
ConditionPart = 0x10,
|
||||||
ThreadSpecPart = 0x20,
|
IgnoreCountPart = 0x20,
|
||||||
|
ThreadSpecPart = 0x40,
|
||||||
AllConditionParts = ConditionPart|IgnoreCountPart|ThreadSpecPart,
|
AllConditionParts = ConditionPart|IgnoreCountPart|ThreadSpecPart,
|
||||||
ModulePart = 0x40,
|
ModulePart = 0x80,
|
||||||
TracePointPart = 0x80,
|
TracePointPart = 0x100,
|
||||||
|
|
||||||
EnabledPart = 0x100,
|
EnabledPart = 0x200,
|
||||||
TypePart = 0x200,
|
TypePart = 0x400,
|
||||||
PathUsagePart = 0x400,
|
PathUsagePart = 0x800,
|
||||||
CommandPart = 0x400,
|
CommandPart = 0x1000,
|
||||||
|
|
||||||
AllParts = FileAndLinePart|FunctionPart|AddressPart|ConditionPart
|
AllParts = FileAndLinePart|FunctionPart
|
||||||
|
|ExpressionPart|AddressPart|ConditionPart
|
||||||
|IgnoreCountPart|ThreadSpecPart|ModulePart|TracePointPart
|
|IgnoreCountPart|ThreadSpecPart|ModulePart|TracePointPart
|
||||||
|EnabledPart|TypePart|PathUsagePart|CommandPart
|
|EnabledPart|TypePart|PathUsagePart|CommandPart
|
||||||
};
|
};
|
||||||
@@ -123,9 +126,10 @@ public:
|
|||||||
BreakpointParts differencesTo(const BreakpointParameters &rhs) const;
|
BreakpointParts differencesTo(const BreakpointParameters &rhs) const;
|
||||||
bool equals(const BreakpointParameters &rhs) const;
|
bool equals(const BreakpointParameters &rhs) const;
|
||||||
bool conditionsMatch(const QByteArray &other) const;
|
bool conditionsMatch(const QByteArray &other) const;
|
||||||
bool isWatchpoint() const { return type == Watchpoint; }
|
bool isWatchpoint() const
|
||||||
|
{ return type == WatchpointAtAddress || type == WatchpointAtExpression; }
|
||||||
// Enough for now.
|
// Enough for now.
|
||||||
bool isBreakpoint() const { return type != Watchpoint && !tracepoint; }
|
bool isBreakpoint() const { return !isWatchpoint() && !isTracepoint(); }
|
||||||
bool isTracepoint() const { return tracepoint; }
|
bool isTracepoint() const { return tracepoint; }
|
||||||
QString toString() const;
|
QString toString() const;
|
||||||
|
|
||||||
@@ -139,7 +143,8 @@ public:
|
|||||||
QByteArray condition; //!< Condition associated with breakpoint.
|
QByteArray condition; //!< Condition associated with breakpoint.
|
||||||
int ignoreCount; //!< Ignore count associated with breakpoint.
|
int ignoreCount; //!< Ignore count associated with breakpoint.
|
||||||
int lineNumber; //!< Line in source file.
|
int lineNumber; //!< Line in source file.
|
||||||
quint64 address; //!< Address for watchpoints.
|
quint64 address; //!< Address for address based watchpoints.
|
||||||
|
QByteArray expression; //!< Address for expression based watchpoints.
|
||||||
uint size; //!< Size of watched area for watchpoints.
|
uint size; //!< Size of watched area for watchpoints.
|
||||||
uint bitpos; //!< Location of watched bitfield within watched area.
|
uint bitpos; //!< Location of watched bitfield within watched area.
|
||||||
uint bitsize; //!< Size of watched bitfield within watched area.
|
uint bitsize; //!< Size of watched bitfield within watched area.
|
||||||
|
|||||||
@@ -90,6 +90,19 @@
|
|||||||
<widget class="QLineEdit" name="lineEditAddress"/>
|
<widget class="QLineEdit" name="lineEditAddress"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0">
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="labelExpression">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Expression:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>lineEditExpression</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineEditExpression"/>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
<widget class="QLabel" name="labelFunction">
|
<widget class="QLabel" name="labelFunction">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Fun&ction:</string>
|
<string>Fun&ction:</string>
|
||||||
@@ -99,7 +112,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="6" column="1">
|
||||||
<widget class="QLineEdit" name="lineEditFunction"/>
|
<widget class="QLineEdit" name="lineEditFunction"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
@@ -80,20 +80,6 @@ public slots:
|
|||||||
void typeChanged(int index);
|
void typeChanged(int index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum DialogPart {
|
|
||||||
FileAndLinePart = 0x1,
|
|
||||||
FunctionPart = 0x2,
|
|
||||||
AddressPart = 0x4,
|
|
||||||
ConditionPart = 0x8,
|
|
||||||
IgnoreCountPart = 0x10,
|
|
||||||
ThreadSpecPart = 0x20,
|
|
||||||
AllConditionParts = ConditionPart|IgnoreCountPart|ThreadSpecPart,
|
|
||||||
ModulePart = 0x40,
|
|
||||||
TracePointPart = 0x80,
|
|
||||||
AllParts = FileAndLinePart|FunctionPart|AddressPart|ConditionPart
|
|
||||||
|IgnoreCountPart|ThreadSpecPart|ModulePart|TracePointPart
|
|
||||||
};
|
|
||||||
|
|
||||||
void setPartsEnabled(unsigned partsMask);
|
void setPartsEnabled(unsigned partsMask);
|
||||||
void clearOtherParts(unsigned partsMask);
|
void clearOtherParts(unsigned partsMask);
|
||||||
void getParts(unsigned partsMask, BreakpointParameters *data) const;
|
void getParts(unsigned partsMask, BreakpointParameters *data) const;
|
||||||
@@ -122,17 +108,18 @@ BreakpointDialog::BreakpointDialog(unsigned engineCapabilities, QWidget *parent)
|
|||||||
// Match BreakpointType (omitting unknown type).
|
// Match BreakpointType (omitting unknown type).
|
||||||
m_ui.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
QStringList types;
|
QStringList types;
|
||||||
types << tr("File and Line Number")
|
types << tr("File name and line number")
|
||||||
<< tr("Function Name")
|
<< tr("Function name")
|
||||||
<< tr("Address")
|
<< tr("Address")
|
||||||
<< tr("Break when C++ Exception is Thrown")
|
<< tr("Break when C++ exception is thrown")
|
||||||
<< tr("Break when C++ Exception is Caught")
|
<< tr("Break when C++ exception is caught")
|
||||||
<< tr("Break when Function \"main()\" Starts")
|
<< tr("Break when function \"main()\" starts")
|
||||||
<< tr("Break when a new Process is Forked")
|
<< tr("Break when a new process is forked")
|
||||||
<< tr("Break when a new Process is Executed")
|
<< tr("Break when a new process is executed")
|
||||||
<< tr("Break when a System Call is Executed")
|
<< tr("Break when a system call is executed")
|
||||||
<< tr("Break on Data Access (Watchpoint)");
|
<< tr("Break on data access (Watchpoint at address)")
|
||||||
QTC_ASSERT(types.size() == Watchpoint, return; )
|
<< tr("Break on data access (Watchpoint at expression)");
|
||||||
|
QTC_ASSERT(types.size() == WatchpointAtExpression, return; )
|
||||||
m_ui.comboBoxType->addItems(types);
|
m_ui.comboBoxType->addItems(types);
|
||||||
m_ui.pathChooserFileName->setExpectedKind(Utils::PathChooser::File);
|
m_ui.pathChooserFileName->setExpectedKind(Utils::PathChooser::File);
|
||||||
connect(m_ui.comboBoxType, SIGNAL(activated(int)), SLOT(typeChanged(int)));
|
connect(m_ui.comboBoxType, SIGNAL(activated(int)), SLOT(typeChanged(int)));
|
||||||
@@ -213,6 +200,8 @@ void BreakpointDialog::setPartsEnabled(unsigned partsMask)
|
|||||||
|
|
||||||
m_ui.labelAddress->setEnabled(partsMask & AddressPart);
|
m_ui.labelAddress->setEnabled(partsMask & AddressPart);
|
||||||
m_ui.lineEditAddress->setEnabled(partsMask & AddressPart);
|
m_ui.lineEditAddress->setEnabled(partsMask & AddressPart);
|
||||||
|
m_ui.labelExpression->setEnabled(partsMask & ExpressionPart);
|
||||||
|
m_ui.lineEditExpression->setEnabled(partsMask & ExpressionPart);
|
||||||
|
|
||||||
m_ui.labelCondition->setEnabled(partsMask & ConditionPart);
|
m_ui.labelCondition->setEnabled(partsMask & ConditionPart);
|
||||||
m_ui.lineEditCondition->setEnabled(partsMask & ConditionPart);
|
m_ui.lineEditCondition->setEnabled(partsMask & ConditionPart);
|
||||||
@@ -242,6 +231,8 @@ void BreakpointDialog::clearOtherParts(unsigned partsMask)
|
|||||||
|
|
||||||
if (invertedPartsMask & AddressPart)
|
if (invertedPartsMask & AddressPart)
|
||||||
m_ui.lineEditAddress->clear();
|
m_ui.lineEditAddress->clear();
|
||||||
|
if (invertedPartsMask & ExpressionPart)
|
||||||
|
m_ui.lineEditExpression->clear();
|
||||||
|
|
||||||
if (invertedPartsMask & ConditionPart)
|
if (invertedPartsMask & ConditionPart)
|
||||||
m_ui.lineEditCondition->clear();
|
m_ui.lineEditCondition->clear();
|
||||||
@@ -271,6 +262,8 @@ void BreakpointDialog::getParts(unsigned partsMask, BreakpointParameters *data)
|
|||||||
|
|
||||||
if (partsMask & AddressPart)
|
if (partsMask & AddressPart)
|
||||||
data->address = m_ui.lineEditAddress->text().toULongLong(0, 0);
|
data->address = m_ui.lineEditAddress->text().toULongLong(0, 0);
|
||||||
|
if (partsMask & ExpressionPart)
|
||||||
|
data->expression = m_ui.lineEditExpression->text().toUtf8();
|
||||||
|
|
||||||
if (partsMask & ConditionPart)
|
if (partsMask & ConditionPart)
|
||||||
data->condition = m_ui.lineEditCondition->text().toUtf8();
|
data->condition = m_ui.lineEditCondition->text().toUtf8();
|
||||||
@@ -309,6 +302,14 @@ void BreakpointDialog::setParts(unsigned mask, const BreakpointParameters &data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mask & ExpressionPart) {
|
||||||
|
if (!data.expression.isEmpty()) {
|
||||||
|
m_ui.lineEditExpression->setText(data.expression);
|
||||||
|
} else {
|
||||||
|
m_ui.lineEditExpression->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mask & ConditionPart)
|
if (mask & ConditionPart)
|
||||||
m_ui.lineEditCondition->setText(QString::fromUtf8(data.condition));
|
m_ui.lineEditCondition->setText(QString::fromUtf8(data.condition));
|
||||||
if (mask & IgnoreCountPart)
|
if (mask & IgnoreCountPart)
|
||||||
@@ -347,9 +348,12 @@ void BreakpointDialog::typeChanged(int)
|
|||||||
case BreakpointAtSysCall:
|
case BreakpointAtSysCall:
|
||||||
break;
|
break;
|
||||||
case BreakpointByAddress:
|
case BreakpointByAddress:
|
||||||
case Watchpoint:
|
case WatchpointAtAddress:
|
||||||
getParts(AddressPart|AllConditionParts|TracePointPart, &m_savedParameters);
|
getParts(AddressPart|AllConditionParts|TracePointPart, &m_savedParameters);
|
||||||
break;
|
break;
|
||||||
|
case WatchpointAtExpression:
|
||||||
|
getParts(ExpressionPart|AllConditionParts|TracePointPart, &m_savedParameters);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable and set up new state from saved values.
|
// Enable and set up new state from saved values.
|
||||||
@@ -381,11 +385,16 @@ void BreakpointDialog::typeChanged(int)
|
|||||||
setPartsEnabled(0);
|
setPartsEnabled(0);
|
||||||
break;
|
break;
|
||||||
case BreakpointByAddress:
|
case BreakpointByAddress:
|
||||||
case Watchpoint:
|
case WatchpointAtAddress:
|
||||||
setParts(AddressPart|AllConditionParts|TracePointPart, m_savedParameters);
|
setParts(AddressPart|AllConditionParts|TracePointPart, m_savedParameters);
|
||||||
setPartsEnabled(AddressPart|AllConditionParts|TracePointPart|TracePointPart);
|
setPartsEnabled(AddressPart|AllConditionParts|TracePointPart|TracePointPart);
|
||||||
clearOtherParts(AddressPart|AllConditionParts|TracePointPart);
|
clearOtherParts(AddressPart|AllConditionParts|TracePointPart);
|
||||||
break;
|
break;
|
||||||
|
case WatchpointAtExpression:
|
||||||
|
setParts(ExpressionPart|AllConditionParts|TracePointPart, m_savedParameters);
|
||||||
|
setPartsEnabled(ExpressionPart|AllConditionParts|TracePointPart|TracePointPart);
|
||||||
|
clearOtherParts(ExpressionPart|AllConditionParts|TracePointPart);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1069,7 +1069,7 @@ void CdbEngine::updateLocalVariable(const QByteArray &iname)
|
|||||||
unsigned CdbEngine::debuggerCapabilities() const
|
unsigned CdbEngine::debuggerCapabilities() const
|
||||||
{
|
{
|
||||||
return DisassemblerCapability | RegisterCapability | ShowMemoryCapability
|
return DisassemblerCapability | RegisterCapability | ShowMemoryCapability
|
||||||
|WatchpointCapability|JumpToLineCapability|AddWatcherCapability
|
|WatchpointByAddressCapability|JumpToLineCapability|AddWatcherCapability
|
||||||
|ReloadModuleCapability
|
|ReloadModuleCapability
|
||||||
|BreakOnThrowAndCatchCapability // Sort-of: Can break on throw().
|
|BreakOnThrowAndCatchCapability // Sort-of: Can break on throw().
|
||||||
|BreakConditionCapability|TracePointCapability
|
|BreakConditionCapability|TracePointCapability
|
||||||
@@ -1849,10 +1849,13 @@ unsigned CdbEngine::examineStopReason(const GdbMi &stopReason,
|
|||||||
id = 0;
|
id = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (id && breakHandler()->type(id) == Watchpoint) {
|
QString tid = QString::number(threadId);
|
||||||
*message = msgWatchpointTriggered(id, number, breakHandler()->address(id), QString::number(threadId));
|
if (id && breakHandler()->type(id) == WatchpointAtAddress) {
|
||||||
|
*message = msgWatchpointByAddressTriggered(id, number, breakHandler()->address(id), tid);
|
||||||
|
} else if (id && breakHandler()->type(id) == WatchpointAtExpression) {
|
||||||
|
*message = msgWatchpointByExpressionTriggered(id, number, breakHandler()->expression(id), tid);
|
||||||
} else {
|
} else {
|
||||||
*message = msgBreakpointTriggered(id, number, QString::number(threadId));
|
*message = msgBreakpointTriggered(id, number, tid);
|
||||||
}
|
}
|
||||||
rc |= StopReportStatusMessage|StopNotifyStop;
|
rc |= StopReportStatusMessage|StopNotifyStop;
|
||||||
return rc;
|
return rc;
|
||||||
@@ -2347,7 +2350,7 @@ bool CdbEngine::acceptsBreakpoint(BreakpointId id) const
|
|||||||
//case BreakpointAtVFork:
|
//case BreakpointAtVFork:
|
||||||
case BreakpointAtSysCall:
|
case BreakpointAtSysCall:
|
||||||
return false;
|
return false;
|
||||||
case Watchpoint:
|
case WatchpointAtAddress:
|
||||||
case BreakpointByFileAndLine:
|
case BreakpointByFileAndLine:
|
||||||
case BreakpointByFunction:
|
case BreakpointByFunction:
|
||||||
case BreakpointByAddress:
|
case BreakpointByAddress:
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ static BreakpointParameters fixWinMSVCBreakpoint(const BreakpointParameters &p)
|
|||||||
case BreakpointAtFork:
|
case BreakpointAtFork:
|
||||||
//case BreakpointAtVFork:
|
//case BreakpointAtVFork:
|
||||||
case BreakpointAtSysCall:
|
case BreakpointAtSysCall:
|
||||||
case Watchpoint:
|
case WatchpointAtAddress:
|
||||||
break;
|
break;
|
||||||
case BreakpointAtExec: { // Emulate by breaking on CreateProcessW().
|
case BreakpointAtExec: { // Emulate by breaking on CreateProcessW().
|
||||||
BreakpointParameters rc(BreakpointByFunction);
|
BreakpointParameters rc(BreakpointByFunction);
|
||||||
@@ -148,7 +148,7 @@ QByteArray cdbAddBreakpointCommand(const BreakpointParameters &bpIn,
|
|||||||
// Currently use 'bu' so that the offset expression (including file name)
|
// Currently use 'bu' so that the offset expression (including file name)
|
||||||
// is kept when reporting back breakpoints (which is otherwise discarded
|
// is kept when reporting back breakpoints (which is otherwise discarded
|
||||||
// when resolving).
|
// when resolving).
|
||||||
str << (bp.type == Watchpoint ? "ba" : "bu");
|
str << (bp.type == WatchpointAtAddress ? "ba" : "bu");
|
||||||
if (id != BreakpointId(-1))
|
if (id != BreakpointId(-1))
|
||||||
str << id;
|
str << id;
|
||||||
str << ' ';
|
str << ' ';
|
||||||
@@ -179,7 +179,7 @@ QByteArray cdbAddBreakpointCommand(const BreakpointParameters &bpIn,
|
|||||||
str << bp.module << '!';
|
str << bp.module << '!';
|
||||||
str << cdbBreakPointFileName(bp, sourcePathMapping) << ':' << bp.lineNumber << '`';
|
str << cdbBreakPointFileName(bp, sourcePathMapping) << ':' << bp.lineNumber << '`';
|
||||||
break;
|
break;
|
||||||
case Watchpoint: { // Read/write, no space here
|
case WatchpointAtAddress: { // Read/write, no space here
|
||||||
const unsigned size = bp.size ? bp.size : 1;
|
const unsigned size = bp.size ? bp.size : 1;
|
||||||
str << "r" << size << ' ' << hex << hexPrefixOn << bp.address << hexPrefixOff << dec;
|
str << "r" << size << ' ' << hex << hexPrefixOn << bp.address << hexPrefixOff << dec;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,9 +147,10 @@ enum DebuggerCapabilities
|
|||||||
ReturnFromFunctionCapability = 0x2000,
|
ReturnFromFunctionCapability = 0x2000,
|
||||||
CreateFullBacktraceCapability = 0x4000,
|
CreateFullBacktraceCapability = 0x4000,
|
||||||
AddWatcherCapability = 0x8000,
|
AddWatcherCapability = 0x8000,
|
||||||
WatchpointCapability = 0x10000,
|
WatchpointByAddressCapability = 0x10000,
|
||||||
ShowModuleSymbolsCapability = 0x20000,
|
WatchpointByExpressionCapability = 0x20000,
|
||||||
CatchCapability = 0x40000, //!< fork, vfork, syscall
|
ShowModuleSymbolsCapability = 0x40000,
|
||||||
|
CatchCapability = 0x80000, //!< fork, vfork, syscall
|
||||||
AllDebuggerCapabilities = 0xFFFFFFFF
|
AllDebuggerCapabilities = 0xFFFFFFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1488,7 +1488,27 @@ bool DebuggerEngine::isDying() const
|
|||||||
return targetState() == DebuggerFinished;
|
return targetState() == DebuggerFinished;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DebuggerEngine::msgWatchpointTriggered(BreakpointId id,
|
QString DebuggerEngine::msgWatchpointByExpressionTriggered(BreakpointId id,
|
||||||
|
const int number, const QByteArray &expr)
|
||||||
|
{
|
||||||
|
return id
|
||||||
|
? tr("Watchpoint %1 (%2) at %3 %4 triggered.")
|
||||||
|
.arg(id).arg(number).arg(_(expr))
|
||||||
|
: tr("Internal watchpoint %1 at %2 %4 triggered.")
|
||||||
|
.arg(number).arg(_(expr));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DebuggerEngine::msgWatchpointByExpressionTriggered(BreakpointId id,
|
||||||
|
const int number, const QByteArray &expr, const QString &threadId)
|
||||||
|
{
|
||||||
|
return id
|
||||||
|
? tr("Watchpoint %1 (%2) at %3 in thread %4 triggered.")
|
||||||
|
.arg(id).arg(number).arg(_(expr)).arg(threadId)
|
||||||
|
: tr("Internal watchpoint %1 at %2 in thread %4 triggered.")
|
||||||
|
.arg(number).arg(_(expr)).arg(threadId);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DebuggerEngine::msgWatchpointByAddressTriggered(BreakpointId id,
|
||||||
const int number, quint64 address)
|
const int number, quint64 address)
|
||||||
{
|
{
|
||||||
return id
|
return id
|
||||||
@@ -1498,7 +1518,7 @@ QString DebuggerEngine::msgWatchpointTriggered(BreakpointId id,
|
|||||||
.arg(number).arg(address, 0, 16);
|
.arg(number).arg(address, 0, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DebuggerEngine::msgWatchpointTriggered(BreakpointId id,
|
QString DebuggerEngine::msgWatchpointByAddressTriggered(BreakpointId id,
|
||||||
const int number, quint64 address, const QString &threadId)
|
const int number, quint64 address, const QString &threadId)
|
||||||
{
|
{
|
||||||
return id
|
return id
|
||||||
|
|||||||
@@ -359,10 +359,14 @@ protected:
|
|||||||
|
|
||||||
DebuggerRunControl *runControl() const;
|
DebuggerRunControl *runControl() const;
|
||||||
|
|
||||||
static QString msgWatchpointTriggered(BreakpointId id,
|
static QString msgWatchpointByAddressTriggered(BreakpointId id,
|
||||||
int number, quint64 address);
|
int number, quint64 address);
|
||||||
static QString msgWatchpointTriggered(BreakpointId id,
|
static QString msgWatchpointByAddressTriggered(BreakpointId id,
|
||||||
int number, quint64 address, const QString &threadId);
|
int number, quint64 address, const QString &threadId);
|
||||||
|
static QString msgWatchpointByExpressionTriggered(BreakpointId id,
|
||||||
|
int number, const QByteArray &expr);
|
||||||
|
static QString msgWatchpointByExpressionTriggered(BreakpointId id,
|
||||||
|
int number, const QByteArray &expr, const QString &threadId);
|
||||||
static QString msgBreakpointTriggered(BreakpointId id,
|
static QString msgBreakpointTriggered(BreakpointId id,
|
||||||
int number, const QString &threadId);
|
int number, const QString &threadId);
|
||||||
static QString msgStopped(const QString &reason = QString());
|
static QString msgStopped(const QString &reason = QString());
|
||||||
|
|||||||
@@ -1499,7 +1499,11 @@ void GdbEngine::handleStop1(const GdbMi &data)
|
|||||||
const int bpNumber = wpt.findChild("number").data().toInt();
|
const int bpNumber = wpt.findChild("number").data().toInt();
|
||||||
const BreakpointId id = breakHandler()->findBreakpointByNumber(bpNumber);
|
const BreakpointId id = breakHandler()->findBreakpointByNumber(bpNumber);
|
||||||
const quint64 bpAddress = wpt.findChild("exp").data().mid(1).toULongLong(0, 0);
|
const quint64 bpAddress = wpt.findChild("exp").data().mid(1).toULongLong(0, 0);
|
||||||
QString msg = msgWatchpointTriggered(id, bpNumber, bpAddress);
|
QString msg;
|
||||||
|
if (id && breakHandler()->type(id) == WatchpointAtExpression)
|
||||||
|
msg = msgWatchpointByExpressionTriggered(id, bpNumber, breakHandler()->expression(id));
|
||||||
|
if (id && breakHandler()->type(id) == WatchpointAtAddress)
|
||||||
|
msg = msgWatchpointByAddressTriggered(id, bpNumber, bpAddress);
|
||||||
GdbMi value = data.findChild("value");
|
GdbMi value = data.findChild("value");
|
||||||
GdbMi oldValue = value.findChild("old");
|
GdbMi oldValue = value.findChild("old");
|
||||||
GdbMi newValue = value.findChild("new");
|
GdbMi newValue = value.findChild("new");
|
||||||
@@ -1882,7 +1886,8 @@ unsigned GdbEngine::debuggerCapabilities() const
|
|||||||
| TracePointCapability
|
| TracePointCapability
|
||||||
| ReturnFromFunctionCapability
|
| ReturnFromFunctionCapability
|
||||||
| CreateFullBacktraceCapability
|
| CreateFullBacktraceCapability
|
||||||
| WatchpointCapability
|
| WatchpointByAddressCapability
|
||||||
|
| WatchpointByExpressionCapability
|
||||||
| AddWatcherCapability
|
| AddWatcherCapability
|
||||||
| ShowModuleSymbolsCapability
|
| ShowModuleSymbolsCapability
|
||||||
| CatchCapability;
|
| CatchCapability;
|
||||||
@@ -2229,7 +2234,7 @@ void GdbEngine::updateBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkp
|
|||||||
if (child.data().contains("tracepoint"))
|
if (child.data().contains("tracepoint"))
|
||||||
response.tracepoint = true;
|
response.tracepoint = true;
|
||||||
else if (!child.data().contains("reakpoint"))
|
else if (!child.data().contains("reakpoint"))
|
||||||
response.type = Watchpoint;
|
response.type = WatchpointAtAddress;
|
||||||
}
|
}
|
||||||
// This field is not present. Contents needs to be parsed from
|
// This field is not present. Contents needs to be parsed from
|
||||||
// the plain "ignore" response.
|
// the plain "ignore" response.
|
||||||
@@ -2692,12 +2697,18 @@ void GdbEngine::insertBreakpoint(BreakpointId id)
|
|||||||
QTC_ASSERT(handler->state(id) == BreakpointInsertRequested, /**/);
|
QTC_ASSERT(handler->state(id) == BreakpointInsertRequested, /**/);
|
||||||
handler->notifyBreakpointInsertProceeding(id);
|
handler->notifyBreakpointInsertProceeding(id);
|
||||||
BreakpointType type = handler->type(id);
|
BreakpointType type = handler->type(id);
|
||||||
if (type == Watchpoint) {
|
if (type == WatchpointAtAddress) {
|
||||||
postCommand("watch " + addressSpec(handler->address(id)),
|
postCommand("watch " + addressSpec(handler->address(id)),
|
||||||
NeedsStop | RebuildBreakpointModel,
|
NeedsStop | RebuildBreakpointModel,
|
||||||
CB(handleWatchInsert), id);
|
CB(handleWatchInsert), id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (type == WatchpointAtExpression) {
|
||||||
|
postCommand("watch " + handler->expression(id),
|
||||||
|
NeedsStop | RebuildBreakpointModel,
|
||||||
|
CB(handleWatchInsert), id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (type == BreakpointAtFork) {
|
if (type == BreakpointAtFork) {
|
||||||
postCommand("catch fork", NeedsStop | RebuildBreakpointModel,
|
postCommand("catch fork", NeedsStop | RebuildBreakpointModel,
|
||||||
CB(handleCatchInsert), id);
|
CB(handleCatchInsert), id);
|
||||||
|
|||||||
@@ -742,7 +742,7 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
|
|||||||
return QVariant(quint64(0));
|
return QVariant(quint64(0));
|
||||||
|
|
||||||
case LocalsIsWatchpointAtAddressRole: {
|
case LocalsIsWatchpointAtAddressRole: {
|
||||||
BreakpointParameters bp(Watchpoint);
|
BreakpointParameters bp(WatchpointAtAddress);
|
||||||
bp.address = data.coreAddress();
|
bp.address = data.coreAddress();
|
||||||
return engine()->breakHandler()->findWatchpoint(bp) != 0;
|
return engine()->breakHandler()->findWatchpoint(bp) != 0;
|
||||||
}
|
}
|
||||||
@@ -756,7 +756,7 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
|
|||||||
|
|
||||||
case LocalsIsWatchpointAtPointerValueRole:
|
case LocalsIsWatchpointAtPointerValueRole:
|
||||||
if (isPointerType(data.type)) {
|
if (isPointerType(data.type)) {
|
||||||
BreakpointParameters bp(Watchpoint);
|
BreakpointParameters bp(WatchpointAtAddress);
|
||||||
bp.address = pointerValue(data.value);
|
bp.address = pointerValue(data.value);
|
||||||
return engine()->breakHandler()->findWatchpoint(bp) != 0;
|
return engine()->breakHandler()->findWatchpoint(bp) != 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -701,7 +701,7 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
|
|||||||
|
|
||||||
QAction *actSetWatchpointAtVariableAddress = 0;
|
QAction *actSetWatchpointAtVariableAddress = 0;
|
||||||
QAction *actSetWatchpointAtPointerValue = 0;
|
QAction *actSetWatchpointAtPointerValue = 0;
|
||||||
const bool canSetWatchpoint = engineCapabilities & WatchpointCapability;
|
const bool canSetWatchpoint = engineCapabilities & WatchpointByAddressCapability;
|
||||||
if (canSetWatchpoint && address) {
|
if (canSetWatchpoint && address) {
|
||||||
actSetWatchpointAtVariableAddress =
|
actSetWatchpointAtVariableAddress =
|
||||||
new QAction(tr("Add Watchpoint at Object's Address (0x%1)")
|
new QAction(tr("Add Watchpoint at Object's Address (0x%1)")
|
||||||
@@ -1015,7 +1015,7 @@ void WatchWindow::setModelData
|
|||||||
|
|
||||||
void WatchWindow::setWatchpoint(quint64 address, unsigned size)
|
void WatchWindow::setWatchpoint(quint64 address, unsigned size)
|
||||||
{
|
{
|
||||||
BreakpointParameters data(Watchpoint);
|
BreakpointParameters data(WatchpointAtAddress);
|
||||||
data.address = address;
|
data.address = address;
|
||||||
data.size = size;
|
data.size = size;
|
||||||
BreakpointId id = breakHandler()->findWatchpoint(data);
|
BreakpointId id = breakHandler()->findWatchpoint(data);
|
||||||
|
|||||||
@@ -2556,6 +2556,10 @@ void testMPI()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum E {
|
||||||
|
ONE = 6
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int *x = new int(32);
|
int *x = new int(32);
|
||||||
|
|||||||
Reference in New Issue
Block a user