Commit c097867f authored by hjk's avatar hjk
Browse files

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: default avatarChristian Stenger <christian.stenger@theqtcompany.com>
parent c1fd41c5
...@@ -238,6 +238,7 @@ public: ...@@ -238,6 +238,7 @@ public:
SeparatedView *m_separatedView; // Not owned. SeparatedView *m_separatedView; // Not owned.
QSet<QByteArray> m_expandedINames; QSet<QByteArray> m_expandedINames;
QSet<QByteArray> m_fetchTriggered;
QTimer m_requestUpdateTimer; QTimer m_requestUpdateTimer;
QHash<QString, DisplayFormats> m_reportedTypeFormats; // Type name -> Dumper Formats QHash<QString, DisplayFormats> m_reportedTypeFormats; // Type name -> Dumper Formats
...@@ -607,23 +608,25 @@ bool WatchItem::canFetchMore() const ...@@ -607,23 +608,25 @@ bool WatchItem::canFetchMore() const
{ {
if (!wantsChildren) if (!wantsChildren)
return false; return false;
if (!watchModel()) const WatchModel *model = watchModel();
if (!model)
return false; return false;
if (!watchModel()->m_contentsValid && !isInspect()) if (!model->m_contentsValid && !isInspect())
return false; return false;
return !fetchTriggered; return !model->m_fetchTriggered.contains(iname);
} }
void WatchItem::fetchMore() void WatchItem::fetchMore()
{ {
if (fetchTriggered) WatchModel *model = watchModel();
if (model->m_fetchTriggered.contains(iname))
return; return;
watchModel()->m_expandedINames.insert(iname); model->m_expandedINames.insert(iname);
fetchTriggered = true; model->m_fetchTriggered.insert(iname);
if (children().isEmpty()) { if (children().isEmpty()) {
setChildrenNeeded(); setChildrenNeeded();
watchModel()->m_engine->updateWatchItem(this); model->m_engine->updateWatchItem(this);
} }
} }
...@@ -1656,6 +1659,7 @@ QString WatchHandler::editorContents() ...@@ -1656,6 +1659,7 @@ QString WatchHandler::editorContents()
void WatchHandler::scheduleResetLocation() void WatchHandler::scheduleResetLocation()
{ {
m_model->m_fetchTriggered.clear();
m_model->m_contentsValid = false; m_model->m_contentsValid = false;
m_model->m_resetLocationScheduled = true; m_model->m_resetLocationScheduled = true;
} }
...@@ -1705,24 +1709,18 @@ QSet<QByteArray> WatchHandler::expandedINames() const ...@@ -1705,24 +1709,18 @@ QSet<QByteArray> WatchHandler::expandedINames() const
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
WatchItem::WatchItem()
: fetchTriggered(false)
{}
WatchItem::WatchItem(const QByteArray &i, const QString &n) WatchItem::WatchItem(const QByteArray &i, const QString &n)
{ {
fetchTriggered = false;
iname = i; iname = i;
name = n; name = n;
} }
WatchItem::WatchItem(const WatchData &data) WatchItem::WatchItem(const WatchData &data)
: WatchData(data), fetchTriggered(false) : WatchData(data)
{ {
} }
WatchItem::WatchItem(const GdbMi &data) WatchItem::WatchItem(const GdbMi &data)
: fetchTriggered(false)
{ {
iname = data["iname"].data(); iname = data["iname"].data();
......
...@@ -90,7 +90,7 @@ typedef QVector<DisplayFormat> DisplayFormats; ...@@ -90,7 +90,7 @@ typedef QVector<DisplayFormat> DisplayFormats;
class WatchItem : public Utils::TreeItem, public WatchData class WatchItem : public Utils::TreeItem, public WatchData
{ {
public: public:
WatchItem(); WatchItem() {}
WatchItem(const QByteArray &i, const QString &n); WatchItem(const QByteArray &i, const QString &n);
explicit WatchItem(const WatchData &data); explicit WatchItem(const WatchData &data);
explicit WatchItem(const GdbMi &data); explicit WatchItem(const GdbMi &data);
...@@ -123,7 +123,6 @@ private: ...@@ -123,7 +123,6 @@ private:
Qt::ItemFlags flags(int column) const; Qt::ItemFlags flags(int column) const;
void parseWatchData(const GdbMi &input); void parseWatchData(const GdbMi &input);
bool fetchTriggered;
}; };
class UpdateParameters class UpdateParameters
......
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