forked from qt-creator/qt-creator
debugger: show return value of last function call in Locals and Watchers view
Works only with gdb/Python so far.
This commit is contained in:
@@ -297,14 +297,15 @@ struct DebuggerManagerPrivate
|
||||
DebuggerManagerActions m_actions;
|
||||
|
||||
QWidget *m_breakWindow;
|
||||
QWidget *m_returnWindow;
|
||||
QWidget *m_localsWindow;
|
||||
QWidget *m_watchersWindow;
|
||||
QWidget *m_registerWindow;
|
||||
QWidget *m_modulesWindow;
|
||||
QWidget *m_snapshotWindow;
|
||||
SourceFilesWindow *m_sourceFilesWindow;
|
||||
QWidget *m_stackWindow;
|
||||
QWidget *m_threadsWindow;
|
||||
QWidget *m_watchersWindow;
|
||||
DebuggerOutputWindow *m_outputWindow;
|
||||
|
||||
bool m_busy;
|
||||
@@ -401,6 +402,8 @@ void DebuggerManager::init()
|
||||
d->m_sourceFilesWindow->setObjectName(QLatin1String("CppDebugSources"));
|
||||
d->m_threadsWindow = new ThreadsWindow;
|
||||
d->m_threadsWindow->setObjectName(QLatin1String("CppDebugThreads"));
|
||||
d->m_returnWindow = new WatchWindow(WatchWindow::ReturnType, this);
|
||||
d->m_returnWindow->setObjectName(QLatin1String("CppDebugReturn"));
|
||||
d->m_localsWindow = new WatchWindow(WatchWindow::LocalsType, this);
|
||||
d->m_localsWindow->setObjectName(QLatin1String("CppDebugLocals"));
|
||||
d->m_watchersWindow = new WatchWindow(WatchWindow::WatchersType, this);
|
||||
@@ -484,8 +487,13 @@ void DebuggerManager::init()
|
||||
d->m_registerHandler = new RegisterHandler;
|
||||
registerView->setModel(d->m_registerHandler->model());
|
||||
|
||||
// Locals
|
||||
|
||||
// Return Value
|
||||
d->m_watchHandler = new WatchHandler(this);
|
||||
QTreeView *returnView = qobject_cast<QTreeView *>(d->m_returnWindow);
|
||||
returnView->setModel(d->m_watchHandler->model(ReturnWatch));
|
||||
|
||||
// Locals
|
||||
QTreeView *localsView = qobject_cast<QTreeView *>(d->m_localsWindow);
|
||||
localsView->setModel(d->m_watchHandler->model(LocalsWatch));
|
||||
|
||||
@@ -633,6 +641,7 @@ void DebuggerManager::init()
|
||||
localsAndWatchers->setObjectName(QLatin1String("CppDebugLocalsAndWatchers"));
|
||||
localsAndWatchers->setWindowTitle(d->m_localsWindow->windowTitle());
|
||||
localsAndWatchers->addWidget(d->m_localsWindow);
|
||||
localsAndWatchers->addWidget(d->m_returnWindow);
|
||||
localsAndWatchers->addWidget(d->m_watchersWindow);
|
||||
//localsAndWatchers->addWidget(d->m_tooltipWindow);
|
||||
localsAndWatchers->setStretchFactor(0, 3);
|
||||
@@ -1365,6 +1374,7 @@ void DebuggerManager::setBusyCursor(bool busy)
|
||||
|
||||
QCursor cursor(busy ? Qt::BusyCursor : Qt::ArrowCursor);
|
||||
d->m_breakWindow->setCursor(cursor);
|
||||
d->m_returnWindow->setCursor(cursor);
|
||||
d->m_localsWindow->setCursor(cursor);
|
||||
d->m_modulesWindow->setCursor(cursor);
|
||||
d->m_outputWindow->setCursor(cursor);
|
||||
@@ -1947,6 +1957,7 @@ static void changeFontSize(QWidget *widget, int size)
|
||||
void DebuggerManager::fontSettingsChanged(const TextEditor::FontSettings &settings)
|
||||
{
|
||||
int size = settings.fontZoom() * settings.fontSize() / 100;
|
||||
changeFontSize(d->m_returnWindow, size);
|
||||
changeFontSize(d->m_localsWindow, size);
|
||||
changeFontSize(d->m_watchersWindow, size);
|
||||
changeFontSize(d->m_breakWindow, size);
|
||||
@@ -1968,6 +1979,8 @@ void DebuggerManager::updateWatchersWindow()
|
||||
{
|
||||
d->m_watchersWindow->setVisible(
|
||||
d->m_watchHandler->model(WatchersWatch)->rowCount(QModelIndex()) > 0);
|
||||
d->m_returnWindow->setVisible(
|
||||
d->m_watchHandler->model(ReturnWatch)->rowCount(QModelIndex()) > 0);
|
||||
}
|
||||
|
||||
void DebuggerManager::openTextEditor(const QString &titlePattern,
|
||||
|
||||
@@ -274,6 +274,7 @@ void GdbEngine::initializeVariables()
|
||||
m_pendingLogStreamOutput.clear();
|
||||
|
||||
m_inbuffer.clear();
|
||||
m_resultVarName.clear();
|
||||
|
||||
m_commandTimer->stop();
|
||||
|
||||
@@ -1290,7 +1291,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
|
||||
}
|
||||
#endif
|
||||
|
||||
// seen on XP after removing a breakpoint while running
|
||||
// This was seen on XP after removing a breakpoint while running
|
||||
// >945*stopped,reason="signal-received",signal-name="SIGTRAP",
|
||||
// signal-meaning="Trace/breakpoint trap",thread-id="2",
|
||||
// frame={addr="0x7c91120f",func="ntdll!DbgUiConnectToDbg",
|
||||
@@ -1333,6 +1334,18 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
|
||||
}
|
||||
}
|
||||
|
||||
// Show return value if possible, usually with reason "function-finished".
|
||||
// *stopped,reason="function-finished",frame={addr="0x080556da",
|
||||
// func="testReturnValue",args=[],file="/../app.cpp",
|
||||
// fullname="/../app.cpp",line="1611"},gdb-result-var="$1",
|
||||
// return-value="{d = 0x808d998}",thread-id="1",stopped-threads="all",
|
||||
// core="1"
|
||||
GdbMi resultVar = data.findChild("gdb-result-var");
|
||||
if (resultVar.isValid())
|
||||
m_resultVarName = resultVar.data();
|
||||
else
|
||||
m_resultVarName.clear();
|
||||
|
||||
bool initHelpers = m_debuggingHelperState == DebuggingHelperUninitialized
|
||||
|| m_debuggingHelperState == DebuggingHelperLoadTried;
|
||||
// Don't load helpers on stops triggered by signals unless it's
|
||||
|
||||
@@ -170,6 +170,10 @@ private:
|
||||
|
||||
AbstractGdbAdapter *m_gdbAdapter;
|
||||
|
||||
// Name of the convenience variable containing the last
|
||||
// known function return value.
|
||||
QByteArray m_resultVarName;
|
||||
|
||||
private: ////////// Gdb Command Management //////////
|
||||
|
||||
public: // Otherwise the Qt flag macros are unhappy.
|
||||
|
||||
@@ -85,8 +85,12 @@ void GdbEngine::updateLocalsPython(const QByteArray &varList)
|
||||
options += "defaults,";
|
||||
options.chop(1);
|
||||
|
||||
QByteArray resultVar;
|
||||
if (!m_resultVarName.isEmpty())
|
||||
resultVar = "resultvarname:" + m_resultVarName + ' ';
|
||||
|
||||
postCommand("bb options:" + options + " vars:" + varList + ' '
|
||||
+ expanded + " watchers:" + watchers.toHex(),
|
||||
+ resultVar + expanded + " watchers:" + watchers.toHex(),
|
||||
WatchUpdate, CB(handleStackFramePython));
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +120,10 @@ WatchModel::WatchModel(WatchHandler *handler, WatchType type)
|
||||
m_root->parent = 0;
|
||||
|
||||
switch (m_type) {
|
||||
case ReturnWatch:
|
||||
m_root->iname = "return";
|
||||
m_root->name = WatchHandler::tr("Return Value");
|
||||
break;
|
||||
case LocalsWatch:
|
||||
m_root->iname = "local";
|
||||
m_root->name = WatchHandler::tr("Locals");
|
||||
@@ -964,6 +968,7 @@ WatchHandler::WatchHandler(DebuggerManager *manager)
|
||||
m_expandPointers = true;
|
||||
m_inChange = false;
|
||||
|
||||
m_return = new WatchModel(this, ReturnWatch);
|
||||
m_locals = new WatchModel(this, LocalsWatch);
|
||||
m_watchers = new WatchModel(this, WatchersWatch);
|
||||
m_tooltips = new WatchModel(this, TooltipsWatch);
|
||||
@@ -981,6 +986,7 @@ WatchHandler::WatchHandler(DebuggerManager *manager)
|
||||
void WatchHandler::beginCycle()
|
||||
{
|
||||
++generationCounter;
|
||||
m_return->beginCycle();
|
||||
m_locals->beginCycle();
|
||||
m_watchers->beginCycle();
|
||||
m_tooltips->beginCycle();
|
||||
@@ -988,6 +994,7 @@ void WatchHandler::beginCycle()
|
||||
|
||||
void WatchHandler::endCycle()
|
||||
{
|
||||
m_return->endCycle();
|
||||
m_locals->endCycle();
|
||||
m_watchers->endCycle();
|
||||
m_tooltips->endCycle();
|
||||
@@ -997,8 +1004,10 @@ void WatchHandler::endCycle()
|
||||
void WatchHandler::cleanup()
|
||||
{
|
||||
m_expandedINames.clear();
|
||||
m_return->reinitialize();
|
||||
m_locals->reinitialize();
|
||||
m_tooltips->reinitialize();
|
||||
m_return->m_fetchTriggered.clear();
|
||||
m_locals->m_fetchTriggered.clear();
|
||||
m_watchers->m_fetchTriggered.clear();
|
||||
m_tooltips->m_fetchTriggered.clear();
|
||||
@@ -1014,6 +1023,7 @@ void WatchHandler::cleanup()
|
||||
|
||||
void WatchHandler::emitAllChanged()
|
||||
{
|
||||
m_return->emitAllChanged();
|
||||
m_locals->emitAllChanged();
|
||||
m_watchers->emitAllChanged();
|
||||
m_tooltips->emitAllChanged();
|
||||
@@ -1337,6 +1347,7 @@ void WatchHandler::loadSessionData()
|
||||
WatchModel *WatchHandler::model(WatchType type) const
|
||||
{
|
||||
switch (type) {
|
||||
case ReturnWatch: return m_return;
|
||||
case LocalsWatch: return m_locals;
|
||||
case WatchersWatch: return m_watchers;
|
||||
case TooltipsWatch: return m_tooltips;
|
||||
@@ -1347,6 +1358,8 @@ WatchModel *WatchHandler::model(WatchType type) const
|
||||
|
||||
WatchModel *WatchHandler::modelForIName(const QByteArray &iname) const
|
||||
{
|
||||
if (iname.startsWith("return"))
|
||||
return m_return;
|
||||
if (iname.startsWith("local"))
|
||||
return m_locals;
|
||||
if (iname.startsWith("tooltip"))
|
||||
@@ -1374,6 +1387,7 @@ void WatchHandler::setFormat(const QString &type, int format)
|
||||
{
|
||||
m_typeFormats[type] = format;
|
||||
saveTypeFormats();
|
||||
m_return->emitDataChanged(1);
|
||||
m_locals->emitDataChanged(1);
|
||||
m_watchers->emitDataChanged(1);
|
||||
m_tooltips->emitDataChanged(1);
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace Internal {
|
||||
|
||||
class WatchItem;
|
||||
class WatchHandler;
|
||||
enum WatchType { LocalsWatch, WatchersWatch, TooltipsWatch };
|
||||
enum WatchType { ReturnWatch, LocalsWatch, WatchersWatch, TooltipsWatch };
|
||||
|
||||
enum WatchRoles
|
||||
{
|
||||
@@ -206,6 +206,7 @@ private:
|
||||
// Items expanded in the Locals & Watchers view.
|
||||
QSet<QByteArray> m_expandedINames;
|
||||
|
||||
WatchModel *m_return;
|
||||
WatchModel *m_locals;
|
||||
WatchModel *m_watchers;
|
||||
WatchModel *m_tooltips;
|
||||
|
||||
@@ -48,7 +48,7 @@ class WatchWindow : public QTreeView
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Type { LocalsType, TooltipType, WatchersType };
|
||||
enum Type { ReturnType, LocalsType, TooltipType, WatchersType };
|
||||
|
||||
WatchWindow(Type type, DebuggerManager *manager, QWidget *parent = 0);
|
||||
void setType(Type type) { m_type = type; }
|
||||
|
||||
Reference in New Issue
Block a user