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
Marco Bubke
flatpak-qt-creator
Commits
75529d87
Commit
75529d87
authored
Oct 05, 2009
by
hjk
Browse files
debugger: rework 'jump to source' logic
parent
1f1c899c
Changes
5
Hide whitespace changes
Inline
Side-by-side
src/plugins/debugger/debuggeractions.cpp
View file @
75529d87
...
...
@@ -84,7 +84,7 @@ void DebuggerSettings::writeSettings(QSettings *settings) const
SavedAction
*
DebuggerSettings
::
item
(
int
code
)
const
{
QTC_ASSERT
(
m_items
.
value
(
code
,
0
),
return
0
);
QTC_ASSERT
(
m_items
.
value
(
code
,
0
),
qDebug
()
<<
"CODE: "
<<
code
;
return
0
);
return
m_items
.
value
(
code
,
0
);
}
...
...
src/plugins/debugger/debuggermanager.cpp
View file @
75529d87
...
...
@@ -454,6 +454,7 @@ void DebuggerManager::init()
//QTreeView *tooltipView = qobject_cast<QTreeView *>(d->m_tooltipWindow);
//tooltipView->setModel(d->m_watchHandler->model(TooltipsWatch));
qRegisterMetaType
<
WatchData
>
(
"WatchData"
);
qRegisterMetaType
<
StackCookie
>
(
"StackCookie"
);
d
->
m_actions
.
continueAction
=
new
QAction
(
tr
(
"Continue"
),
this
);
d
->
m_actions
.
continueAction
->
setIcon
(
QIcon
(
":/debugger/images/debugger_continue_small.png"
));
...
...
@@ -707,7 +708,6 @@ void DebuggerManager::showStatusMessage(const QString &msg, int timeout)
void
DebuggerManager
::
notifyInferiorStopped
()
{
resetLocation
();
setState
(
InferiorStopped
);
showStatusMessage
(
tr
(
"Stopped."
),
5000
);
}
...
...
@@ -1349,7 +1349,7 @@ void DebuggerManager::gotoLocation(const Debugger::Internal::StackFrame &frame,
{
if
(
theDebuggerBoolSetting
(
OperateByInstruction
)
||
!
frame
.
isUsable
())
{
if
(
setMarker
)
resetLocation
();
emit
resetLocation
Requested
();
d
->
m_disassemblerViewAgent
.
setFrame
(
frame
);
}
else
{
// Connected to the plugin.
...
...
src/plugins/debugger/gdb/gdbengine.cpp
View file @
75529d87
...
...
@@ -894,18 +894,13 @@ void GdbEngine::updateAll()
{
QTC_ASSERT
(
state
()
==
InferiorUnrunnable
||
state
()
==
InferiorStopped
,
/**/
);
tryLoadDebuggingHelpers
();
updateLocals
();
postCommand
(
_
(
"-stack-list-frames"
),
WatchUpdate
,
CB
(
handleStackListFrames1
),
false
);
postCommand
(
_
(
"-stack-list-frames"
),
WatchUpdate
,
CB
(
handleStackListFrames
),
QVariant
::
fromValue
<
StackCookie
>
(
StackCookie
(
false
,
true
))
);
manager
()
->
stackHandler
()
->
setCurrentIndex
(
0
);
if
(
supportsThreads
())
postCommand
(
_
(
"-thread-list-ids"
),
WatchUpdate
,
CB
(
handleStackListThreads
),
0
);
manager
()
->
reloadRegisters
();
}
void
GdbEngine
::
handleStackListFrames1
(
const
GdbResponse
&
response
)
{
handleStackListFrames
(
response
);
manager
()
->
gotoLocation
(
manager
()
->
stackHandler
()
->
currentFrame
(),
true
);
updateLocals
();
}
void
GdbEngine
::
handleQuerySources
(
const
GdbResponse
&
response
)
...
...
@@ -1182,29 +1177,6 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
#endif
}
void
GdbEngine
::
reloadFullStack
()
{
QString
cmd
=
_
(
"-stack-list-frames"
);
postCommand
(
cmd
,
WatchUpdate
,
CB
(
handleStackListFrames
),
true
);
}
void
GdbEngine
::
reloadStack
()
{
QString
cmd
=
_
(
"-stack-list-frames"
);
int
stackDepth
=
theDebuggerAction
(
MaximalStackDepth
)
->
value
().
toInt
();
if
(
stackDepth
&&
!
m_gdbAdapter
->
isTrkAdapter
())
cmd
+=
_
(
" 0 "
)
+
QString
::
number
(
stackDepth
);
postCommand
(
cmd
,
WatchUpdate
,
CB
(
handleStackListFrames
),
false
);
// FIXME: gdb 6.4 symbianelf likes to be asked twice. The first time it
// returns with "^error,msg="Previous frame identical to this frame
// (corrupt stack?)". Might be related to the fact that we can't
// access the memory belonging to the lower frames. But as we know
// this sometimes happens, ask the second time immediately instead
// of waiting for the first request to fail.
if
(
m_gdbAdapter
->
isTrkAdapter
())
postCommand
(
cmd
,
WatchUpdate
,
CB
(
handleStackListFrames
),
false
);
}
void
GdbEngine
::
handleStop1
(
const
GdbResponse
&
response
)
{
GdbMi
data
=
response
.
cookie
.
value
<
GdbMi
>
();
...
...
@@ -1307,7 +1279,7 @@ void GdbEngine::handleStop2(const GdbMi &data)
manager
()
->
stackHandler
()
->
setCurrentIndex
(
0
);
updateLocals
();
// Quick shot
reloadStack
();
reloadStack
(
false
);
if
(
supportsThreads
())
{
int
currentId
=
data
.
findChild
(
"thread-id"
).
data
().
toInt
();
...
...
@@ -2235,13 +2207,52 @@ void GdbEngine::reloadSourceFiles()
//
//////////////////////////////////////////////////////////////////////
void
GdbEngine
::
selectThread
(
int
index
)
{
ThreadsHandler
*
threadsHandler
=
manager
()
->
threadsHandler
();
threadsHandler
->
setCurrentThread
(
index
);
QList
<
ThreadData
>
threads
=
threadsHandler
->
threads
();
QTC_ASSERT
(
index
<
threads
.
size
(),
return
);
int
id
=
threads
.
at
(
index
).
id
;
showStatusMessage
(
tr
(
"Retrieving data for stack view..."
),
10000
);
postCommand
(
_
(
"-thread-select %1"
).
arg
(
id
),
CB
(
handleStackSelectThread
));
}
void
GdbEngine
::
handleStackSelectThread
(
const
GdbResponse
&
)
{
QTC_ASSERT
(
state
()
==
InferiorUnrunnable
||
state
()
==
InferiorStopped
,
/**/
);
//qDebug("FIXME: StackHandler::handleOutput: SelectThread");
showStatusMessage
(
tr
(
"Retrieving data for stack view..."
),
3000
);
reloadStack
();
manager
()
->
reloadRegisters
();
reloadStack
(
true
);
updateLocals
();
}
void
GdbEngine
::
reloadFullStack
()
{
QString
cmd
=
_
(
"-stack-list-frames"
);
postCommand
(
cmd
,
WatchUpdate
,
CB
(
handleStackListFrames
),
QVariant
::
fromValue
<
StackCookie
>
(
StackCookie
(
true
,
true
)));
}
void
GdbEngine
::
reloadStack
(
bool
forceGotoLocation
)
{
QString
cmd
=
_
(
"-stack-list-frames"
);
int
stackDepth
=
theDebuggerAction
(
MaximalStackDepth
)
->
value
().
toInt
();
if
(
stackDepth
&&
!
m_gdbAdapter
->
isTrkAdapter
())
cmd
+=
_
(
" 0 "
)
+
QString
::
number
(
stackDepth
);
// FIXME: gdb 6.4 symbianelf likes to be asked twice. The first time it
// returns with "^error,msg="Previous frame identical to this frame
// (corrupt stack?)". Might be related to the fact that we can't
// access the memory belonging to the lower frames. But as we know
// this sometimes happens, ask the second time immediately instead
// of waiting for the first request to fail.
if
(
m_gdbAdapter
->
isTrkAdapter
())
postCommand
(
cmd
,
WatchUpdate
);
postCommand
(
cmd
,
WatchUpdate
,
CB
(
handleStackListFrames
),
QVariant
::
fromValue
<
StackCookie
>
(
StackCookie
(
false
,
forceGotoLocation
)));
}
StackFrame
GdbEngine
::
parseStackFrame
(
const
GdbMi
&
frameMi
,
int
level
)
{
...
...
@@ -2266,94 +2277,94 @@ void GdbEngine::handleStackListFrames(const GdbResponse &response)
#else
bool
handleIt
=
response
.
resultClass
==
GdbResultDone
;
#endif
if
(
handleIt
)
{
bool
isFull
=
response
.
cookie
.
toBool
();
QList
<
StackFrame
>
stackFrames
;
GdbMi
stack
=
response
.
data
.
findChild
(
"stack"
);
if
(
!
stack
.
isValid
())
{
qDebug
()
<<
"FIXME: stack:"
<<
stack
.
toString
();
return
;
}
if
(
!
handleIt
)
{
// That always happens on symbian gdb with
// ^error,data={msg="Previous frame identical to this frame (corrupt stack?)"
// logstreamoutput="Previous frame identical to this frame (corrupt stack?)\n"
//qDebug() << "LISTING STACK FAILED: " << response.toString();
return
;
}
int
topFrame
=
-
1
;
StackCookie
cookie
=
response
.
cookie
.
value
<
StackCookie
>
();
QList
<
StackFrame
>
stackFrames
;
int
n
=
stack
.
childCount
();
for
(
int
i
=
0
;
i
!=
n
;
++
i
)
{
stackFrames
.
append
(
parseStackFrame
(
stack
.
childAt
(
i
),
i
));
const
StackFrame
&
frame
=
stackFrames
.
back
();
GdbMi
stack
=
response
.
data
.
findChild
(
"stack"
);
if
(
!
stack
.
isValid
())
{
qDebug
()
<<
"FIXME: stack:"
<<
stack
.
toString
();
return
;
}
#if defined(Q_OS_WIN)
const
bool
isBogus
=
// Assume this is wrong and points to some strange stl_algobase
// implementation. Happens on Karsten's XP system with Gdb 5.50
(
frame
.
file
.
endsWith
(
__
(
"/bits/stl_algobase.h"
))
&&
frame
.
line
==
150
)
// Also wrong. Happens on Vista with Gdb 5.50
||
(
frame
.
function
==
__
(
"operator new"
)
&&
frame
.
line
==
151
);
int
targetFrame
=
-
1
;
// Immediately leave bogus frames.
if
(
topFrame
==
-
1
&&
isBogus
)
{
postCommand
(
_
(
"-exec-finish"
));
return
;
}
#endif
int
n
=
stack
.
childCount
();
for
(
int
i
=
0
;
i
!=
n
;
++
i
)
{
stackFrames
.
append
(
parseStackFrame
(
stack
.
childAt
(
i
),
i
));
const
StackFrame
&
frame
=
stackFrames
.
back
();
// Initialize top frame to the first valid frame.
// FIXME: Check for QFile(frame.fullname).isReadable()?
const
bool
isValid
=
!
frame
.
file
.
isEmpty
()
&&
!
frame
.
function
.
isEmpty
();
if
(
isValid
&&
topFrame
==
-
1
)
topFrame
=
i
;
#if defined(Q_OS_WIN)
const
bool
isBogus
=
// Assume this is wrong and points to some strange stl_algobase
// implementation. Happens on Karsten's XP system with Gdb 5.50
(
frame
.
file
.
endsWith
(
__
(
"/bits/stl_algobase.h"
))
&&
frame
.
line
==
150
)
// Also wrong. Happens on Vista with Gdb 5.50
||
(
frame
.
function
==
__
(
"operator new"
)
&&
frame
.
line
==
151
);
// Immediately leave bogus frames.
if
(
targetFrame
==
-
1
&&
isBogus
)
{
postCommand
(
_
(
"-exec-finish"
));
return
;
}
bool
canExpand
=
!
isFull
&&
(
n
>=
theDebuggerAction
(
MaximalStackDepth
)
->
value
().
toInt
());
theDebuggerAction
(
ExpandStack
)
->
setEnabled
(
canExpand
);
manager
()
->
stackHandler
()
->
setFrames
(
stackFrames
,
canExpand
);
#ifdef Q_OS_MAC
// Mac gdb does not add the location to the "stopped" message,
// so the early gotoLocation() was not triggered. Force it here.
bool
jump
=
topFrame
!=
-
1
&&
!
theDebuggerBoolSetting
(
OperateByInstruction
);
#else
// For topFrame == -1 there is no frame at all, for topFrame == 0
// we already issued a 'gotoLocation' when reading the *stopped
// message. Also, when OperateByInstruction we always want to
// use frame #0.
bool
jump
=
topFrame
!=
-
1
&&
topFrame
!=
0
&&
!
theDebuggerBoolSetting
(
OperateByInstruction
);
#endif
if
(
jump
)
{
const
StackFrame
&
frame
=
manager
()
->
stackHandler
()
->
currentFrame
();
qDebug
()
<<
"GOTO, 2nd try"
<<
frame
.
toString
()
<<
topFrame
;
gotoLocation
(
frame
,
true
);
}
}
else
{
// That always happens on symbian gdb with
// ^error,data={msg="Previous frame identical to this frame (corrupt stack?)"
// logstreamoutput="Previous frame identical to this frame (corrupt stack?)\n"
//qDebug() << "LISTING STACK FAILED: " << response.toString();
// Initialize top frame to the first valid frame.
// FIXME: Check for QFile(frame.fullname).isReadable()?
const
bool
isValid
=
!
frame
.
file
.
isEmpty
()
&&
!
frame
.
function
.
isEmpty
();
if
(
isValid
&&
targetFrame
==
-
1
)
targetFrame
=
i
;
}
}
void
GdbEngine
::
selectThread
(
int
index
)
{
//reset location arrow
m_
manager
->
resetLocation
(
);
bool
canExpand
=
!
cookie
.
isFull
&&
(
n
>=
theDebuggerAction
(
MaximalStackDepth
)
->
value
().
toInt
());
theDebuggerAction
(
ExpandStack
)
->
setEnabled
(
canExpand
);
manager
()
->
stackHandler
()
->
setFrames
(
stackFrames
,
canExpand
);
ThreadsHandler
*
threadsHandler
=
manager
()
->
threadsHandler
();
threadsHandler
->
setCurrentThread
(
index
);
// We can't jump to any file if we don't have any frames.
if
(
stackFrames
.
isEmpty
())
return
;
QList
<
ThreadData
>
threads
=
threadsHandler
->
threads
();
QTC_ASSERT
(
index
<
threads
.
size
(),
return
);
int
id
=
threads
.
at
(
index
).
id
;
showStatusMessage
(
tr
(
"Retrieving data for stack view..."
),
10000
);
postCommand
(
_
(
"-thread-select %1"
).
arg
(
id
),
CB
(
handleStackSelectThread
));
// targetFrame contains the top most frame for which we have source
// information. That's typically the frame we'd like to jump to, with
// a few exceptions:
// Always jump to frame #0 when stepping by instruction.
if
(
theDebuggerBoolSetting
(
OperateByInstruction
))
targetFrame
=
0
;
// If there is no frame with source, jump to frame #0.
if
(
targetFrame
==
-
1
)
targetFrame
=
0
;
#ifdef Q_OS_MAC
// Mac gdb does not add the location to the "stopped" message,
// so the early gotoLocation() was not triggered. Force it here.
bool
jump
=
true
;
#else
// For targetFrame == 0 we already issued a 'gotoLocation'
// when reading the *stopped message.
bool
jump
=
targetFrame
!=
0
;
#endif
manager
()
->
stackHandler
()
->
setCurrentIndex
(
targetFrame
);
if
(
jump
||
cookie
.
gotoLocation
)
{
const
StackFrame
&
frame
=
manager
()
->
stackHandler
()
->
currentFrame
();
//qDebug() << "GOTO, 2ND ATTEMPT: " << frame.toString() << targetFrame;
gotoLocation
(
frame
,
true
);
}
}
void
GdbEngine
::
activateFrame
(
int
frameIndex
)
{
m_manager
->
resetLocation
();
if
(
state
()
!=
InferiorStopped
)
return
;
...
...
@@ -2394,7 +2405,8 @@ void GdbEngine::handleStackListThreads(const GdbResponse &response)
thread
.
id
=
items
.
at
(
index
).
data
().
toInt
();
threads
.
append
(
thread
);
if
(
thread
.
id
==
id
)
{
//qDebug() << "SETTING INDEX TO:" << index << " ID:" << id << " RECOD:" << response.toString();
//qDebug() << "SETTING INDEX TO:" << index << " ID:"
// << id << " RECOD:" << response.toString();
currentIndex
=
index
;
}
}
...
...
@@ -3086,7 +3098,7 @@ void GdbEngine::sendWatchParameters(const QByteArray ¶ms0)
void
GdbEngine
::
handleVarAssign
(
const
GdbResponse
&
)
{
//
e
verything might have changed, force re-evaluation
//
E
verything might have changed, force re-evaluation
.
// FIXME: Speed this up by re-using variables and only
// marking values as 'unknown'
setTokenBarrier
();
...
...
@@ -3421,7 +3433,8 @@ void GdbEngine::handleStackListArguments(const GdbResponse &response)
const
GdbMi
args
=
frame
.
findChild
(
"args"
);
m_currentFunctionArgs
=
args
.
children
();
}
else
if
(
response
.
resultClass
==
GdbResultError
)
{
qDebug
()
<<
"FIXME: GdbEngine::handleStackListArguments: should not happen"
;
qDebug
()
<<
"FIXME: GdbEngine::handleStackListArguments: should not happen"
<<
response
.
toString
();
}
}
...
...
src/plugins/debugger/gdb/gdbengine.h
View file @
75529d87
...
...
@@ -339,10 +339,9 @@ private:
// Stack specific stuff
//
void
handleStackListFrames
(
const
GdbResponse
&
response
);
void
handleStackListFrames1
(
const
GdbResponse
&
response
);
void
handleStackSelectThread
(
const
GdbResponse
&
response
);
void
handleStackListThreads
(
const
GdbResponse
&
response
);
Q_SLOT
void
reloadStack
();
Q_SLOT
void
reloadStack
(
bool
forceGotoLocation
);
Q_SLOT
void
reloadFullStack
();
...
...
src/plugins/debugger/stackhandler.h
View file @
75529d87
...
...
@@ -41,6 +41,14 @@
namespace
Debugger
{
namespace
Internal
{
struct
StackCookie
{
StackCookie
()
:
isFull
(
true
),
gotoLocation
(
false
)
{}
StackCookie
(
bool
full
,
bool
jump
)
:
isFull
(
full
),
gotoLocation
(
jump
)
{}
bool
isFull
;
bool
gotoLocation
;
};
////////////////////////////////////////////////////////////////////////
//
// StackModel
...
...
@@ -129,4 +137,7 @@ private:
}
// namespace Internal
}
// namespace Debugger
Q_DECLARE_METATYPE
(
Debugger
::
Internal
::
StackCookie
)
#endif // DEBUGGER_STACKHANDLER_H
Write
Preview
Supports
Markdown
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