Commit e11a3a76 authored by hjk's avatar hjk

debugger: rework WatchModel

It's one model for all locals, watch, return, tooltip and inspector
data. This allows more streamlined code paths and better isolation
of the model data from the WatchHandler. WatchItems are now registered
in a hash indexed by iname, so inames can be used as the primary
handle to watch data in the WatchHandler interface.

Change-Id: Idac0a808b5d785307496d1de4198a1f2e9ce3880
Reviewed-by: default avatarAurindam Jana <aurindam.jana@nokia.com>
parent c14c1248
......@@ -2397,6 +2397,14 @@ def qdump__Debugger__Internal__GdbMi(d, value):
d.putByteArrayValue(value["m_data"])
d.putPlainChildren(value)
def qdump__Debugger__Internal__WatchData(d, value):
d.putByteArrayValue(value["iname"])
d.putPlainChildren(value)
def qdump__Debugger__Internal__WatchItem(d, value):
d.putByteArrayValue(value["iname"])
d.putPlainChildren(value)
def qdump__CPlusPlus__ByteArrayRef(d, value):
d.putValue(encodeCharArray(value["m_start"], 100, value["m_length"]),
Hex2EncodedLatin1)
......
......@@ -98,6 +98,12 @@ enum { debugSourceMapping = 0 };
enum { debugWatches = 0 };
enum { debugBreakpoints = 0 };
enum HandleLocalsFlags
{
PartialLocalsUpdate = 0x1,
LocalsUpdateForNewFrame = 0x2
};
#if 0
# define STATE_DEBUG(state, func, line, notifyFunc) qDebug("%s in %s at %s:%d", notifyFunc, stateName(state), func, line);
#else
......@@ -550,18 +556,16 @@ bool CdbEngine::setToolTipExpression(const QPoint &mousePos,
// Can this be found as a local variable?
const QByteArray localsPrefix(localsPrefixC);
QByteArray iname = localsPrefix + exp.toAscii();
QModelIndex index = watchHandler()->itemIndex(iname);
if (!index.isValid()) {
if (!watchHandler()->hasItem(iname)) {
// Nope, try a 'local.this.m_foo'.
exp.prepend(QLatin1String("this."));
iname.insert(localsPrefix.size(), "this.");
index = watchHandler()->itemIndex(iname);
if (!index.isValid())
if (!watchHandler()->hasItem(iname))
return false;
}
DebuggerToolTipWidget *tw = new DebuggerToolTipWidget;
tw->setContext(context);
tw->setDebuggerModel(LocalsWatch);
tw->setDebuggerModel(LocalsType);
tw->setExpression(exp);
tw->acquireEngine(this);
DebuggerToolTipManager::instance()->showToolTip(mousePos, editor, tw);
......@@ -1048,7 +1052,7 @@ void CdbEngine::handleAddWatch(const CdbExtensionCommandPtr &reply)
updateLocalVariable(item.iname);
} else {
item.setError(tr("Unable to add expression"));
watchHandler()->insertData(item);
watchHandler()->insertIncompleteData(item);
showMessage(QString::fromLatin1("Unable to add watch item '%1'/'%2': %3").
arg(QString::fromLatin1(item.iname), QString::fromLatin1(item.exp),
QString::fromLocal8Bit(reply->errorMessage)), LogError);
......@@ -1086,7 +1090,10 @@ void CdbEngine::updateLocalVariable(const QByteArray &iname)
str << blankSeparator << stackFrame;
}
str << blankSeparator << iname;
postExtensionCommand(isWatch ? "watches" : "locals", localsArguments, 0, &CdbEngine::handleLocals);
postExtensionCommand(isWatch ? "watches" : "locals",
localsArguments, 0,
&CdbEngine::handleLocals,
0, QVariant(int(PartialLocalsUpdate)));
}
bool CdbEngine::hasCapability(unsigned cap) const
......@@ -1465,8 +1472,7 @@ void CdbEngine::activateFrame(int index)
stackHandler()->setCurrentIndex(index);
const bool showAssembler = !frames.at(index).isUsable();
if (showAssembler) { // Assembly code: Clean out model and force instruction mode.
watchHandler()->beginCycle();
watchHandler()->endCycle();
watchHandler()->removeAllData();
QAction *assemblerAction = theAssemblerAction();
if (assemblerAction->isChecked()) {
gotoLocation(frame);
......@@ -1485,14 +1491,12 @@ void CdbEngine::updateLocals(bool forNewStackFrame)
const int frameIndex = stackHandler()->currentIndex();
if (frameIndex < 0) {
watchHandler()->beginCycle();
watchHandler()->endCycle();
watchHandler()->removeAllData();
return;
}
const StackFrame frame = stackHandler()->currentFrame();
if (!frame.isUsable()) {
watchHandler()->beginCycle();
watchHandler()->endCycle();
watchHandler()->removeAllData();
return;
}
/* Watchers: Forcibly discard old symbol group as switching from
......@@ -1542,9 +1546,11 @@ void CdbEngine::updateLocals(bool forNewStackFrame)
}
// Required arguments: frame
const int flags = forNewStackFrame ? LocalsUpdateForNewFrame : 0;
str << blankSeparator << frameIndex;
watchHandler()->beginCycle();
postExtensionCommand("locals", arguments, 0, &CdbEngine::handleLocals, 0, QVariant(forNewStackFrame));
postExtensionCommand("locals", arguments, 0,
&CdbEngine::handleLocals, 0,
QVariant(flags));
}
void CdbEngine::selectThread(int index)
......@@ -1925,6 +1931,9 @@ void CdbEngine::handleRegisters(const CdbExtensionCommandPtr &reply)
void CdbEngine::handleLocals(const CdbExtensionCommandPtr &reply)
{
const int flags = reply->cookie.toInt();
if (!(flags & PartialLocalsUpdate))
watchHandler()->removeAllData();
if (reply->success) {
QList<WatchData> watchData;
GdbMi root;
......@@ -1940,16 +1949,14 @@ void CdbEngine::handleLocals(const CdbExtensionCommandPtr &reply)
dummy.name = QLatin1String(child.findChild("name").data());
parseWatchData(watchHandler()->expandedINames(), dummy, child, &watchData);
}
watchHandler()->insertBulkData(watchData);
watchHandler()->endCycle();
watchHandler()->insertData(watchData);
if (debugLocals) {
QDebug nsp = qDebug().nospace();
nsp << "Obtained " << watchData.size() << " items:\n";
foreach (const WatchData &wd, watchData)
nsp << wd.toString() <<'\n';
}
const bool forNewStackFrame = reply->cookie.toBool();
if (forNewStackFrame)
if (flags & LocalsUpdateForNewFrame)
emit stackFrameCompleted();
} else {
showMessage(QString::fromLatin1(reply->errorMessage), LogWarning);
......
......@@ -85,7 +85,7 @@ public:
virtual QVariant configValue(const QString &name) const = 0;
virtual void setConfigValue(const QString &name, const QVariant &value) = 0;
virtual void updateState(DebuggerEngine *engine) = 0;
virtual void updateWatchersWindow() = 0;
virtual void updateWatchersWindow(bool showWatch, bool showReturn) = 0;
virtual void showQtDumperLibraryWarning(const QString &details) = 0;
virtual QIcon locationMarkIcon() const = 0;
virtual const CPlusPlus::Snapshot &cppCodeModelSnapshot() const = 0;
......
......@@ -491,42 +491,32 @@ QAbstractItemModel *DebuggerEngine::threadsModel() const
QAbstractItemModel *DebuggerEngine::localsModel() const
{
QAbstractItemModel *model = watchHandler()->model(LocalsWatch);
if (model->objectName().isEmpty()) // Make debugging easier.
model->setObjectName(objectName() + QLatin1String("LocalsModel"));
return model;
return watchHandler()->model();
}
QAbstractItemModel *DebuggerEngine::watchersModel() const
{
QAbstractItemModel *model = watchHandler()->model(WatchersWatch);
if (model->objectName().isEmpty()) // Make debugging easier.
model->setObjectName(objectName() + QLatin1String("WatchersModel"));
return model;
return watchHandler()->model();
}
QAbstractItemModel *DebuggerEngine::returnModel() const
{
QAbstractItemModel *model = watchHandler()->model(ReturnWatch);
if (model->objectName().isEmpty()) // Make debugging easier.
model->setObjectName(objectName() + QLatin1String("ReturnModel"));
return model;
return watchHandler()->model();
}
QAbstractItemModel *DebuggerEngine::inspectorModel() const
{
QAbstractItemModel *model = watchHandler()->model(InspectWatch);
if (model->objectName().isEmpty()) // Make debugging easier.
model->setObjectName(objectName() + QLatin1String("InspectorModel"));
return model;
return watchHandler()->model();
}
QAbstractItemModel *DebuggerEngine::toolTipsModel() const
{
QAbstractItemModel *model = watchHandler()->model(TooltipsWatch);
if (model->objectName().isEmpty()) // Make debugging easier.
model->setObjectName(objectName() + QLatin1String("TooltipsModel"));
return model;
return watchHandler()->model();
}
QAbstractItemModel *DebuggerEngine::watchModel() const
{
return watchHandler()->model();
}
QAbstractItemModel *DebuggerEngine::sourceFilesModel() const
......
......@@ -229,11 +229,12 @@ public:
virtual QAbstractItemModel *registerModel() const;
virtual QAbstractItemModel *stackModel() const;
virtual QAbstractItemModel *threadsModel() const;
virtual QAbstractItemModel *localsModel() const;
virtual QAbstractItemModel *watchersModel() const;
virtual QAbstractItemModel *returnModel() const;
virtual QAbstractItemModel *inspectorModel() const;
virtual QAbstractItemModel *toolTipsModel() const;
virtual QAbstractItemModel *localsModel() const; // Deprecated, FIXME: use watchModel
virtual QAbstractItemModel *watchersModel() const; // Deprecated, FIXME: use watchModel
virtual QAbstractItemModel *returnModel() const; // Deprecated, FIXME: use watchModel
virtual QAbstractItemModel *inspectorModel() const; // Deprecated, FIXME: use watchModel
virtual QAbstractItemModel *toolTipsModel() const; // Deprecated, FIXME: use watchModel
virtual QAbstractItemModel *watchModel() const;
virtual QAbstractItemModel *sourceFilesModel() const;
virtual QAbstractItemModel *qtMessageLogModel() const;
......
......@@ -815,7 +815,7 @@ public slots:
void fontSettingsChanged(const TextEditor::FontSettings &settings);
void updateState(DebuggerEngine *engine);
void updateWatchersWindow();
void updateWatchersWindow(bool showWatch, bool showReturn);
void onCurrentProjectChanged(ProjectExplorer::Project *project);
void sessionLoaded();
......@@ -2238,12 +2238,10 @@ void DebuggerPluginPrivate::setInitialState()
m_qtMessageLogWindow->setEnabled(true);
}
void DebuggerPluginPrivate::updateWatchersWindow()
void DebuggerPluginPrivate::updateWatchersWindow(bool showWatch, bool showReturn)
{
m_watchersWindow->setVisible(
m_watchersWindow->model()->rowCount(QModelIndex()) > 0);
m_returnWindow->setVisible(
m_returnWindow->model()->rowCount(QModelIndex()) > 0);
m_watchersWindow->setVisible(showWatch);
m_returnWindow->setVisible(showReturn);
}
void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
......@@ -2254,8 +2252,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
QTC_ASSERT(!engine->isSlaveEngine(), return);
m_threadBox->setCurrentIndex(engine->threadsHandler()->currentThread());
updateWatchersWindow();
engine->watchHandler()->updateWatchersWindow();
const DebuggerState state = engine->state();
//showMessage(QString("PLUGIN SET STATE: ")
......
......@@ -230,7 +230,6 @@ QDataStream &operator<<(QDataStream &stream, const WatchData &wd)
stream << wd.address;
stream << wd.size;
stream << wd.hasChildren;
stream << wd.generation;
stream << wd.valueEnabled;
stream << wd.valueEditable;
stream << wd.error;
......@@ -256,7 +255,6 @@ QDataStream &operator>>(QDataStream &stream, WatchData &wd)
stream >> wd.address;
stream >> wd.size;
stream >> wd.hasChildren;
stream >> wd.generation;
stream >> wd.valueEnabled;
stream >> wd.valueEditable;
stream >> wd.error;
......
......@@ -31,6 +31,7 @@
**************************************************************************/
#include "debuggertooltipmanager.h"
#include "debuggerinternalconstants.h"
#include "watchutils.h"
#include "debuggerengine.h"
#include "debuggeractions.h"
......@@ -617,7 +618,7 @@ DebuggerToolTipWidget::DebuggerToolTipWidget(QWidget *parent) :
m_titleLabel(new DraggableLabel),
m_engineAcquired(false),
m_creationDate(QDate::currentDate()),
m_debuggerModel(TooltipsWatch),
m_debuggerModel(TooltipType),
m_treeView(new DebuggerToolTipTreeView),
m_defaultModel(new QStandardItemModel(this))
{
......@@ -664,7 +665,7 @@ bool DebuggerToolTipWidget::matches(const QString &fileName,
return function == m_context.function;
}
void DebuggerToolTipWidget::acquireEngine(Debugger::DebuggerEngine *engine)
void DebuggerToolTipWidget::acquireEngine(DebuggerEngine *engine)
{
QTC_ASSERT(engine, return);
......@@ -836,7 +837,7 @@ void DebuggerToolTipWidget::saveSessionData(QXmlStreamWriter &w) const
}
/*!
\class Debugger::Internal::DebuggerToolTipExpressionFilterModel
\class Debugger::Internal::TooltipFilterModel
\brief Model for tooltips filtering a local variable using the locals or tooltip model,
matching on the name.
......@@ -847,50 +848,46 @@ void DebuggerToolTipWidget::saveSessionData(QXmlStreamWriter &w) const
In addition, suppress the model's tooltip data to avoid a tooltip on a tooltip.
*/
class DebuggerToolTipExpressionFilterModel : public QSortFilterProxyModel
class TooltipFilterModel : public QSortFilterProxyModel
{
public:
explicit DebuggerToolTipExpressionFilterModel(QAbstractItemModel *model, const QString &exp, QObject *parent = 0);
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
TooltipFilterModel(QAbstractItemModel *model, const QString &exp, int debuggerModel) :
m_expressions(exp.split(QLatin1Char('.'))),
m_debuggerModel(debuggerModel)
{
setSourceModel(model);
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
{
return role == Qt::ToolTipRole
? QVariant() : QSortFilterProxyModel::data(index, role);
}
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
private:
const QStringList m_expressions;
int m_debuggerModel;
};
DebuggerToolTipExpressionFilterModel::DebuggerToolTipExpressionFilterModel(QAbstractItemModel *model,
const QString &exp,
QObject *parent) :
QSortFilterProxyModel(parent),
m_expressions(exp.split(QLatin1Char('.')))
{
setSourceModel(model);
}
QVariant DebuggerToolTipExpressionFilterModel::data(const QModelIndex &index, int role) const
{
return role != Qt::ToolTipRole ?
QSortFilterProxyModel::data(index, role) : QVariant();
}
// Return depth of a model index, that is, 0 for root index, 1 for level-1 children, etc.
static inline int indexDepth(QModelIndex index)
{
int depth = 0;
for ( ; index.isValid() ; index = index.parent())
depth++;
return depth;
}
bool DebuggerToolTipExpressionFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
bool TooltipFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
const QModelIndex nameIndex = sourceModel()->index(sourceRow, 0, sourceParent);
QByteArray iname = nameIndex.data(LocalsINameRole).toByteArray();
if (m_debuggerModel == LocalsType && !iname.startsWith("local"))
return false;
if (m_debuggerModel == TooltipType && !iname.startsWith("tooltip"))
return false;
// Match on expression for top level, else pass through.
const int depth = indexDepth(sourceParent);
if (depth >= m_expressions.size()) // No filters at this level
const int depth = iname.count('.');
if (depth == 0)
return true;
const QModelIndex nameIndex = sourceModel()->index(sourceRow, 0, sourceParent);
return nameIndex.data().toString() == m_expressions.at(depth);
if (depth > m_expressions.size())
return true;
const QString name = nameIndex.data().toString();
//const QString exp = nameIndex.data(LocalsExpressionRole).toString();
return name == m_expressions.at(depth - 1);
}
/*!
......@@ -924,6 +921,7 @@ QAbstractItemModel *DebuggerToolTipTreeView::swapModel(QAbstractItemModel *newMo
if (previousModel)
previousModel->disconnect(SIGNAL(rowsInserted(QModelIndex,int,int)), this);
setModel(newModel);
//setRootIndex(newModel->index(0, 0));
connect(newModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(computeSize()), Qt::QueuedConnection);
computeSize();
......@@ -991,24 +989,12 @@ void DebuggerToolTipTreeView::computeSize()
setRootIsDecorated(rootDecorated);
}
void DebuggerToolTipWidget::doAcquireEngine(Debugger::DebuggerEngine *engine)
void DebuggerToolTipWidget::doAcquireEngine(DebuggerEngine *engine)
{
// Create a filter model on the debugger's model and switch to it.
QAbstractItemModel *model = 0;
switch (m_debuggerModel) {
case LocalsWatch:
model = engine->localsModel();
break;
case WatchersWatch:
model = engine->watchersModel();
break;
case TooltipsWatch:
model = engine->toolTipsModel();
break;
}
QTC_ASSERT(model, return);
DebuggerToolTipExpressionFilterModel *filterModel =
new DebuggerToolTipExpressionFilterModel(model, m_expression);
QAbstractItemModel *model = engine->watchModel();
TooltipFilterModel *filterModel =
new TooltipFilterModel(model, m_expression, m_debuggerModel);
swapModel(filterModel);
}
......@@ -1311,7 +1297,7 @@ void DebuggerToolTipManager::slotUpdateVisibleToolTips()
}
}
void DebuggerToolTipManager::slotDebuggerStateChanged(Debugger::DebuggerState state)
void DebuggerToolTipManager::slotDebuggerStateChanged(DebuggerState state)
{
const QObject *engine = sender();
QTC_ASSERT(engine, return);
......@@ -1319,7 +1305,7 @@ void DebuggerToolTipManager::slotDebuggerStateChanged(Debugger::DebuggerState st
const QString name = engine->objectName();
if (debugToolTips)
qDebug() << "DebuggerToolTipWidget::debuggerStateChanged"
<< engine << Debugger::DebuggerEngine::stateName(state);
<< engine << DebuggerEngine::stateName(state);
// Release at earliest possible convenience.
switch (state) {
......
......@@ -63,8 +63,11 @@ void AbstractPlainGdbAdapter::setupInferior()
QString args = startParameters().processArgs;
m_engine->postCommand("-exec-arguments " + toLocalEncoding(args));
}
m_engine->postCommand("-file-exec-and-symbols \"" + execFilePath() + '"',
CB(handleFileExecAndSymbols));
if (m_engine->gdbVersion() > 70000)
m_engine->postCommand("-file-exec-and-symbols \"" + execFilePath() + '"',
CB(handleFileExecAndSymbols));
else
m_engine->postCommand("file " + execFilePath(), CB(handleFileExecAndSymbols));
}
void AbstractPlainGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response)
......
......@@ -716,7 +716,7 @@ static bool parseConsoleStream(const GdbResponse &response, GdbMi *contents)
void GdbEngine::updateLocalsClassic()
{
PRECONDITION;
m_pendingWatchRequests = 0;
//m_pendingWatchRequests = 0;
m_pendingBreakpointRequests = 0;
m_processedNames.clear();
......@@ -724,15 +724,14 @@ void GdbEngine::updateLocalsClassic()
qDebug() << "\nRESET PENDING";
//m_toolTipCache.clear();
clearToolTip();
watchHandler()->beginCycle();
QByteArray level = QByteArray::number(currentFrame());
// '2' is 'list with type and value'
QByteArray cmd = "-stack-list-arguments 2 " + level + ' ' + level;
postCommand(cmd, WatchUpdate,
postCommand(cmd, Discardable,
CB(handleStackListArgumentsClassic));
// '2' is 'list with type and value'
postCommand("-stack-list-locals 2", WatchUpdate,
postCommand("-stack-list-locals 2", Discardable,
CB(handleStackListLocalsClassic)); // stage 2/2
}
......@@ -754,9 +753,9 @@ void GdbEngine::runDirectDebuggingHelperClassic(const WatchData &data, bool dump
QVariant var;
var.setValue(data);
postCommand(cmd, WatchUpdate, CB(handleDebuggingHelperValue3Classic), var);
postCommand(cmd, Discardable, CB(handleDebuggingHelperValue3Classic), var);
showStatusMessage(msgRetrievingWatchData(m_pendingWatchRequests + 1), 10000);
showStatusMessage(msgRetrievingWatchData(m_uncompleted.size()), 10000);
}
void GdbEngine::runDebuggingHelperClassic(const WatchData &data0, bool dumpChildren)
......@@ -811,25 +810,25 @@ void GdbEngine::runDebuggingHelperClassic(const WatchData &data0, bool dumpChild
cmd += ',' + ex;
cmd += ')';
postCommand(cmd, WatchUpdate | NonCriticalResponse);
postCommand(cmd, Discardable | NonCriticalResponse);
showStatusMessage(msgRetrievingWatchData(m_pendingWatchRequests + 1), 10000);
showStatusMessage(msgRetrievingWatchData(m_uncompleted.size()), 10000);
// retrieve response
postCommand("p (char*)&qDumpOutBuffer", WatchUpdate,
postCommand("p (char*)&qDumpOutBuffer", Discardable,
CB(handleDebuggingHelperValue2Classic), qVariantFromValue(data));
}
void GdbEngine::createGdbVariableClassic(const WatchData &data)
{
PRECONDITION;
postCommand("-var-delete \"" + data.iname + '"', WatchUpdate);
postCommand("-var-delete \"" + data.iname + '"', Discardable);
QByteArray exp = data.exp;
if (exp.isEmpty() && data.address)
exp = "*(" + gdbQuoteTypes(data.type) + "*)" + data.hexAddress();
QVariant val = QVariant::fromValue<WatchData>(data);
postCommand("-var-create \"" + data.iname + "\" * \"" + exp + '"',
WatchUpdate, CB(handleVarCreate), val);
Discardable, CB(handleVarCreate), val);
}
void GdbEngine::updateSubItemClassic(const WatchData &data0)
......@@ -929,7 +928,7 @@ void GdbEngine::updateSubItemClassic(const WatchData &data0)
if (debugSubItem)
qDebug() << "UPDATE SUBITEM: VALUE";
QByteArray cmd = "-var-evaluate-expression \"" + data.iname + '"';
postCommand(cmd, WatchUpdate,
postCommand(cmd, Discardable,
CB(handleEvaluateExpressionClassic), QVariant::fromValue(data));
return;
}
......@@ -953,7 +952,7 @@ void GdbEngine::updateSubItemClassic(const WatchData &data0)
if (data.isChildrenNeeded()) {
QTC_ASSERT(!data.variable.isEmpty(), return); // tested above
QByteArray cmd = "-var-list-children --all-values \"" + data.variable + '"';
postCommand(cmd, WatchUpdate,
postCommand(cmd, Discardable,
CB(handleVarListChildrenClassic), QVariant::fromValue(data));
return;
}
......@@ -999,7 +998,7 @@ void GdbEngine::handleDebuggingHelperValue2Classic(const GdbResponse &response)
if (m_cookieForToken.contains(response.token - 1)) {
m_cookieForToken.remove(response.token - 1);
showMessage(_("DETECTING LOST COMMAND %1").arg(response.token - 1));
--m_pendingWatchRequests;
// --m_pendingWatchRequests;
data.setError(WatchData::msgNotInScope());
insertData(data);
return;
......@@ -1025,7 +1024,7 @@ void GdbEngine::handleDebuggingHelperValue2Classic(const GdbResponse &response)
parseWatchData(watchHandler()->expandedINames(), data, contents, &list);
//for (int i = 0; i != list.size(); ++i)
// qDebug() << "READ: " << list.at(i).toString();
watchHandler()->insertBulkData(list);
watchHandler()->insertData(list);
}
void GdbEngine::handleDebuggingHelperValue3Classic(const GdbResponse &response)
......@@ -1082,7 +1081,7 @@ void GdbEngine::handleDebuggingHelperValue3Classic(const GdbResponse &response)
QByteArray cmd = "qdumpqstring (" + data1.exp + ')';
QVariant var;
var.setValue(data1);
postCommand(cmd, WatchUpdate,
postCommand(cmd, Discardable,
CB(handleDebuggingHelperValue3Classic), var);
}
}
......@@ -1101,6 +1100,9 @@ void GdbEngine::handleDebuggingHelperValue3Classic(const GdbResponse &response)
void GdbEngine::tryLoadDebuggingHelpersClassic()
{
if (m_forceAsyncModel)
return;
PRECONDITION;
if (m_gdbAdapter->dumperHandling() == AbstractGdbAdapter::DumperNotAvailable) {
// Load at least gdb macro based dumpers.
......@@ -1171,12 +1173,12 @@ void GdbEngine::updateAllClassic()
qDebug() << state());
tryLoadDebuggingHelpersClassic();
reloadModulesInternal();
postCommand("-stack-list-frames", WatchUpdate,
postCommand("-stack-list-frames", Discardable,
CB(handleStackListFrames),
QVariant::fromValue<StackCookie>(StackCookie(false, true)));
stackHandler()->setCurrentIndex(0);
if (supportsThreads())
postCommand("-thread-list-ids", WatchUpdate, CB(handleThreadListIds), 0);
postCommand("-thread-list-ids", Discardable, CB(handleThreadListIds), 0);
reloadRegisters();
updateLocals();
}
......@@ -1248,11 +1250,10 @@ void GdbEngine::handleStackListLocalsClassic(const GdbResponse &response)
frame.function, frame.file, frame.line,
&uninitializedVariables);
}
QList<WatchData> list;
foreach (const GdbMi &item, locals) {
const WatchData data = localVariable(item, uninitializedVariables, &seen);
if (data.isValid())
list.push_back(data);
insertData(data);
}
if (!m_resultVarName.isEmpty()) {
......@@ -1260,10 +1261,9 @@ void GdbEngine::handleStackListLocalsClassic(const GdbResponse &response)
rd.iname = "return.0";
rd.name = QLatin1String("return");
rd.exp = m_resultVarName;
list.append(rd);
insertData(rd);
}
watchHandler()->insertBulkData(list);
watchHandler()->updateWatchers();
}
......@@ -1371,7 +1371,7 @@ void GdbEngine::handleVarListChildrenHelperClassic(const GdbMi &