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.
|
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
|
|||||||
{
|
{
|
||||||
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()
|
|||||||
|
|
||||||
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
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
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;
|
|||||||
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:
|
|||||||
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
|
||||||
|
Reference in New Issue
Block a user