Commit 05e56fc1 authored by hjk's avatar hjk
Browse files

debugger: prevent endless recursion due to broken dumpers

parent 80f0239b
......@@ -692,10 +692,10 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd)
if (cmd.flags & RebuildModel) {
++m_pendingRequests;
PENDING_DEBUG(" CALLBACK" << cmd.callbackName
PENDING_DEBUG(" COMMAND" << cmd.callbackName
<< "INCREMENTS PENDING TO:" << m_pendingRequests << cmd.command);
} else {
PENDING_DEBUG(" UNKNOWN CALLBACK" << cmd.callbackName
PENDING_DEBUG(" UNKNOWN COMMAND" << cmd.callbackName
<< "LEAVES PENDING AT:" << m_pendingRequests << cmd.command);
}
......@@ -816,14 +816,14 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
if (cmd.flags & RebuildModel) {
--m_pendingRequests;
PENDING_DEBUG(" TYPE " << cmd.callbackName << " DECREMENTS PENDING TO: "
PENDING_DEBUG(" RESULT " << cmd.callbackName << " DECREMENTS PENDING TO: "
<< m_pendingRequests << cmd.command);
if (m_pendingRequests <= 0) {
PENDING_DEBUG("\n\n .... AND TRIGGERS MODEL UPDATE\n");
rebuildModel();
}
} else {
PENDING_DEBUG(" UNKNOWN TYPE " << cmd.callbackName << " LEAVES PENDING AT: "
PENDING_DEBUG(" UNKNOWN RESULT " << cmd.callbackName << " LEAVES PENDING AT: "
<< m_pendingRequests << cmd.command);
}
......@@ -1120,6 +1120,8 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
if (initHelpers && reason == "signal-received"
&& data.findChild("signal-name").data() != "SIGTRAP")
initHelpers = false;
if (isSynchroneous())
initHelpers = false;
if (initHelpers) {
tryLoadDebuggingHelpers();
QVariant var = QVariant::fromValue<GdbMi>(data);
......@@ -2952,6 +2954,22 @@ void GdbEngine::updateWatchData(const WatchData &data)
#else
if (data.iname.endsWith(_(".")))
return;
// Avoid endless loops created by faulty dumpers.
QString processedName = QString(_("%1-%2").arg(1).arg(data.iname));
//qDebug() << "PROCESSED NAMES: " << processedName << m_processedNames;
if (m_processedNames.contains(processedName)) {
WatchData data1 = data;
gdbInputAvailable(LogStatus,
_("<Breaking endless loop for %1>").arg(data1.iname));
data1.setAllUnneeded();
data1.setValue(_("<unavailable>"));
data1.setHasChildren(false);
insertData(data1);
return;
}
m_processedNames.insert(processedName);
updateLocals();
#endif
} else {
......@@ -2990,7 +3008,8 @@ void GdbEngine::rebuildModel()
{
static int count = 0;
++count;
m_processedNames.clear();
if (!isSynchroneous())
m_processedNames.clear();
PENDING_DEBUG("REBUILDING MODEL" << count);
gdbInputAvailable(LogStatus, _("<Rebuild Watchmodel %1>").arg(count));
showStatusMessage(tr("Finished retrieving data."), 400);
......@@ -3359,27 +3378,26 @@ void GdbEngine::handleDebuggingHelperValue3(const GdbResponse &response)
void GdbEngine::updateLocals(const QVariant &cookie)
{
m_pendingRequests = 0;
m_processedNames.clear();
PENDING_DEBUG("\nRESET PENDING");
//m_toolTipCache.clear();
m_toolTipExpression.clear();
manager()->watchHandler()->beginCycle();
// Asynchronous load of injected library, initialize in first stop
if (m_dumperInjectionLoad && m_debuggingHelperState == DebuggingHelperLoadTried
&& m_dumperHelper.typeCount() == 0
&& inferiorPid() > 0)
tryQueryDebuggingHelpers();
if (isSynchroneous()) {
QStringList expanded = m_manager->watchHandler()->expandedINames().toList();
postCommand(_("bb %1 %2")
.arg(int(theDebuggerBoolSetting(UseDebuggingHelpers)))
.arg(expanded.join(_(","))),
CB(handleStackFrame1));
postCommand(_("p 1"), CB(handleStackFrame2));
CB(handleStackFrame));
} else {
m_processedNames.clear();
PENDING_DEBUG("\nRESET PENDING");
//m_toolTipCache.clear();
m_toolTipExpression.clear();
manager()->watchHandler()->beginCycle();
// Asynchronous load of injected library, initialize in first stop
if (m_dumperInjectionLoad && m_debuggingHelperState == DebuggingHelperLoadTried
&& m_dumperHelper.typeCount() == 0
&& inferiorPid() > 0)
tryQueryDebuggingHelpers();
QString level = QString::number(currentFrame());
// '2' is 'list with type and value'
QString cmd = _("-stack-list-arguments 2 ") + level + _c(' ') + level;
......@@ -3390,27 +3408,13 @@ void GdbEngine::updateLocals(const QVariant &cookie)
}
}
void GdbEngine::handleStackFrame1(const GdbResponse &response)
{
if (response.resultClass == GdbResultDone) {
QByteArray out = response.data.findChild("consolestreamoutput").data();
while (out.endsWith(' ') || out.endsWith('\n'))
out.chop(1);
//qDebug() << "FIRST CHUNK: " << out;
m_firstChunk = out;
} else {
QTC_ASSERT(false, qDebug() << response.toString());
}
}
void GdbEngine::handleStackFrame2(const GdbResponse &response)
void GdbEngine::handleStackFrame(const GdbResponse &response)
{
if (response.resultClass == GdbResultDone) {
QByteArray out = response.data.findChild("consolestreamoutput").data();
while (out.endsWith(' ') || out.endsWith('\n'))
out.chop(1);
//qDebug() << "SECOND CHUNK: " << out;
out = m_firstChunk + out;
int pos = out.indexOf("locals=");
if (pos != 0) {
qDebug() << "DISCARDING JUNK AT BEGIN OF RESPONSE: "
......@@ -3436,7 +3440,13 @@ void GdbEngine::handleStackFrame2(const GdbResponse &response)
// FIXME:
//manager()->watchHandler()->updateWatchers();
rebuildModel();
PENDING_DEBUG("AFTER handleStackFrame()");
// FIXME: This should only be used when updateLocals() was
// triggered by expanding an item in the view.
if (m_pendingRequests <= 0) {
PENDING_DEBUG("\n\n .... AND TRIGGERS MODEL UPDATE\n");
rebuildModel();
}
} else {
QTC_ASSERT(false, /**/);
}
......
......@@ -370,14 +370,12 @@ private: ////////// View & Data Stuff //////////
void handleStackListFrames(const GdbResponse &response);
void handleStackSelectThread(const GdbResponse &response);
void handleStackListThreads(const GdbResponse &response);
void handleStackFrame1(const GdbResponse &response);
void handleStackFrame2(const GdbResponse &response);
void handleStackFrame(const GdbResponse &response);
Q_SLOT void reloadStack(bool forceGotoLocation);
Q_SLOT void reloadFullStack();
int currentFrame() const;
QList<GdbMi> m_currentFunctionArgs;
QByteArray m_firstChunk;
QString m_currentFrame;
//
......
Supports Markdown
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