Commit 5309e217 authored by hjk's avatar hjk

Debugger: Consolidate GDB and LLDB "updateLocals" code paths

This splits the bool setToolTipExpression() operation into
a bool canHandleToolTip(), and the actual processing of
the request, which is mostly identical to the handling of
a watcher.

Handling a watcher is now mostly the same as a full Locals
update, except for the 'partial' flag. Pushing the handling
of that down to the bridges gives identical code paths
in the gdb and lldbengine. Move that to the
DebuggerEngine base class.

Change-Id: I3861b43e8630c7e7bd57fcd549b2a2387e3d4869
Reviewed-by: default avatarhjk <hjk@theqtcompany.com>
Reviewed-by: default avatarChristian Stenger <christian.stenger@theqtcompany.com>
parent 7d257acb
......@@ -1179,9 +1179,11 @@ class Dumper(DumperBase):
shadowed = {}
ids = {} # Filter out duplicates entries at the same address.
if isPartial:
values = [frame.FindVariable(partialVariable)]
else:
# FIXME: Implement shortcut for partial updates.
#if isPartial:
# values = [frame.FindVariable(partialVariable)]
#else:
if True:
values = list(frame.GetVariables(True, True, False, False))
values.reverse() # To get shadowed vars numbered backwards.
......
......@@ -414,7 +414,7 @@ void CdbEngine::syncVerboseLog(bool verboseLog)
postCommand(m_verboseLog ? QByteArray("!sym noisy") : QByteArray("!sym quiet"), 0);
}
bool CdbEngine::setToolTipExpression(const DebuggerToolTipContext &context)
bool CdbEngine::canHandleToolTip(const DebuggerToolTipContext &context) const
{
Q_UNUSED(context);
// Tooltips matching local variables are already handled in the
......
......@@ -78,7 +78,7 @@ public:
// Factory function that returns 0 if the debug engine library cannot be found.
virtual bool setToolTipExpression(const DebuggerToolTipContext &context);
virtual bool canHandleToolTip(const DebuggerToolTipContext &context) const;
virtual DebuggerEngine *cppEngine() { return this; }
......
......@@ -98,6 +98,17 @@ enum { debug = 0 };
//
///////////////////////////////////////////////////////////////////////
DebuggerRunParameters::DebuggerRunParameters()
: cppEngineType(NoEngineType),
isSnapshot(false),
testCase(0)
{}
void DebuggerRunParameters::initialize(const DebuggerStartParameters &sp)
{
DebuggerStartParameters::operator=(sp);
}
// VariableManager Prefix
const char PrefixDebugExecutable[] = "DebuggedExecutable";
......@@ -402,6 +413,10 @@ void DebuggerEngine::frameDown()
activateFrame(qMax(currentIndex - 1, 0));
}
void DebuggerEngine::doUpdateLocals(const UpdateParameters &)
{
}
void DebuggerEngine::setTargetState(DebuggerState state)
{
d->m_targetState = state;
......@@ -1308,6 +1323,11 @@ DebuggerEngine *DebuggerEngine::masterEngine() const
return d->m_masterEngine;
}
bool DebuggerEngine::canDisplayTooltip() const
{
return state() == InferiorStopOk;
}
QString DebuggerEngine::toFileInProject(const QUrl &fileUrl)
{
// make sure file finder is properly initialized
......@@ -1449,12 +1469,7 @@ Terminal *DebuggerEngine::terminal() const
return &d->m_terminal;
}
bool DebuggerEngine::setToolTipExpression(const DebuggerToolTipContext &)
{
return false;
}
void DebuggerEngine::watchDataSelected(const QByteArray &)
void DebuggerEngine::selectWatchData(const QByteArray &)
{
}
......@@ -1541,6 +1556,13 @@ void DebuggerEngine::createSnapshot()
{
}
void DebuggerEngine::updateLocals()
{
watchHandler()->resetValueCache();
watchHandler()->notifyUpdateStarted();
doUpdateLocals(UpdateParameters());
}
void DebuggerEngine::updateAll()
{
}
......@@ -1983,15 +2005,16 @@ void DebuggerEngine::updateLocalsView(const GdbMi &all)
emit stackFrameCompleted();
}
DebuggerRunParameters::DebuggerRunParameters()
: cppEngineType(NoEngineType),
isSnapshot(false),
testCase(0)
{}
bool DebuggerEngine::canHandleToolTip(const DebuggerToolTipContext &context) const
{
return state() == InferiorStopOk && context.isCppEditor;
}
void DebuggerRunParameters::initialize(const DebuggerStartParameters &sp)
void DebuggerEngine::updateWatchData(const QByteArray &iname)
{
DebuggerStartParameters::operator=(sp);
UpdateParameters params;
params.partialVariable = iname;
doUpdateLocals(params);
}
} // namespace Internal
......
......@@ -108,6 +108,14 @@ public:
int testCase;
};
class UpdateParameters
{
public:
UpdateParameters() {}
QByteArray partialVariable;
};
class Location
{
public:
......@@ -167,10 +175,9 @@ public:
const DebuggerRunParameters &runParameters() const;
DebuggerRunParameters &runParameters();
virtual bool setToolTipExpression(const Internal::DebuggerToolTipContext &);
virtual void updateWatchItem(WatchItem *) {}
virtual void watchDataSelected(const QByteArray &iname);
virtual bool canHandleToolTip(const DebuggerToolTipContext &) const;
virtual void updateWatchData(const QByteArray &iname);
virtual void selectWatchData(const QByteArray &iname);
virtual void startDebugger(DebuggerRunControl *runControl);
......@@ -218,6 +225,7 @@ public:
virtual void createSnapshot();
virtual void updateAll();
virtual void updateLocals();
virtual bool stateAcceptsBreakpointChanges() const { return true; }
virtual void attemptBreakpointSynchronization();
......@@ -282,7 +290,7 @@ public:
DebuggerEngine *masterEngine() const;
virtual DebuggerEngine *cppEngine() { return 0; }
virtual bool canDisplayTooltip() const { return state() == InferiorStopOk; }
virtual bool canDisplayTooltip() const;
virtual void notifyInferiorIll();
......@@ -377,6 +385,8 @@ protected:
virtual void frameUp();
virtual void frameDown();
virtual void doUpdateLocals(const UpdateParameters &params);
void setTargetState(DebuggerState state);
void setMasterEngine(DebuggerEngine *masterEngine);
......@@ -431,6 +441,7 @@ DebuggerRunControl *createAndScheduleRun(const DebuggerRunParameters &rp);
} // namespace Internal
} // namespace Debugger
Q_DECLARE_METATYPE(Debugger::Internal::UpdateParameters)
Q_DECLARE_METATYPE(Debugger::Internal::ContextData)
#endif // DEBUGGER_DEBUGGERENGINE_H
......@@ -1221,8 +1221,9 @@ static void slotTooltipOverrideRequested
tooltip->context.mousePosition = point;
m_tooltips.push_back(tooltip);
tooltip->setState(PendingUnshown);
*handled = engine->setToolTipExpression(context);
if (!*handled) {
if (engine->canHandleToolTip(context)) {
engine->updateWatchData(context.iname);
} else {
ToolTip::show(point, DebuggerToolTipManager::tr("Expression too complex"),
Internal::mainWindow());
tooltip->destroy();
......
......@@ -3693,24 +3693,6 @@ void GdbEngine::handleRegisterListValues(const DebuggerResponse &response)
}
//////////////////////////////////////////////////////////////////////
//
// Tooltip specific stuff
//
//////////////////////////////////////////////////////////////////////
bool GdbEngine::setToolTipExpression(const DebuggerToolTipContext &context)
{
if (state() != InferiorStopOk || !context.isCppEditor)
return false;
UpdateParameters params;
params.partialVariable = context.iname;
doUpdateLocals(params);
return true;
}
//////////////////////////////////////////////////////////////////////
//
// Watch specific stuff
......@@ -3723,13 +3705,6 @@ void GdbEngine::reloadLocals()
updateLocals();
}
void GdbEngine::updateWatchItem(WatchItem *item)
{
UpdateParameters params;
params.partialVariable = item->iname;
doUpdateLocals(params);
}
void GdbEngine::handleVarAssign(const DebuggerResponse &)
{
// Everything might have changed, force re-evaluation.
......@@ -3737,13 +3712,6 @@ void GdbEngine::handleVarAssign(const DebuggerResponse &)
updateLocals();
}
void GdbEngine::updateLocals()
{
watchHandler()->resetValueCache();
watchHandler()->notifyUpdateStarted();
doUpdateLocals(UpdateParameters());
}
void GdbEngine::assignValueInDebugger(WatchItem *item,
const QString &expression, const QVariant &value)
{
......@@ -4744,14 +4712,14 @@ void GdbEngine::doUpdateLocals(const UpdateParameters &params)
cmd.arg("resultvarname", m_resultVarName);
cmd.arg("partialVariable", params.partialVariable);
cmd.flags = Discardable;
cmd.callback = [this, params](const DebuggerResponse &r) { handleStackFramePython(r); };
cmd.callback = [this, params](const DebuggerResponse &r) { handleStackFrame(r); };
runCommand(cmd);
cmd.arg("passExceptions", true);
m_lastDebuggableCommand = cmd;
}
void GdbEngine::handleStackFramePython(const DebuggerResponse &response)
void GdbEngine::handleStackFrame(const DebuggerResponse &response)
{
watchHandler()->notifyUpdateFinished();
if (response.resultClass == ResultDone) {
......
......@@ -381,7 +381,6 @@ protected:
//
// Watch specific stuff
//
virtual bool setToolTipExpression(const DebuggerToolTipContext &);
virtual void assignValueInDebugger(WatchItem *item,
const QString &expr, const QVariant &value);
......@@ -396,7 +395,6 @@ protected:
virtual void watchPoint(const QPoint &);
void handleWatchPoint(const DebuggerResponse &response);
void updateWatchItem(WatchItem *item);
void showToolTip();
void handleVarAssign(const DebuggerResponse &response);
......@@ -407,9 +405,8 @@ protected:
Q_SLOT void createFullBacktrace();
void handleCreateFullBacktrace(const DebuggerResponse &response);
void updateLocals();
void doUpdateLocals(const UpdateParameters &parameters);
void handleStackFramePython(const DebuggerResponse &response);
void doUpdateLocals(const UpdateParameters &parameters);
void handleStackFrame(const DebuggerResponse &response);
void setLocals(const QList<GdbMi> &locals);
......
......@@ -814,19 +814,9 @@ void LldbEngine::refreshSymbols(const GdbMi &symbols)
//
//////////////////////////////////////////////////////////////////////
bool LldbEngine::setToolTipExpression(const DebuggerToolTipContext &context)
bool LldbEngine::canHandleToolTip(const DebuggerToolTipContext &context) const
{
if (state() != InferiorStopOk || !context.isCppEditor) {
//qDebug() << "SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED "
// " OR NOT A CPPEDITOR";
return false;
}
UpdateParameters params;
params.partialVariable = context.iname;
doUpdateLocals(params);
return true;
return state() == InferiorStopOk && context.isCppEditor;
}
void LldbEngine::updateAll()
......@@ -867,19 +857,7 @@ void LldbEngine::assignValueInDebugger(WatchItem *,
runCommand(cmd);
}
void LldbEngine::updateWatchItem(WatchItem *)
{
doUpdateLocals(UpdateParameters());
}
void LldbEngine::updateLocals()
{
watchHandler()->resetValueCache();
watchHandler()->notifyUpdateStarted();
doUpdateLocals(UpdateParameters());
}
void LldbEngine::doUpdateLocals(UpdateParameters params)
void LldbEngine::doUpdateLocals(const UpdateParameters &params)
{
if (stackHandler()->stackSize() == 0) {
showMessage(_("SKIPPING LOCALS DUE TO EMPTY STACK"));
......
......@@ -87,7 +87,7 @@ private:
void shutdownEngine();
void abortDebugger();
bool setToolTipExpression(const DebuggerToolTipContext &);
bool canHandleToolTip(const DebuggerToolTipContext &) const;
void continueInferior();
void interruptInferior();
......@@ -122,7 +122,6 @@ private:
bool supportsThreads() const { return true; }
bool isSynchronous() const { return true; }
void updateWatchItem(WatchItem *item);
void setRegisterValue(const QByteArray &name, const QString &value);
void fetchMemory(Internal::MemoryAgent *, QObject *, quint64 addr, quint64 length);
......@@ -142,9 +141,8 @@ private:
void readLldbStandardError();
void handleResponse(const QByteArray &data);
void updateAll();
void updateLocals();
void createFullBacktrace();
void doUpdateLocals(UpdateParameters params);
void doUpdateLocals(const UpdateParameters &params);
void handleContinuation(const GdbMi &data);
void refreshAll(const GdbMi &all);
......
......@@ -378,16 +378,9 @@ void PdbEngine::refreshSymbols(const GdbMi &symbols)
Internal::showModuleSymbols(moduleName, syms);
}
bool PdbEngine::setToolTipExpression(const DebuggerToolTipContext &ctx)
bool PdbEngine::canHandleToolTip(const DebuggerToolTipContext &) const
{
if (state() != InferiorStopOk)
return false;
DebuggerCommand cmd("evaluateTooltip");
ctx.appendFormatRequest(&cmd);
watchHandler()->appendFormatRequests(&cmd);
runCommand(cmd);
return true;
return state() == InferiorStopOk;
}
void PdbEngine::assignValueInDebugger(WatchItem *, const QString &expression, const QVariant &value)
......@@ -401,9 +394,9 @@ void PdbEngine::assignValueInDebugger(WatchItem *, const QString &expression, co
updateLocals();
}
void PdbEngine::updateWatchItem(WatchItem *item)
void PdbEngine::updateWatchData(const QByteArray &iname)
{
Q_UNUSED(item);
Q_UNUSED(iname);
updateAll();
}
......
......@@ -66,7 +66,7 @@ private:
void shutdownInferior();
void shutdownEngine();
bool setToolTipExpression(const DebuggerToolTipContext &);
bool canHandleToolTip(const DebuggerToolTipContext &) const;
void continueInferior();
void interruptInferior();
......@@ -96,7 +96,7 @@ private:
bool supportsThreads() const { return true; }
bool isSynchronous() const { return true; }
void updateWatchItem(WatchItem *item);
void updateWatchData(const QByteArray &iname);
QString mainPythonFile() const;
QString pythonInterpreter() const;
......
......@@ -102,29 +102,28 @@ bool QmlCppEngine::canDisplayTooltip() const
return m_cppEngine->canDisplayTooltip() || m_qmlEngine->canDisplayTooltip();
}
bool QmlCppEngine::setToolTipExpression(const DebuggerToolTipContext &ctx)
bool QmlCppEngine::canHandleToolTip(const DebuggerToolTipContext &ctx) const
{
bool success = false;
if (ctx.isCppEditor)
success = m_cppEngine->setToolTipExpression(ctx);
success = m_cppEngine->canHandleToolTip(ctx);
else
success = m_qmlEngine->setToolTipExpression(ctx);
success = m_qmlEngine->canHandleToolTip(ctx);
return success;
}
void QmlCppEngine::updateWatchItem(WatchItem *item)
void QmlCppEngine::updateWatchData(const QByteArray &iname)
{
if (item->isInspect())
m_qmlEngine->updateWatchItem(item);
if (iname.startsWith("inspect."))
m_qmlEngine->updateWatchData(iname);
else
m_activeEngine->updateWatchItem(item);
m_activeEngine->updateWatchData(iname);
}
void QmlCppEngine::watchDataSelected(const QByteArray &iname)
void QmlCppEngine::selectWatchData(const QByteArray &iname)
{
const WatchItem *item = watchHandler()->findItem(iname);
if (item && item->isInspect())
m_qmlEngine->watchDataSelected(iname);
if (iname.startsWith("inspect."))
m_qmlEngine->selectWatchData(iname);
}
void QmlCppEngine::watchPoint(const QPoint &point)
......
......@@ -47,9 +47,9 @@ public:
~QmlCppEngine();
bool canDisplayTooltip() const;
bool setToolTipExpression(const DebuggerToolTipContext &);
void updateWatchItem(WatchItem *item);
void watchDataSelected(const QByteArray &iname);
bool canHandleToolTip(const DebuggerToolTipContext &) const;
void updateWatchData(const QByteArray &iname);
void selectWatchData(const QByteArray &iname);
void watchPoint(const QPoint &);
void fetchMemory(MemoryAgent *, QObject *, quint64 addr, quint64 length);
......
......@@ -973,12 +973,11 @@ void QmlEngine::requestModuleSymbols(const QString &moduleName)
//
//////////////////////////////////////////////////////////////////////
bool QmlEngine::setToolTipExpression(const DebuggerToolTipContext &context)
bool QmlEngine::canHandleToolTip(const DebuggerToolTipContext &) const
{
// This is processed by QML inspector, which has dependencies to
// the qml js editor. Makes life easier.
// FIXME: Except that there isn't any attached.
emit tooltipRequested(context);
return true;
}
......@@ -999,11 +998,12 @@ void QmlEngine::assignValueInDebugger(WatchItem *item,
}
}
void QmlEngine::updateWatchItem(WatchItem *item)
void QmlEngine::updateWatchData(const QByteArray &iname)
{
// qDebug() << "UPDATE WATCH DATA" << data.toString();
//showStatusMessage(tr("Stopped."), 5000);
const WatchItem *item = watchHandler()->findItem(iname);
QTC_ASSERT(item, return);
if (item->isInspect()) {
m_inspectorAdapter.agent()->updateWatchData(*item);
} else {
......@@ -1018,7 +1018,7 @@ void QmlEngine::updateWatchItem(WatchItem *item)
}
}
void QmlEngine::watchDataSelected(const QByteArray &iname)
void QmlEngine::selectWatchData(const QByteArray &iname)
{
const WatchItem *item = watchHandler()->findItem(iname);
if (item && item->isInspect())
......
......@@ -89,9 +89,6 @@ public:
void insertBreakpoint(Breakpoint bp);
signals:
void tooltipRequested(const DebuggerToolTipContext &context);
private slots:
void disconnected();
void documentUpdated(QmlJS::Document::Ptr doc);
......@@ -128,7 +125,7 @@ private:
void shutdownInferior();
void shutdownEngine();
bool setToolTipExpression(const DebuggerToolTipContext &);
bool canHandleToolTip(const DebuggerToolTipContext &) const;
void continueInferior();
void interruptInferior();
......@@ -157,8 +154,8 @@ private:
void reloadFullStack() {}
bool supportsThreads() const { return false; }
void updateWatchItem(WatchItem *item);
void watchDataSelected(const QByteArray &iname);
void updateWatchData(const QByteArray &iname);
void selectWatchData(const QByteArray &iname);
void executeDebuggerCommand(const QString &command, DebuggerLanguages languages);
bool evaluateScript(const QString &expression);
......
......@@ -683,7 +683,7 @@ void WatchItem::fetchMore()
model->m_fetchTriggered.insert(iname);
if (children().isEmpty()) {
setChildrenNeeded();
model->m_engine->updateWatchItem(this);
model->m_engine->updateWatchData(iname);
}
}
......@@ -940,12 +940,12 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role
case LocalsTypeFormatRole:
setTypeFormat(item->type, value.toInt());
m_engine->updateWatchItem(item);
m_engine->updateWatchData(item->iname);
break;
case LocalsIndividualFormatRole: {
setIndividualFormat(item->iname, value.toInt());
m_engine->updateWatchItem(item);
m_engine->updateWatchData(item->iname);
break;
}
}
......@@ -1281,7 +1281,7 @@ void WatchHandler::watchExpression(const QString &exp0, const QString &name)
item->setValue(QString(QLatin1Char(' ')));
m_model->insertItem(item);
} else {
m_model->m_engine->updateWatchItem(item);
m_model->m_engine->updateWatchData(item->iname);
}
updateWatchersWindow();
}
......
......@@ -125,14 +125,6 @@ private:
void parseWatchData(const GdbMi &input);
};
class UpdateParameters
{
public:
UpdateParameters() {}
QByteArray partialVariable;
};
class WatchModelBase : public Utils::TreeModel
{
Q_OBJECT
......@@ -216,7 +208,6 @@ private:
} // namespace Internal
} // namespace Debugger
Q_DECLARE_METATYPE(Debugger::Internal::UpdateParameters)
Q_DECLARE_METATYPE(Debugger::Internal::DisplayFormats)
#endif // DEBUGGER_WATCHHANDLER_H
......@@ -961,7 +961,7 @@ void WatchTreeView::setModel(QAbstractItemModel *model)
void WatchTreeView::rowActivated(const QModelIndex &index)
{
currentEngine()->watchDataSelected(index.data(LocalsINameRole).toByteArray());
currentEngine()->selectWatchData(index.data(LocalsINameRole).toByteArray());
}
void WatchTreeView::handleItemIsExpanded(const QModelIndex &idx)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment