forked from qt-creator/qt-creator
debugger: work on a "synchroneous" mode
For the case that gdb can give all the interesting data in one go.
This commit is contained in:
@@ -89,7 +89,7 @@
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
|
||||
// FIXME: temporary hack to evalute tbreak based step-over behaviour
|
||||
// FIXME: temporary hack to evalaute tbreak based step-over behaviour
|
||||
static QString lastFile;
|
||||
static int lastLine;
|
||||
|
||||
@@ -2648,8 +2648,6 @@ static void setWatchDataSAddress(WatchData &data, const GdbMi &mi)
|
||||
void GdbEngine::setUseDebuggingHelpers(const QVariant &on)
|
||||
{
|
||||
//qDebug() << "SWITCHING ON/OFF DUMPER DEBUGGING:" << on;
|
||||
// FIXME: a bit too harsh, but otherwise the treeview sometimes look funny
|
||||
//m_expandedINames.clear();
|
||||
Q_UNUSED(on)
|
||||
setTokenBarrier();
|
||||
updateLocals();
|
||||
@@ -2916,6 +2914,7 @@ void GdbEngine::updateSubItem(const WatchData &data0)
|
||||
return;
|
||||
}
|
||||
|
||||
//#if !X
|
||||
if (data.isHasChildrenNeeded() && data.variable.isEmpty()) {
|
||||
#if DEBUG_SUBITEM
|
||||
qDebug() << "UPDATE SUBITEM: VARIABLE NEEDED FOR CHILDCOUNT";
|
||||
@@ -2925,6 +2924,7 @@ void GdbEngine::updateSubItem(const WatchData &data0)
|
||||
// item, with childrenNeeded() set.
|
||||
return;
|
||||
}
|
||||
//#endif
|
||||
|
||||
if (data.isHasChildrenNeeded()) {
|
||||
QTC_ASSERT(!data.variable.isEmpty(), return); // tested above
|
||||
@@ -2939,6 +2939,21 @@ void GdbEngine::updateSubItem(const WatchData &data0)
|
||||
|
||||
void GdbEngine::updateWatchData(const WatchData &data)
|
||||
{
|
||||
if (isSynchroneous()) {
|
||||
// This should only be called for fresh expanded items, not for
|
||||
// items that had their children retrieved earlier.
|
||||
qDebug() << "\nUPDATE WATCH DATA: " << data.toString() << "\n";
|
||||
#if 0
|
||||
WatchData data1 = data;
|
||||
data1.setAllUnneeded();
|
||||
insertData(data1);
|
||||
rebuildModel();
|
||||
#else
|
||||
if (data.iname.endsWith(_(".")))
|
||||
return;
|
||||
updateLocals();
|
||||
#endif
|
||||
} else {
|
||||
// Bump requests to avoid model rebuilding during the nested
|
||||
// updateWatchModel runs.
|
||||
++m_pendingRequests;
|
||||
@@ -2950,6 +2965,7 @@ void GdbEngine::updateWatchData(const WatchData &data)
|
||||
updateWatchDataHelper(data);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void GdbEngine::updateWatchDataHelper(const WatchData &data)
|
||||
{
|
||||
@@ -3341,12 +3357,6 @@ void GdbEngine::handleDebuggingHelperValue3(const GdbResponse &response)
|
||||
|
||||
void GdbEngine::updateLocals()
|
||||
{
|
||||
// Asynchronous load of injected library, initialize in first stop
|
||||
if (m_dumperInjectionLoad && m_debuggingHelperState == DebuggingHelperLoadTried
|
||||
&& m_dumperHelper.typeCount() == 0
|
||||
&& inferiorPid() > 0)
|
||||
tryQueryDebuggingHelpers();
|
||||
|
||||
m_pendingRequests = 0;
|
||||
m_processedNames.clear();
|
||||
|
||||
@@ -3355,6 +3365,19 @@ void GdbEngine::updateLocals()
|
||||
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();
|
||||
qDebug() << "EXPANDED: " << expanded;
|
||||
postCommand(_("bb %1").arg(expanded.join(_(","))),
|
||||
WatchUpdate, CB(handleStackFrame1));
|
||||
postCommand(_("p 0"), WatchUpdate, CB(handleStackFrame2));
|
||||
} else {
|
||||
QString level = QString::number(currentFrame());
|
||||
// '2' is 'list with type and value'
|
||||
QString cmd = _("-stack-list-arguments 2 ") + level + _c(' ') + level;
|
||||
@@ -3363,6 +3386,50 @@ void GdbEngine::updateLocals()
|
||||
postCommand(_("-stack-list-locals 2"), WatchUpdate,
|
||||
CB(handleStackListLocals)); // stage 2/2
|
||||
}
|
||||
}
|
||||
|
||||
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 if (response.resultClass == GdbResultError) {
|
||||
QTC_ASSERT(false, /**/);
|
||||
}
|
||||
}
|
||||
|
||||
void GdbEngine::handleStackFrame2(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;
|
||||
// FIXME: Hack, make sure dumper does not return "{}"
|
||||
out.replace(",{}", "");
|
||||
GdbMi all("[" + out + "]");
|
||||
qDebug() << "ALL: " << all.toString();
|
||||
QList<GdbMi> locals = all.children();
|
||||
//manager()->watchHandler()->insertBulkData(locals);
|
||||
//setLocals(locals);
|
||||
WatchData *data = manager()->watchHandler()->findItem(_("local"));
|
||||
QTC_ASSERT(data, return);
|
||||
|
||||
QList<WatchData> list;
|
||||
foreach (const GdbMi &local, locals)
|
||||
handleChildren(*data, local, &list);
|
||||
|
||||
manager()->watchHandler()->insertBulkData(list);
|
||||
|
||||
manager()->watchHandler()->updateWatchers();
|
||||
} else if (response.resultClass == GdbResultError) {
|
||||
QTC_ASSERT(false, /**/);
|
||||
}
|
||||
}
|
||||
|
||||
void GdbEngine::handleStackListArguments(const GdbResponse &response)
|
||||
{
|
||||
@@ -3456,6 +3523,13 @@ void GdbEngine::setLocals(const QList<GdbMi> &locals)
|
||||
data.exp = nam;
|
||||
data.framekey = m_currentFrame + data.name;
|
||||
setWatchDataType(data, item.findChild("type"));
|
||||
if (isSynchroneous()) {
|
||||
setWatchDataValue(data, item.findChild("value"),
|
||||
item.findChild("valueencoded").data().toInt());
|
||||
// We know that the complete list of children is
|
||||
// somewhere in the response.
|
||||
data.setChildrenUnneeded();
|
||||
} else {
|
||||
// set value only directly if it is simple enough, otherwise
|
||||
// pass through the insertData() machinery
|
||||
if (isIntOrFloatType(data.type) || isPointerType(data.type))
|
||||
@@ -3464,6 +3538,8 @@ void GdbEngine::setLocals(const QList<GdbMi> &locals)
|
||||
setWatchDataValue(data, item.findChild("value"));
|
||||
data.setHasChildren(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Let's be a bit more bold:
|
||||
//if (!hasDebuggingHelperForType(data.type)) {
|
||||
// QByteArray value = item.findChild("value").data();
|
||||
@@ -3515,7 +3591,8 @@ void GdbEngine::handleVarListChildrenHelper(const GdbMi &item,
|
||||
//qDebug() << "DATA" << data.toString();
|
||||
QString cmd = _("-var-list-children --all-values \"") + data.variable + _c('"');
|
||||
//iname += '.' + exp;
|
||||
postCommand(cmd, WatchUpdate, CB(handleVarListChildren), QVariant::fromValue(data));
|
||||
postCommand(cmd, WatchUpdate,
|
||||
CB(handleVarListChildren), QVariant::fromValue(data));
|
||||
} else if (item.findChild("numchild").data() == "0") {
|
||||
// happens for structs without data, e.g. interfaces.
|
||||
WatchData data;
|
||||
@@ -3533,7 +3610,8 @@ void GdbEngine::handleVarListChildrenHelper(const GdbMi &item,
|
||||
WatchData data;
|
||||
data.iname = _(name);
|
||||
QString cmd = _("-var-list-children --all-values \"") + data.variable + _c('"');
|
||||
postCommand(cmd, WatchUpdate, CB(handleVarListChildren), QVariant::fromValue(data));
|
||||
postCommand(cmd, WatchUpdate,
|
||||
CB(handleVarListChildren), QVariant::fromValue(data));
|
||||
} else if (exp == "staticMetaObject") {
|
||||
// && item.findChild("type").data() == "const QMetaObject")
|
||||
// FIXME: Namespaces?
|
||||
@@ -3655,6 +3733,9 @@ void GdbEngine::assignValueInDebugger(const QString &expression, const QString &
|
||||
|
||||
void GdbEngine::tryLoadDebuggingHelpers()
|
||||
{
|
||||
if (isSynchroneous())
|
||||
return;
|
||||
|
||||
if (m_debuggingHelperState != DebuggingHelperUninitialized)
|
||||
return;
|
||||
if (!startModeAllowsDumpers()) {
|
||||
@@ -3735,9 +3816,13 @@ void GdbEngine::tryLoadDebuggingHelpers()
|
||||
|
||||
void GdbEngine::tryQueryDebuggingHelpers()
|
||||
{
|
||||
#if !X
|
||||
// retrieve list of dumpable classes
|
||||
postCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)"), EmbedToken);
|
||||
postCommand(_("p (char*)&qDumpOutBuffer"), CB(handleQueryDebuggingHelper));
|
||||
#else
|
||||
m_debuggingHelperState = DebuggingHelperUnavailable;
|
||||
#endif
|
||||
}
|
||||
|
||||
void GdbEngine::recheckDebuggingHelperAvailability()
|
||||
@@ -4186,6 +4271,10 @@ void GdbEngine::showMessageBox(int icon, const QString &title, const QString &te
|
||||
m_manager->showMessageBox(icon, title, text);
|
||||
}
|
||||
|
||||
bool GdbEngine::isSynchroneous() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Factory
|
||||
|
@@ -146,9 +146,10 @@ private:
|
||||
Q_SLOT void setDebugDebuggingHelpers(const QVariant &on);
|
||||
Q_SLOT void setUseDebuggingHelpers(const QVariant &on);
|
||||
Q_SLOT void setAutoDerefPointers(const QVariant &on);
|
||||
virtual bool isGdbEngine() const { return true; }
|
||||
bool isGdbEngine() const { return true; }
|
||||
bool isSynchroneous() const;
|
||||
|
||||
virtual bool checkConfiguration(int toolChain, QString *errorMessage, QString *settingsPage= 0) const;
|
||||
bool checkConfiguration(int toolChain, QString *errorMessage, QString *settingsPage= 0) const;
|
||||
|
||||
//
|
||||
// Own stuff
|
||||
@@ -347,6 +348,9 @@ private:
|
||||
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);
|
||||
QByteArray m_firstChunk;
|
||||
Q_SLOT void reloadStack(bool forceGotoLocation);
|
||||
Q_SLOT void reloadFullStack();
|
||||
|
||||
|
@@ -119,6 +119,7 @@ public:
|
||||
virtual bool isGdbEngine() const { return false; }
|
||||
virtual bool checkConfiguration(int /* toolChain */, QString * /* errorMessage */, QString * /* settingsPage */ = 0) const { return true; }
|
||||
|
||||
virtual bool isSynchroneous() const { return false; }
|
||||
protected:
|
||||
void showStatusMessage(const QString &msg, int timeout = -1);
|
||||
DebuggerState state() const;
|
||||
|
Reference in New Issue
Block a user