forked from qt-creator/qt-creator
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 <christian.stenger@theqtcompany.com>
This commit is contained in:
@@ -238,6 +238,7 @@ public:
|
||||
SeparatedView *m_separatedView; // Not owned.
|
||||
|
||||
QSet<QByteArray> m_expandedINames;
|
||||
QSet<QByteArray> m_fetchTriggered;
|
||||
QTimer m_requestUpdateTimer;
|
||||
|
||||
QHash<QString, DisplayFormats> 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<QByteArray> 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();
|
||||
|
||||
|
@@ -90,7 +90,7 @@ typedef QVector<DisplayFormat> 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
|
||||
|
Reference in New Issue
Block a user