forked from qt-creator/qt-creator
debugger: work on watchpoints (or, "data breakpoints" as they are called now)
This commit is contained in:
@@ -287,6 +287,7 @@ BreakpointId BreakHandler::findWatchpoint(const BreakpointParameters &data) cons
|
|||||||
if (it->data.isWatchpoint()
|
if (it->data.isWatchpoint()
|
||||||
&& it->data.address == data.address
|
&& it->data.address == data.address
|
||||||
&& it->data.size == data.size
|
&& it->data.size == data.size
|
||||||
|
&& it->data.expression == data.expression
|
||||||
&& it->data.bitpos == data.bitpos)
|
&& it->data.bitpos == data.bitpos)
|
||||||
return it.key();
|
return it.key();
|
||||||
return BreakpointId();
|
return BreakpointId();
|
||||||
@@ -520,7 +521,9 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
|
|||||||
|| data.type == BreakpointAtSysCall)
|
|| data.type == BreakpointAtSysCall)
|
||||||
return typeToString(data.type);
|
return typeToString(data.type);
|
||||||
if (data.type == WatchpointAtAddress)
|
if (data.type == WatchpointAtAddress)
|
||||||
return tr("Watchpoint at 0x%1").arg(data.address, 0, 16);
|
return tr("Data breakpoint at 0x%1").arg(data.address, 0, 16);
|
||||||
|
if (data.type == WatchpointAtExpression)
|
||||||
|
return tr("Data breakpoint at %1").arg(data.expression);
|
||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -650,7 +653,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(QString, expression, setExpression)
|
||||||
PROPERTY(int, ignoreCount, setIgnoreCount)
|
PROPERTY(int, ignoreCount, setIgnoreCount)
|
||||||
|
|
||||||
bool BreakHandler::isEnabled(BreakpointId id) const
|
bool BreakHandler::isEnabled(BreakpointId id) const
|
||||||
@@ -1207,6 +1210,8 @@ QIcon BreakHandler::BreakpointItem::icon() const
|
|||||||
return BreakHandler::tracepointIcon();
|
return BreakHandler::tracepointIcon();
|
||||||
if (data.type == WatchpointAtAddress)
|
if (data.type == WatchpointAtAddress)
|
||||||
return BreakHandler::watchpointIcon();
|
return BreakHandler::watchpointIcon();
|
||||||
|
if (data.type == WatchpointAtExpression)
|
||||||
|
return BreakHandler::watchpointIcon();
|
||||||
if (!data.enabled)
|
if (!data.enabled)
|
||||||
return BreakHandler::disabledBreakpointIcon();
|
return BreakHandler::disabledBreakpointIcon();
|
||||||
if (state == BreakpointInserted)
|
if (state == BreakpointInserted)
|
||||||
|
@@ -115,8 +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;
|
QString expression(BreakpointId id) const;
|
||||||
void setExpression(BreakpointId, const QByteArray &expression);
|
void setExpression(BreakpointId, const QString &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;
|
||||||
|
@@ -144,7 +144,7 @@ public:
|
|||||||
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 address based watchpoints.
|
quint64 address; //!< Address for address based watchpoints.
|
||||||
QByteArray expression; //!< Address for expression based watchpoints.
|
QString expression; //!< Expression 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.
|
||||||
|
@@ -111,15 +111,15 @@ BreakpointDialog::BreakpointDialog(unsigned engineCapabilities, QWidget *parent)
|
|||||||
QStringList types;
|
QStringList types;
|
||||||
types << tr("File name and line number")
|
types << tr("File name and line number")
|
||||||
<< tr("Function name")
|
<< tr("Function name")
|
||||||
<< tr("Memory address")
|
<< tr("Break on memory 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 at address)")
|
<< tr("Break on data access at fixed address)")
|
||||||
<< tr("Break on data access (Watchpoint at expression)");
|
<< tr("Break on data access at address given by expression)");
|
||||||
QTC_ASSERT(types.size() == WatchpointAtExpression, return; )
|
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);
|
||||||
|
@@ -1489,32 +1489,32 @@ bool DebuggerEngine::isDying() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString DebuggerEngine::msgWatchpointByExpressionTriggered(BreakpointId id,
|
QString DebuggerEngine::msgWatchpointByExpressionTriggered(BreakpointId id,
|
||||||
const int number, const QByteArray &expr)
|
const int number, const QString &expr)
|
||||||
{
|
{
|
||||||
return id
|
return id
|
||||||
? tr("Watchpoint %1 (%2) at %3 %4 triggered.")
|
? tr("Data breakpoint %1 (%2) at %3 triggered.")
|
||||||
.arg(id).arg(number).arg(_(expr))
|
.arg(id).arg(number).arg(expr)
|
||||||
: tr("Internal watchpoint %1 at %2 %4 triggered.")
|
: tr("Internal data breakpoint %1 at %2 triggered.")
|
||||||
.arg(number).arg(_(expr));
|
.arg(number).arg(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DebuggerEngine::msgWatchpointByExpressionTriggered(BreakpointId id,
|
QString DebuggerEngine::msgWatchpointByExpressionTriggered(BreakpointId id,
|
||||||
const int number, const QByteArray &expr, const QString &threadId)
|
const int number, const QString &expr, const QString &threadId)
|
||||||
{
|
{
|
||||||
return id
|
return id
|
||||||
? tr("Watchpoint %1 (%2) at %3 in thread %4 triggered.")
|
? tr("Data breakpoint %1 (%2) at %3 in thread %4 triggered.")
|
||||||
.arg(id).arg(number).arg(_(expr)).arg(threadId)
|
.arg(id).arg(number).arg(expr).arg(threadId)
|
||||||
: tr("Internal watchpoint %1 at %2 in thread %4 triggered.")
|
: tr("Internal data breakpoint %1 at %2 in thread %4 triggered.")
|
||||||
.arg(number).arg(_(expr)).arg(threadId);
|
.arg(number).arg(expr).arg(threadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DebuggerEngine::msgWatchpointByAddressTriggered(BreakpointId id,
|
QString DebuggerEngine::msgWatchpointByAddressTriggered(BreakpointId id,
|
||||||
const int number, quint64 address)
|
const int number, quint64 address)
|
||||||
{
|
{
|
||||||
return id
|
return id
|
||||||
? tr("Watchpoint %1 (%2) at 0x%3 triggered.")
|
? tr("Data breakpoint %1 (%2) at 0x%3 triggered.")
|
||||||
.arg(id).arg(number).arg(address, 0, 16)
|
.arg(id).arg(number).arg(address, 0, 16)
|
||||||
: tr("Internal watchpoint %1 at 0x%2 triggered.")
|
: tr("Internal data breakpoint %1 at 0x%2 triggered.")
|
||||||
.arg(number).arg(address, 0, 16);
|
.arg(number).arg(address, 0, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1522,9 +1522,9 @@ 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
|
||||||
? tr("Watchpoint %1 (%2) at 0x%3 in thread %4 triggered.")
|
? tr("Data breakpoint %1 (%2) at 0x%3 in thread %4 triggered.")
|
||||||
.arg(id).arg(number).arg(address, 0, 16).arg(threadId)
|
.arg(id).arg(number).arg(address, 0, 16).arg(threadId)
|
||||||
: tr("Internal watchpoint %1 at 0x%2 in thread %3 triggered.")
|
: tr("Internal data breakpoint %1 at 0x%2 in thread %3 triggered.")
|
||||||
.arg(id).arg(number).arg(address, 0, 16).arg(threadId);
|
.arg(id).arg(number).arg(address, 0, 16).arg(threadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -364,9 +364,9 @@ protected:
|
|||||||
static QString msgWatchpointByAddressTriggered(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,
|
static QString msgWatchpointByExpressionTriggered(BreakpointId id,
|
||||||
int number, const QByteArray &expr);
|
int number, const QString &expr);
|
||||||
static QString msgWatchpointByExpressionTriggered(BreakpointId id,
|
static QString msgWatchpointByExpressionTriggered(BreakpointId id,
|
||||||
int number, const QByteArray &expr, const QString &threadId);
|
int number, const QString &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());
|
||||||
|
@@ -83,6 +83,7 @@ enum ModelRoles
|
|||||||
LocalsINameRole,
|
LocalsINameRole,
|
||||||
LocalsEditTypeRole, // A QVariant::type describing the item
|
LocalsEditTypeRole, // A QVariant::type describing the item
|
||||||
LocalsIntegerBaseRole, // Number base 16, 10, 8, 2
|
LocalsIntegerBaseRole, // Number base 16, 10, 8, 2
|
||||||
|
LocalsNameRole,
|
||||||
LocalsExpressionRole,
|
LocalsExpressionRole,
|
||||||
LocalsRawExpressionRole,
|
LocalsRawExpressionRole,
|
||||||
LocalsExpandedRole, // The preferred expanded state to the view
|
LocalsExpandedRole, // The preferred expanded state to the view
|
||||||
|
@@ -2706,7 +2706,7 @@ void GdbEngine::insertBreakpoint(BreakpointId id)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (type == WatchpointAtExpression) {
|
if (type == WatchpointAtExpression) {
|
||||||
postCommand("watch " + handler->expression(id),
|
postCommand("watch " + handler->expression(id).toLocal8Bit(),
|
||||||
NeedsStop | RebuildBreakpointModel,
|
NeedsStop | RebuildBreakpointModel,
|
||||||
CB(handleWatchInsert), id);
|
CB(handleWatchInsert), id);
|
||||||
return;
|
return;
|
||||||
|
@@ -605,6 +605,9 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
|
|||||||
case LocalsEditTypeRole:
|
case LocalsEditTypeRole:
|
||||||
return QVariant(editType(data));
|
return QVariant(editType(data));
|
||||||
|
|
||||||
|
case LocalsNameRole:
|
||||||
|
return QVariant(data.name);
|
||||||
|
|
||||||
case LocalsIntegerBaseRole:
|
case LocalsIntegerBaseRole:
|
||||||
if (isPointerType(data.type)) // Pointers using 0x-convention
|
if (isPointerType(data.type)) // Pointers using 0x-convention
|
||||||
return QVariant(16);
|
return QVariant(16);
|
||||||
|
@@ -467,7 +467,7 @@ WatchWindow::WatchWindow(Type type, QWidget *parent)
|
|||||||
|
|
||||||
setFrameStyle(QFrame::NoFrame);
|
setFrameStyle(QFrame::NoFrame);
|
||||||
setAttribute(Qt::WA_MacShowFocusRect, false);
|
setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||||
setWindowTitle(tr("Locals and Watchers"));
|
setWindowTitle(tr("Locals and Expressions"));
|
||||||
setIndentation(indentation() * 9/10);
|
setIndentation(indentation() * 9/10);
|
||||||
setUniformRowHeights(true);
|
setUniformRowHeights(true);
|
||||||
setItemDelegate(new WatchDelegate(this));
|
setItemDelegate(new WatchDelegate(this));
|
||||||
@@ -562,24 +562,24 @@ void WatchWindow::mouseDoubleClickEvent(QMouseEvent *ev)
|
|||||||
static inline QString addWatchActionText(QString exp)
|
static inline QString addWatchActionText(QString exp)
|
||||||
{
|
{
|
||||||
if (exp.isEmpty())
|
if (exp.isEmpty())
|
||||||
return WatchWindow::tr("Watch Expression");
|
return WatchWindow::tr("Evaluate Expression");
|
||||||
if (exp.size() > 30) {
|
if (exp.size() > 30) {
|
||||||
exp.truncate(30);
|
exp.truncate(30);
|
||||||
exp.append(QLatin1String("..."));
|
exp.append(QLatin1String("..."));
|
||||||
}
|
}
|
||||||
return WatchWindow::tr("Watch Expression \"%1\"").arg(exp);
|
return WatchWindow::tr("Evaluate Expression \"%1\"").arg(exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text for add watch action with truncated expression
|
// Text for add watch action with truncated expression
|
||||||
static inline QString removeWatchActionText(QString exp)
|
static inline QString removeWatchActionText(QString exp)
|
||||||
{
|
{
|
||||||
if (exp.isEmpty())
|
if (exp.isEmpty())
|
||||||
return WatchWindow::tr("Remove Watch Expression");
|
return WatchWindow::tr("Remove Evaluated Expression");
|
||||||
if (exp.size() > 30) {
|
if (exp.size() > 30) {
|
||||||
exp.truncate(30);
|
exp.truncate(30);
|
||||||
exp.append(QLatin1String("..."));
|
exp.append(QLatin1String("..."));
|
||||||
}
|
}
|
||||||
return WatchWindow::tr("Remove Watch Expression \"%1\"").arg(exp);
|
return WatchWindow::tr("Remove Evaluated Expression \"%1\"").arg(exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void copyToClipboard(const QString &clipboardText)
|
static inline void copyToClipboard(const QString &clipboardText)
|
||||||
@@ -604,8 +604,12 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
|
|||||||
const uint size = sizeOf(mi0);
|
const uint size = sizeOf(mi0);
|
||||||
const quint64 pointerValue = pointerValueOf(mi0);
|
const quint64 pointerValue = pointerValueOf(mi0);
|
||||||
const QString exp = mi0.data(LocalsExpressionRole).toString();
|
const QString exp = mi0.data(LocalsExpressionRole).toString();
|
||||||
|
const QString name = mi0.data(LocalsNameRole).toString();
|
||||||
const QString type = mi2.data().toString();
|
const QString type = mi2.data().toString();
|
||||||
|
|
||||||
|
// Offer to open address pointed to or variable address.
|
||||||
|
const bool createPointerActions = pointerValue && pointerValue != address;
|
||||||
|
|
||||||
const QStringList alternativeFormats =
|
const QStringList alternativeFormats =
|
||||||
mi0.data(LocalsTypeFormatListRole).toStringList();
|
mi0.data(LocalsTypeFormatListRole).toStringList();
|
||||||
const int typeFormat =
|
const int typeFormat =
|
||||||
@@ -686,44 +690,57 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
|
|||||||
const unsigned engineCapabilities = engine->debuggerCapabilities();
|
const unsigned engineCapabilities = engine->debuggerCapabilities();
|
||||||
const bool canHandleWatches = engineCapabilities & AddWatcherCapability;
|
const bool canHandleWatches = engineCapabilities & AddWatcherCapability;
|
||||||
const DebuggerState state = engine->state();
|
const DebuggerState state = engine->state();
|
||||||
const bool canInsertWatches = (state==InferiorStopOk) || ((state==InferiorRunOk) && engine->acceptsWatchesWhileRunning());
|
const bool canInsertWatches = state == InferiorStopOk
|
||||||
|
|| (state == InferiorRunOk && engine->acceptsWatchesWhileRunning());
|
||||||
QMenu menu;
|
|
||||||
QAction *actInsertNewWatchItem = menu.addAction(tr("Insert New Watch Item"));
|
|
||||||
actInsertNewWatchItem->setEnabled(canHandleWatches && canInsertWatches);
|
|
||||||
QAction *actSelectWidgetToWatch = menu.addAction(tr("Select Widget to Watch"));
|
|
||||||
actSelectWidgetToWatch->setEnabled(canHandleWatches && (engine->canWatchWidgets()));
|
|
||||||
|
|
||||||
// Offer to open address pointed to or variable address.
|
|
||||||
const bool createPointerActions = pointerValue && pointerValue != address;
|
|
||||||
|
|
||||||
menu.addSeparator();
|
|
||||||
|
|
||||||
|
QMenu breakpointMenu;
|
||||||
|
breakpointMenu.setTitle(tr("Add Data Breakpoint..."));
|
||||||
QAction *actSetWatchpointAtVariableAddress = 0;
|
QAction *actSetWatchpointAtVariableAddress = 0;
|
||||||
QAction *actSetWatchpointAtPointerValue = 0;
|
QAction *actSetWatchpointAtPointerValue = 0;
|
||||||
const bool canSetWatchpoint = engineCapabilities & WatchpointByAddressCapability;
|
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 Data Breakpoint at Object's Address (0x%1)")
|
||||||
.arg(address, 0, 16), &menu);
|
.arg(address, 0, 16), &breakpointMenu);
|
||||||
actSetWatchpointAtVariableAddress->
|
actSetWatchpointAtVariableAddress->
|
||||||
setChecked(mi0.data(LocalsIsWatchpointAtAddressRole).toBool());
|
setChecked(mi0.data(LocalsIsWatchpointAtAddressRole).toBool());
|
||||||
if (createPointerActions) {
|
if (createPointerActions) {
|
||||||
actSetWatchpointAtPointerValue =
|
actSetWatchpointAtPointerValue =
|
||||||
new QAction(tr("Add Watchpoint at Referenced Address (0x%1)")
|
new QAction(tr("Add Data Breakpoint at Referenced Address (0x%1)")
|
||||||
.arg(pointerValue, 0, 16), &menu);
|
.arg(pointerValue, 0, 16), &breakpointMenu);
|
||||||
actSetWatchpointAtPointerValue->setCheckable(true);
|
actSetWatchpointAtPointerValue->setCheckable(true);
|
||||||
actSetWatchpointAtPointerValue->
|
actSetWatchpointAtPointerValue->
|
||||||
setChecked(mi0.data(LocalsIsWatchpointAtPointerValueRole).toBool());
|
setChecked(mi0.data(LocalsIsWatchpointAtPointerValueRole).toBool());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
actSetWatchpointAtVariableAddress =
|
actSetWatchpointAtVariableAddress =
|
||||||
new QAction(tr("Add Watchpoint"), &menu);
|
new QAction(tr("Add Data Breakpoint"), &breakpointMenu);
|
||||||
actSetWatchpointAtVariableAddress->setEnabled(false);
|
actSetWatchpointAtVariableAddress->setEnabled(false);
|
||||||
}
|
}
|
||||||
actSetWatchpointAtVariableAddress->setToolTip(
|
actSetWatchpointAtVariableAddress->setToolTip(
|
||||||
tr("Setting a watchpoint on an address will cause the program "
|
tr("Setting a data breakpoint on an address will cause the program "
|
||||||
"to stop when the data at the address it modified."));
|
"to stop when the data at the address is modified."));
|
||||||
|
|
||||||
|
QAction *actSetWatchpointAtExpression =
|
||||||
|
new QAction(tr("Add Data Breakpoint at Expression \"%1\"").arg(name),
|
||||||
|
&breakpointMenu);
|
||||||
|
actSetWatchpointAtExpression->setToolTip(
|
||||||
|
tr("Setting a data breakpoint on an expression will cause the program "
|
||||||
|
"to stop when the data at the address given by the expression "
|
||||||
|
"is modified."));
|
||||||
|
|
||||||
|
breakpointMenu.addAction(actSetWatchpointAtVariableAddress);
|
||||||
|
if (actSetWatchpointAtPointerValue)
|
||||||
|
breakpointMenu.addAction(actSetWatchpointAtPointerValue);
|
||||||
|
breakpointMenu.addAction(actSetWatchpointAtExpression);
|
||||||
|
|
||||||
|
QMenu menu;
|
||||||
|
QAction *actInsertNewWatchItem = menu.addAction(tr("Insert New Evaluated Expression"));
|
||||||
|
actInsertNewWatchItem->setEnabled(canHandleWatches && canInsertWatches);
|
||||||
|
QAction *actSelectWidgetToWatch = menu.addAction(tr("Select Widget to Watch"));
|
||||||
|
actSelectWidgetToWatch->setEnabled(canHandleWatches && (engine->canWatchWidgets()));
|
||||||
|
|
||||||
|
menu.addSeparator();
|
||||||
|
|
||||||
QAction *actWatchExpression = new QAction(addWatchActionText(exp), &menu);
|
QAction *actWatchExpression = new QAction(addWatchActionText(exp), &menu);
|
||||||
actWatchExpression->setEnabled(canHandleWatches && !exp.isEmpty());
|
actWatchExpression->setEnabled(canHandleWatches && !exp.isEmpty());
|
||||||
@@ -803,9 +820,7 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
|
|||||||
menu.addAction(actSelectWidgetToWatch);
|
menu.addAction(actSelectWidgetToWatch);
|
||||||
menu.addMenu(&formatMenu);
|
menu.addMenu(&formatMenu);
|
||||||
menu.addMenu(&memoryMenu);
|
menu.addMenu(&memoryMenu);
|
||||||
menu.addAction(actSetWatchpointAtVariableAddress);
|
menu.addMenu(&breakpointMenu);
|
||||||
if (actSetWatchpointAtPointerValue)
|
|
||||||
menu.addAction(actSetWatchpointAtPointerValue);
|
|
||||||
menu.addAction(actCopy);
|
menu.addAction(actCopy);
|
||||||
menu.addAction(actCopyValue);
|
menu.addAction(actCopyValue);
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
@@ -868,9 +883,11 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
|
|||||||
} else if (act == actOpenMemoryEditorStackLayout) {
|
} else if (act == actOpenMemoryEditorStackLayout) {
|
||||||
addStackLayoutMemoryView(currentEngine(), false, mi0.model(), ev->globalPos(), this);
|
addStackLayoutMemoryView(currentEngine(), false, mi0.model(), ev->globalPos(), this);
|
||||||
} else if (act == actSetWatchpointAtVariableAddress) {
|
} else if (act == actSetWatchpointAtVariableAddress) {
|
||||||
setWatchpoint(address, size);
|
setWatchpointAtAddress(address, size);
|
||||||
} else if (act == actSetWatchpointAtPointerValue) {
|
} else if (act == actSetWatchpointAtPointerValue) {
|
||||||
setWatchpoint(pointerValue, 1);
|
setWatchpointAtAddress(pointerValue, sizeof(void *)); // FIXME: an approximation..
|
||||||
|
} else if (act == actSetWatchpointAtExpression) {
|
||||||
|
setWatchpointAtExpression(name);
|
||||||
} else if (act == actSelectWidgetToWatch) {
|
} else if (act == actSelectWidgetToWatch) {
|
||||||
grabMouse(Qt::CrossCursor);
|
grabMouse(Qt::CrossCursor);
|
||||||
m_grabbing = true;
|
m_grabbing = true;
|
||||||
@@ -1013,7 +1030,7 @@ void WatchWindow::setModelData
|
|||||||
model()->setData(index, value, role);
|
model()->setData(index, value, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchWindow::setWatchpoint(quint64 address, unsigned size)
|
void WatchWindow::setWatchpointAtAddress(quint64 address, unsigned size)
|
||||||
{
|
{
|
||||||
BreakpointParameters data(WatchpointAtAddress);
|
BreakpointParameters data(WatchpointAtAddress);
|
||||||
data.address = address;
|
data.address = address;
|
||||||
@@ -1027,6 +1044,19 @@ void WatchWindow::setWatchpoint(quint64 address, unsigned size)
|
|||||||
breakHandler()->appendBreakpoint(data);
|
breakHandler()->appendBreakpoint(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WatchWindow::setWatchpointAtExpression(const QString &exp)
|
||||||
|
{
|
||||||
|
BreakpointParameters data(WatchpointAtExpression);
|
||||||
|
data.expression = exp;
|
||||||
|
BreakpointId id = breakHandler()->findWatchpoint(data);
|
||||||
|
if (id) {
|
||||||
|
qDebug() << "WATCHPOINT EXISTS";
|
||||||
|
// removeBreakpoint(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
breakHandler()->appendBreakpoint(data);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|
||||||
|
@@ -78,7 +78,8 @@ private:
|
|||||||
|
|
||||||
void editItem(const QModelIndex &idx);
|
void editItem(const QModelIndex &idx);
|
||||||
void resetHelper(const QModelIndex &idx);
|
void resetHelper(const QModelIndex &idx);
|
||||||
void setWatchpoint(quint64 address, unsigned size);
|
void setWatchpointAtAddress(quint64 address, unsigned size);
|
||||||
|
void setWatchpointAtExpression(const QString &exp);
|
||||||
|
|
||||||
void setModelData(int role, const QVariant &value = QVariant(),
|
void setModelData(int role, const QVariant &value = QVariant(),
|
||||||
const QModelIndex &index = QModelIndex());
|
const QModelIndex &index = QModelIndex());
|
||||||
|
Reference in New Issue
Block a user