Skip to content
GitLab
Menu
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
172a1ae4
Commit
172a1ae4
authored
Mar 03, 2010
by
hjk
Browse files
debugger: sanitize breakpoint setting sequences
parent
839ad4da
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/plugins/debugger/gdb/gdbengine.cpp
View file @
172a1ae4
...
...
@@ -255,10 +255,10 @@ void GdbEngine::initializeVariables()
invalidateSourcesList
();
m_sourcesListUpdating
=
false
;
m_breakListUpdating
=
false
;
m_oldestAcceptableToken
=
-
1
;
m_outputCodec
=
QTextCodec
::
codecForLocale
();
m_pendingWatchRequests
=
0
;
m_pendingBreakpointRequests
=
0
;
m_commandsDoneCallback
=
0
;
m_commandsToRunOnTemporaryBreak
.
clear
();
m_cookieForToken
.
clear
();
...
...
@@ -719,11 +719,16 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd)
if
(
cmd
.
flags
&
RebuildWatchModel
)
{
++
m_pendingWatchRequests
;
PENDING_DEBUG
(
" MODEL:"
<<
cmd
.
command
<<
"=>"
<<
cmd
.
callbackName
PENDING_DEBUG
(
"
WATCH
MODEL:"
<<
cmd
.
command
<<
"=>"
<<
cmd
.
callbackName
<<
"INCREMENTS PENDING TO"
<<
m_pendingWatchRequests
);
}
else
if
(
cmd
.
flags
&
RebuildBreakpointModel
)
{
++
m_pendingBreakpointRequests
;
PENDING_DEBUG
(
" BRWAKPOINT MODEL:"
<<
cmd
.
command
<<
"=>"
<<
cmd
.
callbackName
<<
"INCREMENTS PENDING TO"
<<
m_pendingBreakpointRequests
);
}
else
{
PENDING_DEBUG
(
" OTHER (IN):"
<<
cmd
.
command
<<
"=>"
<<
cmd
.
callbackName
<<
"LEAVES PENDING AT"
<<
m_pendingWatchRequests
);
<<
"LEAVES PENDING WATCH AT"
<<
m_pendingWatchRequests
<<
"LEAVES PENDING BREAKPOINT AT"
<<
m_pendingBreakpointRequests
);
}
if
((
cmd
.
flags
&
NeedsStop
)
||
!
m_commandsToRunOnTemporaryBreak
.
isEmpty
())
{
...
...
@@ -942,14 +947,23 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
if
(
cmd
.
flags
&
RebuildWatchModel
)
{
--
m_pendingWatchRequests
;
PENDING_DEBUG
(
" WATCH"
<<
cmd
.
command
<<
"=>"
<<
cmd
.
callbackName
<<
"DECREMENTS PENDING TO"
<<
m_pendingWatchRequests
);
<<
"DECREMENTS PENDING
WATCH
TO"
<<
m_pendingWatchRequests
);
if
(
m_pendingWatchRequests
<=
0
)
{
PENDING_DEBUG
(
"
\n\n
... AND TRIGGERS MODEL UPDATE
\n
"
);
PENDING_DEBUG
(
"
\n\n
... AND TRIGGERS
WATCH
MODEL UPDATE
\n
"
);
rebuildWatchModel
();
}
}
else
if
(
cmd
.
flags
&
RebuildBreakpointModel
)
{
--
m_pendingBreakpointRequests
;
PENDING_DEBUG
(
" BREAKPOINT"
<<
cmd
.
command
<<
"=>"
<<
cmd
.
callbackName
<<
"DECREMENTS PENDING TO"
<<
m_pendingWatchRequests
);
if
(
m_pendingBreakpointRequests
<=
0
)
{
PENDING_DEBUG
(
"
\n\n
... AND TRIGGERS BREAKPOINT MODEL UPDATE
\n
"
);
attemptBreakpointSynchronization
();
}
}
else
{
PENDING_DEBUG
(
" OTHER (OUT):"
<<
cmd
.
command
<<
"=>"
<<
cmd
.
callbackName
<<
"LEAVES PENDING AT"
<<
m_pendingWatchRequests
);
<<
"LEAVES PENDING WATCH AT"
<<
m_pendingWatchRequests
<<
"LEAVES PENDING BREAKPOINT AT"
<<
m_pendingBreakpointRequests
);
}
// Commands were queued, but we were in RunningRequested state, so the interrupt
...
...
@@ -1103,7 +1117,6 @@ void GdbEngine::handleAqcuiredInferior()
// It's nicer to see a bit of the world we live in.
reloadModulesInternal();
attemptBreakpointSynchronization();
}
#endif
...
...
@@ -1312,20 +1325,22 @@ void GdbEngine::handleStop1(const GdbMi &data)
return
;
}
// This is for display only.
if
(
m_modulesListOutdated
)
reloadModulesInternal
();
// This is for display only
reloadModulesInternal
();
// This needs to be done before fullName() may need it.
if
(
m_sourcesListOutdated
&&
theDebuggerBoolSetting
(
UsePreciseBreakpoints
))
reloadSourceFilesInternal
();
// This needs to be done before fullName() may need it
reloadSourceFilesInternal
();
if
(
!
hasPython
())
{
if
(
m_breakListOutdated
)
if
(
m_breakListOutdated
)
{
reloadBreakListInternal
();
}
else
{
// Older gdb versions do not produce "library loaded" messages
// so the breakpoint update is not triggered.
if
(
m_gdbVersion
<
70000
&&
!
m_isMacGdb
&&
manager
()
->
breakHandler
()
->
size
()
>
0
)
reloadBreakListInternal
();
else
// Older gdb versions do not produce "library loaded" messages
// so the breakpoint update is not triggered.
if
(
m_gdbVersion
<
70000
&&
!
m_isMacGdb
&&
!
m_breakListUpdating
&&
manager
()
->
breakHandler
()
->
size
()
>
0
)
reloadBreakListInternal
();
}
if
(
reason
==
"breakpoint-hit"
)
{
...
...
@@ -2035,8 +2050,7 @@ void GdbEngine::breakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt
QString
GdbEngine
::
breakLocation
(
const
QString
&
file
)
const
{
QTC_ASSERT
(
!
m_breakListOutdated
,
/* */
)
QTC_ASSERT
(
!
m_breakListUpdating
,
/* */
)
//QTC_ASSERT(!m_breakListOutdated, /* */)
QString
where
=
m_fullToShortName
.
value
(
file
);
if
(
where
.
isEmpty
())
return
QFileInfo
(
file
).
fileName
();
...
...
@@ -2057,28 +2071,30 @@ void GdbEngine::sendInsertBreakpoint(int index)
where
=
data
->
funcName
.
toLatin1
();
}
//
s
et up fallback in case of pending breakpoints which aren't handled
// by the MI interface
//
S
et up fallback in case of pending breakpoints which aren't handled
// by the MI interface
.
QByteArray
cmd
;
if
(
m_isMacGdb
)
cmd
=
"-break-insert -l -1 -f "
;
else
if
(
m_gdbAdapter
->
isTrkAdapter
())
cmd
=
"-break-insert -h -f "
;
else
if
(
m_gdbVersion
>=
60800
)
// Probably some earlier version would work as well ...
else
if
(
m_gdbVersion
>=
60800
)
// Probably some earlier version would work as well.
cmd
=
"-break-insert -f "
;
else
cmd
=
"-break-insert "
;
//if (!data->condition.isEmpty())
// cmd += "-c " + data->condition + ' ';
cmd
+=
where
;
postCommand
(
cmd
,
NeedsStop
,
CB
(
handleBreakInsert
),
index
);
postCommand
(
cmd
,
NeedsStop
|
RebuildBreakpointModel
,
CB
(
handleBreakInsert
),
index
);
}
void
GdbEngine
::
reloadBreakListInternal
()
{
m_
break
L
ist
Updating
=
true
;
// "Discardable" as long as we do in each step
postCommand
(
"-break-list"
,
NeedsStop
|
Discardable
,
CB
(
handleBreakList
));
postCommand
(
"-
break
-l
ist
"
,
NeedsStop
|
RebuildBreakpointModel
,
CB
(
handleBreakList
));
}
void
GdbEngine
::
handleBreakList
(
const
GdbResponse
&
response
)
...
...
@@ -2129,9 +2145,7 @@ void GdbEngine::handleBreakList(const GdbMi &table)
//qDebug() << "CANNOT HANDLE RESPONSE" << bkpts.at(index).toString();
}
m_breakListUpdating
=
false
;
m_breakListOutdated
=
false
;
attemptBreakpointSynchronization
();
}
void
GdbEngine
::
handleBreakIgnore
(
const
GdbResponse
&
response
)
...
...
@@ -2196,7 +2210,6 @@ void GdbEngine::handleBreakInsert(const GdbResponse &response)
GdbMi
bkpt
=
response
.
data
.
findChild
(
"bkpt"
);
breakpointDataFromOutput
(
data
,
bkpt
);
//#endif
attemptBreakpointSynchronization
();
}
else
{
if
(
m_gdbVersion
<
60800
&&
!
m_isMacGdb
)
{
// This gdb version doesn't "do" pending breakpoints.
...
...
@@ -2267,7 +2280,6 @@ void GdbEngine::handleBreakInfo(const GdbResponse &response)
QString
str
=
QString
::
fromLocal8Bit
(
response
.
data
.
findChild
(
"consolestreamoutput"
).
data
());
extractDataFromInfoBreak
(
str
,
handler
->
at
(
found
));
attemptBreakpointSynchronization
();
// trigger "ready"
}
}
}
...
...
@@ -2286,15 +2298,13 @@ void GdbEngine::handleBreakInsert1(const GdbResponse &response)
BreakpointData
*
data
=
handler
->
at
(
index
);
data
->
bpNumber
=
"<unavailable>"
;
}
attemptBreakpointSynchronization
();
// trigger "ready"
}
void
GdbEngine
::
attemptBreakpointSynchronization
()
{
//QTC_ASSERT(!m_breakListUpdating,
// qDebug() << "BREAK LIST CURRENTLY UPDATING"; return);
QTC_ASSERT
(
!
m_sourcesListUpdating
,
qDebug
()
<<
"SOURCES LIST CURRENTLY UPDATING"
;
return
);
debugMessage
(
tr
(
"ATTEMPT BREAKPOINT SYNC"
));
switch
(
state
())
{
case
InferiorStarting
:
...
...
@@ -2332,6 +2342,7 @@ void GdbEngine::attemptBreakpointSynchronization()
reloadBreakListInternal
();
return
;
}
if
(
m_breakListOutdated
)
{
reloadBreakListInternal
();
return
;
...
...
@@ -2342,7 +2353,8 @@ void GdbEngine::attemptBreakpointSynchronization()
foreach
(
BreakpointData
*
data
,
handler
->
takeDisabledBreakpoints
())
{
QByteArray
bpNumber
=
data
->
bpNumber
;
if
(
!
bpNumber
.
trimmed
().
isEmpty
())
{
postCommand
(
"-break-disable "
+
bpNumber
,
NeedsStop
);
postCommand
(
"-break-disable "
+
bpNumber
,
NeedsStop
|
RebuildBreakpointModel
);
data
->
bpEnabled
=
false
;
}
}
...
...
@@ -2350,7 +2362,8 @@ void GdbEngine::attemptBreakpointSynchronization()
foreach
(
BreakpointData
*
data
,
handler
->
takeEnabledBreakpoints
())
{
QByteArray
bpNumber
=
data
->
bpNumber
;
if
(
!
bpNumber
.
trimmed
().
isEmpty
())
{
postCommand
(
"-break-enable "
+
bpNumber
,
NeedsStop
);
postCommand
(
"-break-enable "
+
bpNumber
,
NeedsStop
|
RebuildBreakpointModel
);
data
->
bpEnabled
=
true
;
}
}
...
...
@@ -2360,7 +2373,8 @@ void GdbEngine::attemptBreakpointSynchronization()
debugMessage
(
_
(
"DELETING BP "
+
bpNumber
+
" IN "
+
data
->
markerFileName
.
toLocal8Bit
()));
if
(
!
bpNumber
.
trimmed
().
isEmpty
())
postCommand
(
"-break-delete "
+
bpNumber
,
NeedsStop
);
postCommand
(
"-break-delete "
+
bpNumber
,
NeedsStop
|
RebuildBreakpointModel
);
delete
data
;
}
...
...
@@ -2372,19 +2386,23 @@ void GdbEngine::attemptBreakpointSynchronization()
}
else
if
(
data
->
bpNumber
.
toInt
())
{
if
(
data
->
bpMultiple
&&
data
->
bpFileName
.
isEmpty
())
{
postCommand
(
"info break "
+
data
->
bpNumber
,
RebuildBreakpointModel
,
CB
(
handleBreakInfo
),
data
->
bpNumber
.
toInt
());
continue
;
}
// update conditions if needed
if
(
data
->
condition
!=
data
->
bpCondition
&&
!
data
->
conditionsMatch
())
postCommand
(
"condition "
+
data
->
bpNumber
+
' '
+
data
->
condition
,
CB
(
handleBreakCondition
),
index
);
RebuildBreakpointModel
,
CB
(
handleBreakCondition
),
index
);
// update ignorecount if needed
if
(
data
->
ignoreCount
!=
data
->
bpIgnoreCount
)
postCommand
(
"ignore "
+
data
->
bpNumber
+
' '
+
data
->
ignoreCount
,
CB
(
handleBreakIgnore
),
index
);
RebuildBreakpointModel
,
CB
(
handleBreakIgnore
),
index
);
if
(
!
data
->
enabled
&&
data
->
bpEnabled
)
{
postCommand
(
"-break-disable "
+
data
->
bpNumber
,
NeedsStop
);
postCommand
(
"-break-disable "
+
data
->
bpNumber
,
NeedsStop
|
RebuildBreakpointModel
);
data
->
bpEnabled
=
false
;
}
}
...
...
@@ -3418,6 +3436,7 @@ void GdbEngine::handleChildren(const WatchData &data0, const GdbMi &item,
void
GdbEngine
::
updateLocals
(
const
QVariant
&
cookie
)
{
m_pendingWatchRequests
=
0
;
m_pendingBreakpointRequests
=
0
;
if
(
hasPython
())
updateLocalsPython
(
QByteArray
());
else
...
...
@@ -4121,6 +4140,7 @@ void GdbEngine::handleInferiorPrepared()
// Initial attempt to set breakpoints
showStatusMessage
(
tr
(
"Setting breakpoints..."
));
debugMessage
(
tr
(
"Setting breakpoints..."
));
attemptBreakpointSynchronization
();
if
(
m_cookieForToken
.
isEmpty
())
{
...
...
src/plugins/debugger/gdb/gdbengine.h
View file @
172a1ae4
...
...
@@ -102,7 +102,8 @@ private: ////////// General Interface //////////
virtual
void
addOptionPages
(
QList
<
Core
::
IOptionsPage
*>
*
opts
)
const
;
virtual
bool
checkConfiguration
(
int
toolChain
,
QString
*
errorMessage
,
QString
*
settingsPage
=
0
)
const
;
virtual
bool
checkConfiguration
(
int
toolChain
,
QString
*
errorMessage
,
QString
*
settingsPage
=
0
)
const
;
virtual
void
startDebugger
(
const
DebuggerStartParametersPtr
&
sp
);
virtual
unsigned
debuggerCapabilities
()
const
;
virtual
void
exitDebugger
();
...
...
@@ -149,7 +150,8 @@ private slots:
void
readDebugeeOutput
(
const
QByteArray
&
data
);
void
handleAdapterStarted
();
void
handleAdapterStartFailed
(
const
QString
&
msg
,
const
QString
&
settingsIdHint
=
QString
());
void
handleAdapterStartFailed
(
const
QString
&
msg
,
const
QString
&
settingsIdHint
=
QString
());
void
handleInferiorPrepared
();
...
...
@@ -169,17 +171,26 @@ private:
private:
////////// Gdb Command Management //////////
public:
//
o
therwise the Qt flag macros are unhappy
public:
//
O
therwise the Qt flag macros are unhappy
.
enum
GdbCommandFlag
{
NoFlags
=
0
,
NeedsStop
=
1
,
// The command needs a stopped inferior
Discardable
=
2
,
// No need to wait for the reply before continuing inferior
RebuildWatchModel
=
4
,
// Trigger model rebuild when no such commands are pending any more
// The command needs a stopped inferior.
NeedsStop
=
1
,
// No need to wait for the reply before continuing inferior.
Discardable
=
2
,
// Trigger watch model rebuild when no such commands are pending anymore.
RebuildWatchModel
=
4
,
WatchUpdate
=
Discardable
|
RebuildWatchModel
,
NonCriticalResponse
=
8
,
// We can live without recieving an answer
RunRequest
=
16
,
// Callback expects GdbResultRunning instead of GdbResultDone
ExitRequest
=
32
,
// Callback expects GdbResultExit instead of GdbResultDone
LosesChild
=
64
// Auto-set inferior shutdown related states
// We can live without recieving an answer.
NonCriticalResponse
=
8
,
// Callback expects GdbResultRunning instead of GdbResultDone.
RunRequest
=
16
,
// Callback expects GdbResultExit instead of GdbResultDone.
ExitRequest
=
32
,
// Auto-set inferior shutdown related states.
LosesChild
=
64
,
// Trigger breakpoint model rebuild when no such commands are pending anymore.
RebuildBreakpointModel
=
128
,
};
Q_DECLARE_FLAGS
(
GdbCommandFlags
,
GdbCommandFlag
)
private:
...
...
@@ -204,7 +215,7 @@ private: ////////// Gdb Command Management //////////
QTime
postTime
;
};
//
t
ype and cookie are sender-internal data, opaque for the "event
//
T
ype and cookie are sender-internal data, opaque for the "event
// queue". resultNeeded == true increments m_pendingResults on
// send and decrements on receipt, effectively preventing
// watch model updates before everything is finished.
...
...
@@ -239,15 +250,16 @@ private: ////////// Gdb Command Management //////////
QByteArray
m_pendingConsoleStreamOutput
;
QByteArray
m_pendingLogStreamOutput
;
// contains the first token number for the current round
//
This
contains the first token number for the current round
// of evaluation. Responses with older tokens are considers
// out of date and discarded.
int
m_oldestAcceptableToken
;
int
m_pendingWatchRequests
;
// Watch updating commands in flight
int
m_pendingBreakpointRequests
;
// Watch updating commands in flight
typedef
void
(
GdbEngine
::*
CommandsDoneCallback
)();
// function called after all previous responses have been received
//
This
function
is
called after all previous responses have been received
.
CommandsDoneCallback
m_commandsDoneCallback
;
QList
<
GdbCommand
>
m_commandsToRunOnTemporaryBreak
;
...
...
@@ -402,7 +414,6 @@ private: ////////// View & Data Stuff //////////
bool
m_sourcesListOutdated
;
bool
m_sourcesListUpdating
;
bool
m_breakListOutdated
;
bool
m_breakListUpdating
;
//
// Stack specific stuff
...
...
@@ -459,7 +470,6 @@ private: ////////// View & Data Stuff //////////
void
handleVarCreate
(
const
GdbResponse
&
response
);
void
handleVarAssign
(
const
GdbResponse
&
response
);
void
handleEvaluateExpressionClassic
(
const
GdbResponse
&
response
);
//void handleToolTip(const GdbResponse &response);
void
handleQueryDebuggingHelperClassic
(
const
GdbResponse
&
response
);
void
handleDebuggingHelperValue2Classic
(
const
GdbResponse
&
response
);
void
handleDebuggingHelperValue3Classic
(
const
GdbResponse
&
response
);
...
...
src/plugins/debugger/gdb/pythongdbengine.cpp
View file @
172a1ae4
...
...
@@ -142,6 +142,7 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
//for (int i = 0; i != list.size(); ++i)
// qDebug() << "LOCAL: " << list.at(i).toString();
#if 0
data = all.findChild("bkpts");
if (data.isValid()) {
BreakHandler *handler = manager()->breakHandler();
...
...
@@ -175,6 +176,7 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
}
handler->updateMarkers();
}
#endif
//PENDING_DEBUG("AFTER handleStackFrame()");
// FIXME: This should only be used when updateLocals() was
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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