From c097867f3cc0c04e40a96a86dd41848c4a21eb13 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 23 Mar 2015 13:17:56 +0100 Subject: Debugger: Prevent endless recursion on output of broken dumpers That fixes a recent regression. If a dumper announces to have children, but doesn't produce any we re-tried for ever. This is reproducible e.g. by putting an 'return' before any 'if d.isExpanded():' stanza in a dumper and triggering that dumper. Keep track of expanded items, and only ask for children once per location change. Change-Id: I349fdc7380444eb3ac9fa2fae098a3f3e7658195 Reviewed-by: Christian Stenger --- src/plugins/debugger/watchhandler.cpp | 26 ++++++++++++-------------- src/plugins/debugger/watchhandler.h | 3 +-- 2 files changed, 13 insertions(+), 16 deletions(-) (limited to 'src/plugins/debugger') diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index cfcc0466c0..8b67ee91d4 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -238,6 +238,7 @@ public: SeparatedView *m_separatedView; // Not owned. QSet m_expandedINames; + QSet m_fetchTriggered; QTimer m_requestUpdateTimer; QHash m_reportedTypeFormats; // Type name -> Dumper Formats @@ -607,23 +608,25 @@ bool WatchItem::canFetchMore() const { if (!wantsChildren) return false; - if (!watchModel()) + const WatchModel *model = watchModel(); + if (!model) return false; - if (!watchModel()->m_contentsValid && !isInspect()) + if (!model->m_contentsValid && !isInspect()) return false; - return !fetchTriggered; + return !model->m_fetchTriggered.contains(iname); } void WatchItem::fetchMore() { - if (fetchTriggered) + WatchModel *model = watchModel(); + if (model->m_fetchTriggered.contains(iname)) return; - watchModel()->m_expandedINames.insert(iname); - fetchTriggered = true; + model->m_expandedINames.insert(iname); + model->m_fetchTriggered.insert(iname); if (children().isEmpty()) { setChildrenNeeded(); - watchModel()->m_engine->updateWatchItem(this); + model->m_engine->updateWatchItem(this); } } @@ -1656,6 +1659,7 @@ QString WatchHandler::editorContents() void WatchHandler::scheduleResetLocation() { + m_model->m_fetchTriggered.clear(); m_model->m_contentsValid = false; m_model->m_resetLocationScheduled = true; } @@ -1705,24 +1709,18 @@ QSet WatchHandler::expandedINames() const // //////////////////////////////////////////////////////////////////// -WatchItem::WatchItem() - : fetchTriggered(false) -{} - WatchItem::WatchItem(const QByteArray &i, const QString &n) { - fetchTriggered = false; iname = i; name = n; } WatchItem::WatchItem(const WatchData &data) - : WatchData(data), fetchTriggered(false) + : WatchData(data) { } WatchItem::WatchItem(const GdbMi &data) - : fetchTriggered(false) { iname = data["iname"].data(); diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index c505853d6d..5f7a6cb128 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -90,7 +90,7 @@ typedef QVector DisplayFormats; class WatchItem : public Utils::TreeItem, public WatchData { public: - WatchItem(); + WatchItem() {} WatchItem(const QByteArray &i, const QString &n); explicit WatchItem(const WatchData &data); explicit WatchItem(const GdbMi &data); @@ -123,7 +123,6 @@ private: Qt::ItemFlags flags(int column) const; void parseWatchData(const GdbMi &input); - bool fetchTriggered; }; class UpdateParameters -- cgit v1.2.1