Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Tobias Hunger
qt-creator
Commits
e8496ca3
Commit
e8496ca3
authored
May 10, 2011
by
hjk
Browse files
debugger: work on watchpoints (or, "data breakpoints" as they are called now)
parent
6331b689
Changes
11
Hide whitespace changes
Inline
Side-by-side
src/plugins/debugger/breakhandler.cpp
View file @
e8496ca3
...
...
@@ -287,6 +287,7 @@ BreakpointId BreakHandler::findWatchpoint(const BreakpointParameters &data) cons
if
(
it
->
data
.
isWatchpoint
()
&&
it
->
data
.
address
==
data
.
address
&&
it
->
data
.
size
==
data
.
size
&&
it
->
data
.
expression
==
data
.
expression
&&
it
->
data
.
bitpos
==
data
.
bitpos
)
return
it
.
key
();
return
BreakpointId
();
...
...
@@ -520,7 +521,9 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
||
data
.
type
==
BreakpointAtSysCall
)
return
typeToString
(
data
.
type
);
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
;
}
break
;
...
...
@@ -650,7 +653,7 @@ PROPERTY(int, threadSpec, setThreadSpec)
PROPERTY
(
QByteArray
,
condition
,
setCondition
)
GETTER
(
int
,
lineNumber
)
PROPERTY
(
quint64
,
address
,
setAddress
)
PROPERTY
(
Q
ByteArray
,
expression
,
setExpression
)
PROPERTY
(
Q
String
,
expression
,
setExpression
)
PROPERTY
(
int
,
ignoreCount
,
setIgnoreCount
)
bool
BreakHandler
::
isEnabled
(
BreakpointId
id
)
const
...
...
@@ -1207,6 +1210,8 @@ QIcon BreakHandler::BreakpointItem::icon() const
return
BreakHandler
::
tracepointIcon
();
if
(
data
.
type
==
WatchpointAtAddress
)
return
BreakHandler
::
watchpointIcon
();
if
(
data
.
type
==
WatchpointAtExpression
)
return
BreakHandler
::
watchpointIcon
();
if
(
!
data
.
enabled
)
return
BreakHandler
::
disabledBreakpointIcon
();
if
(
state
==
BreakpointInserted
)
...
...
src/plugins/debugger/breakhandler.h
View file @
e8496ca3
...
...
@@ -115,8 +115,8 @@ public:
void
setFileName
(
BreakpointId
,
const
QString
&
fileName
);
QString
functionName
(
BreakpointId
id
)
const
;
void
setFunctionName
(
BreakpointId
,
const
QString
&
functionName
);
Q
ByteArray
expression
(
BreakpointId
id
)
const
;
void
setExpression
(
BreakpointId
,
const
Q
ByteArray
&
expression
);
Q
String
expression
(
BreakpointId
id
)
const
;
void
setExpression
(
BreakpointId
,
const
Q
String
&
expression
);
BreakpointType
type
(
BreakpointId
id
)
const
;
void
setType
(
BreakpointId
id
,
const
BreakpointType
&
type
);
quint64
address
(
BreakpointId
id
)
const
;
...
...
src/plugins/debugger/breakpoint.h
View file @
e8496ca3
...
...
@@ -144,7 +144,7 @@ public:
int
ignoreCount
;
//!< Ignore count associated with breakpoint.
int
lineNumber
;
//!< Line in source file.
quint64
address
;
//!< Address for address based watchpoints.
Q
ByteArray
expression
;
//!<
Add
ress for expression based watchpoints.
Q
String
expression
;
//!<
Exp
ress
ion
for expression based watchpoints.
uint
size
;
//!< Size of watched area for watchpoints.
uint
bitpos
;
//!< Location of watched bitfield within watched area.
uint
bitsize
;
//!< Size of watched bitfield within watched area.
...
...
src/plugins/debugger/breakwindow.cpp
View file @
e8496ca3
...
...
@@ -111,15 +111,15 @@ BreakpointDialog::BreakpointDialog(unsigned engineCapabilities, QWidget *parent)
QStringList
types
;
types
<<
tr
(
"File name and line number"
)
<<
tr
(
"Function name"
)
<<
tr
(
"
M
emory address"
)
<<
tr
(
"
Break on m
emory address"
)
<<
tr
(
"Break when C++ exception is thrown"
)
<<
tr
(
"Break when C++ exception is caught"
)
<<
tr
(
"Break when function
\"
main
\"
starts"
)
<<
tr
(
"Break when a new process is forked"
)
<<
tr
(
"Break when a new process is executed"
)
<<
tr
(
"Break when a system call is executed"
)
<<
tr
(
"Break on data access
(Watchpoint at
address)"
)
<<
tr
(
"Break on data access
(Watchpoint at
expression)"
);
<<
tr
(
"Break on data access
at fixed
address)"
)
<<
tr
(
"Break on data access
at address given by
expression)"
);
QTC_ASSERT
(
types
.
size
()
==
WatchpointAtExpression
,
return
;
)
m_ui
.
comboBoxType
->
addItems
(
types
);
m_ui
.
pathChooserFileName
->
setExpectedKind
(
Utils
::
PathChooser
::
File
);
...
...
src/plugins/debugger/debuggerengine.cpp
View file @
e8496ca3
...
...
@@ -1489,32 +1489,32 @@ bool DebuggerEngine::isDying() const
}
QString
DebuggerEngine
::
msgWatchpointByExpressionTriggered
(
BreakpointId
id
,
const
int
number
,
const
Q
ByteArray
&
expr
)
const
int
number
,
const
Q
String
&
expr
)
{
return
id
?
tr
(
"
W
at
ch
point %1 (%2) at %3
%4
triggered."
)
.
arg
(
id
).
arg
(
number
).
arg
(
_
(
expr
)
)
:
tr
(
"Internal
w
at
ch
point %1 at %2
%4
triggered."
)
.
arg
(
number
).
arg
(
_
(
expr
)
)
;
?
tr
(
"
D
at
a break
point %1 (%2) at %3 triggered."
)
.
arg
(
id
).
arg
(
number
).
arg
(
expr
)
:
tr
(
"Internal
d
at
a break
point %1 at %2 triggered."
)
.
arg
(
number
).
arg
(
expr
);
}
QString
DebuggerEngine
::
msgWatchpointByExpressionTriggered
(
BreakpointId
id
,
const
int
number
,
const
Q
ByteArray
&
expr
,
const
QString
&
threadId
)
const
int
number
,
const
Q
String
&
expr
,
const
QString
&
threadId
)
{
return
id
?
tr
(
"
W
at
ch
point %1 (%2) at %3 in thread %4 triggered."
)
.
arg
(
id
).
arg
(
number
).
arg
(
_
(
expr
)
)
.
arg
(
threadId
)
:
tr
(
"Internal
w
at
ch
point %1 at %2 in thread %4 triggered."
)
.
arg
(
number
).
arg
(
_
(
expr
)
)
.
arg
(
threadId
);
?
tr
(
"
D
at
a break
point %1 (%2) at %3 in thread %4 triggered."
)
.
arg
(
id
).
arg
(
number
).
arg
(
expr
).
arg
(
threadId
)
:
tr
(
"Internal
d
at
a break
point %1 at %2 in thread %4 triggered."
)
.
arg
(
number
).
arg
(
expr
).
arg
(
threadId
);
}
QString
DebuggerEngine
::
msgWatchpointByAddressTriggered
(
BreakpointId
id
,
const
int
number
,
quint64
address
)
{
return
id
?
tr
(
"
W
at
ch
point %1 (%2) at 0x%3 triggered."
)
?
tr
(
"
D
at
a break
point %1 (%2) at 0x%3 triggered."
)
.
arg
(
id
).
arg
(
number
).
arg
(
address
,
0
,
16
)
:
tr
(
"Internal
w
at
ch
point %1 at 0x%2 triggered."
)
:
tr
(
"Internal
d
at
a break
point %1 at 0x%2 triggered."
)
.
arg
(
number
).
arg
(
address
,
0
,
16
);
}
...
...
@@ -1522,9 +1522,9 @@ QString DebuggerEngine::msgWatchpointByAddressTriggered(BreakpointId id,
const
int
number
,
quint64
address
,
const
QString
&
threadId
)
{
return
id
?
tr
(
"
W
at
ch
point %1 (%2) at 0x%3 in thread %4 triggered."
)
?
tr
(
"
D
at
a break
point %1 (%2) at 0x%3 in thread %4 triggered."
)
.
arg
(
id
).
arg
(
number
).
arg
(
address
,
0
,
16
).
arg
(
threadId
)
:
tr
(
"Internal
w
at
ch
point %1 at 0x%2 in thread %3 triggered."
)
:
tr
(
"Internal
d
at
a break
point %1 at 0x%2 in thread %3 triggered."
)
.
arg
(
id
).
arg
(
number
).
arg
(
address
,
0
,
16
).
arg
(
threadId
);
}
...
...
src/plugins/debugger/debuggerengine.h
View file @
e8496ca3
...
...
@@ -364,9 +364,9 @@ protected:
static
QString
msgWatchpointByAddressTriggered
(
BreakpointId
id
,
int
number
,
quint64
address
,
const
QString
&
threadId
);
static
QString
msgWatchpointByExpressionTriggered
(
BreakpointId
id
,
int
number
,
const
Q
ByteArray
&
expr
);
int
number
,
const
Q
String
&
expr
);
static
QString
msgWatchpointByExpressionTriggered
(
BreakpointId
id
,
int
number
,
const
Q
ByteArray
&
expr
,
const
QString
&
threadId
);
int
number
,
const
Q
String
&
expr
,
const
QString
&
threadId
);
static
QString
msgBreakpointTriggered
(
BreakpointId
id
,
int
number
,
const
QString
&
threadId
);
static
QString
msgStopped
(
const
QString
&
reason
=
QString
());
...
...
src/plugins/debugger/debuggerinternalconstants.h
View file @
e8496ca3
...
...
@@ -83,6 +83,7 @@ enum ModelRoles
LocalsINameRole
,
LocalsEditTypeRole
,
// A QVariant::type describing the item
LocalsIntegerBaseRole
,
// Number base 16, 10, 8, 2
LocalsNameRole
,
LocalsExpressionRole
,
LocalsRawExpressionRole
,
LocalsExpandedRole
,
// The preferred expanded state to the view
...
...
src/plugins/debugger/gdb/gdbengine.cpp
View file @
e8496ca3
...
...
@@ -2706,7 +2706,7 @@ void GdbEngine::insertBreakpoint(BreakpointId id)
return
;
}
if
(
type
==
WatchpointAtExpression
)
{
postCommand
(
"watch "
+
handler
->
expression
(
id
),
postCommand
(
"watch "
+
handler
->
expression
(
id
)
.
toLocal8Bit
()
,
NeedsStop
|
RebuildBreakpointModel
,
CB
(
handleWatchInsert
),
id
);
return
;
...
...
src/plugins/debugger/watchhandler.cpp
View file @
e8496ca3
...
...
@@ -605,6 +605,9 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
case
LocalsEditTypeRole
:
return
QVariant
(
editType
(
data
));
case
LocalsNameRole
:
return
QVariant
(
data
.
name
);
case
LocalsIntegerBaseRole
:
if
(
isPointerType
(
data
.
type
))
// Pointers using 0x-convention
return
QVariant
(
16
);
...
...
src/plugins/debugger/watchwindow.cpp
View file @
e8496ca3
...
...
@@ -467,7 +467,7 @@ WatchWindow::WatchWindow(Type type, QWidget *parent)
setFrameStyle
(
QFrame
::
NoFrame
);
setAttribute
(
Qt
::
WA_MacShowFocusRect
,
false
);
setWindowTitle
(
tr
(
"Locals and
Watcher
s"
));
setWindowTitle
(
tr
(
"Locals and
Expression
s"
));
setIndentation
(
indentation
()
*
9
/
10
);
setUniformRowHeights
(
true
);
setItemDelegate
(
new
WatchDelegate
(
this
));
...
...
@@ -562,24 +562,24 @@ void WatchWindow::mouseDoubleClickEvent(QMouseEvent *ev)
static
inline
QString
addWatchActionText
(
QString
exp
)
{
if
(
exp
.
isEmpty
())
return
WatchWindow
::
tr
(
"
Watch
Expression"
);
return
WatchWindow
::
tr
(
"
Evaluate
Expression"
);
if
(
exp
.
size
()
>
30
)
{
exp
.
truncate
(
30
);
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
static
inline
QString
removeWatchActionText
(
QString
exp
)
{
if
(
exp
.
isEmpty
())
return
WatchWindow
::
tr
(
"Remove
Watch
Expression"
);
return
WatchWindow
::
tr
(
"Remove
Evaluated
Expression"
);
if
(
exp
.
size
()
>
30
)
{
exp
.
truncate
(
30
);
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
)
...
...
@@ -604,8 +604,12 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
const
uint
size
=
sizeOf
(
mi0
);
const
quint64
pointerValue
=
pointerValueOf
(
mi0
);
const
QString
exp
=
mi0
.
data
(
LocalsExpressionRole
).
toString
();
const
QString
name
=
mi0
.
data
(
LocalsNameRole
).
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
=
mi0
.
data
(
LocalsTypeFormatListRole
).
toStringList
();
const
int
typeFormat
=
...
...
@@ -686,44 +690,57 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
const
unsigned
engineCapabilities
=
engine
->
debuggerCapabilities
();
const
bool
canHandleWatches
=
engineCapabilities
&
AddWatcherCapability
;
const
DebuggerState
state
=
engine
->
state
();
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
();
const
bool
canInsertWatches
=
state
==
InferiorStopOk
||
(
state
==
InferiorRunOk
&&
engine
->
acceptsWatchesWhileRunning
());
QMenu
breakpointMenu
;
breakpointMenu
.
setTitle
(
tr
(
"Add Data Breakpoint..."
));
QAction
*
actSetWatchpointAtVariableAddress
=
0
;
QAction
*
actSetWatchpointAtPointerValue
=
0
;
const
bool
canSetWatchpoint
=
engineCapabilities
&
WatchpointByAddressCapability
;
if
(
canSetWatchpoint
&&
address
)
{
actSetWatchpointAtVariableAddress
=
new
QAction
(
tr
(
"Add
W
at
ch
point at Object's Address (0x%1)"
)
.
arg
(
address
,
0
,
16
),
&
m
enu
);
new
QAction
(
tr
(
"Add
D
at
a Break
point at Object's Address (0x%1)"
)
.
arg
(
address
,
0
,
16
),
&
breakpointM
enu
);
actSetWatchpointAtVariableAddress
->
setChecked
(
mi0
.
data
(
LocalsIsWatchpointAtAddressRole
).
toBool
());
if
(
createPointerActions
)
{
actSetWatchpointAtPointerValue
=
new
QAction
(
tr
(
"Add
W
at
ch
point at Referenced Address (0x%1)"
)
.
arg
(
pointerValue
,
0
,
16
),
&
m
enu
);
new
QAction
(
tr
(
"Add
D
at
a Break
point at Referenced Address (0x%1)"
)
.
arg
(
pointerValue
,
0
,
16
),
&
breakpointM
enu
);
actSetWatchpointAtPointerValue
->
setCheckable
(
true
);
actSetWatchpointAtPointerValue
->
setChecked
(
mi0
.
data
(
LocalsIsWatchpointAtPointerValueRole
).
toBool
());
}
}
else
{
actSetWatchpointAtVariableAddress
=
new
QAction
(
tr
(
"Add
W
at
ch
point"
),
&
m
enu
);
new
QAction
(
tr
(
"Add
D
at
a Break
point"
),
&
breakpointM
enu
);
actSetWatchpointAtVariableAddress
->
setEnabled
(
false
);
}
actSetWatchpointAtVariableAddress
->
setToolTip
(
tr
(
"Setting a watchpoint on an address will cause the program "
"to stop when the data at the address it modified."
));
tr
(
"Setting a data breakpoint on an address will cause the program "
"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
);
actWatchExpression
->
setEnabled
(
canHandleWatches
&&
!
exp
.
isEmpty
());
...
...
@@ -803,9 +820,7 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
menu
.
addAction
(
actSelectWidgetToWatch
);
menu
.
addMenu
(
&
formatMenu
);
menu
.
addMenu
(
&
memoryMenu
);
menu
.
addAction
(
actSetWatchpointAtVariableAddress
);
if
(
actSetWatchpointAtPointerValue
)
menu
.
addAction
(
actSetWatchpointAtPointerValue
);
menu
.
addMenu
(
&
breakpointMenu
);
menu
.
addAction
(
actCopy
);
menu
.
addAction
(
actCopyValue
);
menu
.
addSeparator
();
...
...
@@ -868,9 +883,11 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
}
else
if
(
act
==
actOpenMemoryEditorStackLayout
)
{
addStackLayoutMemoryView
(
currentEngine
(),
false
,
mi0
.
model
(),
ev
->
globalPos
(),
this
);
}
else
if
(
act
==
actSetWatchpointAtVariableAddress
)
{
setWatchpoint
(
address
,
size
);
setWatchpoint
AtAddress
(
address
,
size
);
}
else
if
(
act
==
actSetWatchpointAtPointerValue
)
{
setWatchpoint
(
pointerValue
,
1
);
setWatchpointAtAddress
(
pointerValue
,
sizeof
(
void
*
));
// FIXME: an approximation..
}
else
if
(
act
==
actSetWatchpointAtExpression
)
{
setWatchpointAtExpression
(
name
);
}
else
if
(
act
==
actSelectWidgetToWatch
)
{
grabMouse
(
Qt
::
CrossCursor
);
m_grabbing
=
true
;
...
...
@@ -1013,7 +1030,7 @@ void WatchWindow::setModelData
model
()
->
setData
(
index
,
value
,
role
);
}
void
WatchWindow
::
setWatchpoint
(
quint64
address
,
unsigned
size
)
void
WatchWindow
::
setWatchpoint
AtAddress
(
quint64
address
,
unsigned
size
)
{
BreakpointParameters
data
(
WatchpointAtAddress
);
data
.
address
=
address
;
...
...
@@ -1027,6 +1044,19 @@ void WatchWindow::setWatchpoint(quint64 address, unsigned size)
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 Debugger
src/plugins/debugger/watchwindow.h
View file @
e8496ca3
...
...
@@ -78,7 +78,8 @@ private:
void
editItem
(
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
(),
const
QModelIndex
&
index
=
QModelIndex
());
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment