forked from qt-creator/qt-creator
Fixes: debugger: fix custom dumpers
Details: again...
This commit is contained in:
@@ -1096,8 +1096,8 @@ bool DebuggerManager::useFastStart() const
|
|||||||
|
|
||||||
void DebuggerManager::setUseCustomDumpers(bool on)
|
void DebuggerManager::setUseCustomDumpers(bool on)
|
||||||
{
|
{
|
||||||
//m_settings.m_useCustomDumpers = on;
|
m_settings.m_useCustomDumpers = on;
|
||||||
//engine()->setUseCustomDumpers(on);
|
engine()->setUseCustomDumpers(on);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerManager::setUseFastStart(bool on)
|
void DebuggerManager::setUseFastStart(bool on)
|
||||||
|
@@ -253,6 +253,7 @@ void GdbEngine::init()
|
|||||||
m_gdbVersion = 100;
|
m_gdbVersion = 100;
|
||||||
m_shared = 0;
|
m_shared = 0;
|
||||||
m_outputCodec = QTextCodec::codecForLocale();
|
m_outputCodec = QTextCodec::codecForLocale();
|
||||||
|
m_dataDumperState = DataDumperUninitialized;
|
||||||
|
|
||||||
m_oldestAcceptableToken = -1;
|
m_oldestAcceptableToken = -1;
|
||||||
|
|
||||||
@@ -733,7 +734,7 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record)
|
|||||||
--m_pendingRequests;
|
--m_pendingRequests;
|
||||||
PENDING_DEBUG(" TYPE " << cmd.type << " DECREMENTS PENDING TO: "
|
PENDING_DEBUG(" TYPE " << cmd.type << " DECREMENTS PENDING TO: "
|
||||||
<< m_pendingRequests << cmd.command);
|
<< m_pendingRequests << cmd.command);
|
||||||
if (m_pendingRequests == 0)
|
if (m_pendingRequests <= 0)
|
||||||
updateWatchModel2();
|
updateWatchModel2();
|
||||||
} else {
|
} else {
|
||||||
PENDING_DEBUG(" UNKNOWN TYPE " << cmd.type << " LEAVES PENDING AT: "
|
PENDING_DEBUG(" UNKNOWN TYPE " << cmd.type << " LEAVES PENDING AT: "
|
||||||
@@ -2883,7 +2884,7 @@ static QString sizeofTypeExpression(const QString &type)
|
|||||||
|
|
||||||
void GdbEngine::setUseCustomDumpers(bool on)
|
void GdbEngine::setUseCustomDumpers(bool on)
|
||||||
{
|
{
|
||||||
qDebug() << "SWITCHING ON/OFF DUMPER DEBUGGING:" << on;
|
//qDebug() << "SWITCHING ON/OFF DUMPER DEBUGGING:" << on;
|
||||||
Q_UNUSED(on);
|
Q_UNUSED(on);
|
||||||
// FIXME: a bit too harsh, but otherwise the treeview sometimes look funny
|
// FIXME: a bit too harsh, but otherwise the treeview sometimes look funny
|
||||||
//m_expandedINames.clear();
|
//m_expandedINames.clear();
|
||||||
@@ -3052,15 +3053,15 @@ void GdbEngine::runCustomDumper(const WatchData & data0, bool dumpChildren)
|
|||||||
|
|
||||||
//qDebug() << "CMD: " << cmd;
|
//qDebug() << "CMD: " << cmd;
|
||||||
|
|
||||||
sendSynchronizedCommand(cmd, WatchDumpCustomValue1, QVariant::fromValue(data));
|
QVariant var;
|
||||||
|
var.setValue(data);
|
||||||
|
sendSynchronizedCommand(cmd, WatchDumpCustomValue1, var);
|
||||||
|
|
||||||
q->showStatusMessage(
|
q->showStatusMessage(
|
||||||
tr("Retrieving data for watch view (%1 requests pending)...")
|
tr("Retrieving data for watch view (%1 requests pending)...")
|
||||||
.arg(m_pendingRequests + 1), 10000);
|
.arg(m_pendingRequests + 1), 10000);
|
||||||
|
|
||||||
// retrieve response
|
// retrieve response
|
||||||
QVariant var;
|
|
||||||
var.setValue(data);
|
|
||||||
sendSynchronizedCommand("p (char*)qDumpOutBuffer", WatchDumpCustomValue2, var);
|
sendSynchronizedCommand("p (char*)qDumpOutBuffer", WatchDumpCustomValue2, var);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3268,7 +3269,7 @@ void GdbEngine::updateWatchModel2()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PENDING_DEBUG("REBUILDING MODEL")
|
PENDING_DEBUG("REBUILDING MODEL");
|
||||||
emit gdbInputAvailable(QString(),
|
emit gdbInputAvailable(QString(),
|
||||||
"[" + currentTime() + "] <Rebuild Watchmodel>");
|
"[" + currentTime() + "] <Rebuild Watchmodel>");
|
||||||
q->showStatusMessage(tr("Finished retrieving data."), 400);
|
q->showStatusMessage(tr("Finished retrieving data."), 400);
|
||||||
@@ -3454,7 +3455,7 @@ void GdbEngine::handleDumpCustomValue1(const GdbResultRecord &record,
|
|||||||
} else if (record.resultClass == GdbResultError) {
|
} else if (record.resultClass == GdbResultError) {
|
||||||
// Record an extra result, as the socket result will be lost
|
// Record an extra result, as the socket result will be lost
|
||||||
// in transmission
|
// in transmission
|
||||||
--m_pendingRequests;
|
//--m_pendingRequests;
|
||||||
QString msg = record.data.findChild("msg").data();
|
QString msg = record.data.findChild("msg").data();
|
||||||
//qDebug() << "CUSTOM DUMPER ERROR MESSAGE: " << msg;
|
//qDebug() << "CUSTOM DUMPER ERROR MESSAGE: " << msg;
|
||||||
#ifdef QT_DEBUG
|
#ifdef QT_DEBUG
|
||||||
@@ -3469,12 +3470,12 @@ void GdbEngine::handleDumpCustomValue1(const GdbResultRecord &record,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (msg.startsWith("The program being debugged was sig"))
|
//if (msg.startsWith("The program being debugged was sig"))
|
||||||
msg = strNotInScope;
|
// msg = strNotInScope;
|
||||||
if (msg.startsWith("The program being debugged stopped while"))
|
//if (msg.startsWith("The program being debugged stopped while"))
|
||||||
msg = strNotInScope;
|
// msg = strNotInScope;
|
||||||
data.setError(msg);
|
//data.setError(msg);
|
||||||
insertData(data);
|
//insertData(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3485,34 +3486,36 @@ void GdbEngine::handleDumpCustomValue2(const GdbResultRecord &record,
|
|||||||
QTC_ASSERT(data.isValid(), return);
|
QTC_ASSERT(data.isValid(), return);
|
||||||
//qDebug() << "CUSTOM VALUE RESULT: " << record.toString();
|
//qDebug() << "CUSTOM VALUE RESULT: " << record.toString();
|
||||||
//qDebug() << "FOR DATA: " << data.toString() << record.resultClass;
|
//qDebug() << "FOR DATA: " << data.toString() << record.resultClass;
|
||||||
if (record.resultClass == GdbResultDone) {
|
if (record.resultClass != GdbResultDone) {
|
||||||
|
qDebug() << "STRANGE CUSTOM DUMPER RESULT DATA: " << data.toString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
GdbMi output = record.data.findChild("consolestreamoutput");
|
GdbMi output = record.data.findChild("consolestreamoutput");
|
||||||
QByteArray out = output.data();
|
QByteArray out = output.data();
|
||||||
out = out.mid(out.indexOf('"') + 2); // + 1 is the 'success marker'
|
|
||||||
|
int markerPos = out.indexOf('"') + 1; // position of 'success marker'
|
||||||
|
if (markerPos == -1 || out.at(markerPos) == 'f') { // 't' or 'f'
|
||||||
|
// custom dumper produced no output
|
||||||
|
data.setError(strNotInScope);
|
||||||
|
insertData(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out = out.mid(markerPos + 1);
|
||||||
out = out.left(out.lastIndexOf('"'));
|
out = out.left(out.lastIndexOf('"'));
|
||||||
//out.replace('\'', '"');
|
|
||||||
out.replace("\\", "");
|
out.replace("\\", "");
|
||||||
out = "dummy={" + out + "}";
|
out = "dummy={" + out + "}";
|
||||||
//qDebug() << "OUTPUT: " << out;
|
|
||||||
|
|
||||||
GdbMi contents;
|
GdbMi contents;
|
||||||
contents.fromString(out);
|
contents.fromString(out);
|
||||||
//qDebug() << "CONTENTS" << contents.toString(true);
|
//qDebug() << "CONTENTS" << contents.toString(true);
|
||||||
|
|
||||||
if (!contents.isValid()) {
|
if (!contents.isValid()) {
|
||||||
qDebug() << "INVALID";
|
data.setError(strNotInScope);
|
||||||
// custom dumper produced no output
|
|
||||||
if (data.isValueNeeded())
|
|
||||||
data.setValue("<unknown>");
|
|
||||||
if (data.isTypeNeeded())
|
|
||||||
data.setType("<unknown>");
|
|
||||||
if (data.isChildrenNeeded())
|
|
||||||
data.setChildCount(0);
|
|
||||||
if (data.isChildCountNeeded())
|
|
||||||
data.setChildCount(0);
|
|
||||||
data.setValueToolTip("<custom dumper produced no output>");
|
|
||||||
insertData(data);
|
insertData(data);
|
||||||
} else {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setWatchDataType(data, contents.findChild("type"));
|
setWatchDataType(data, contents.findChild("type"));
|
||||||
setWatchDataValue(data, contents.findChild("value"),
|
setWatchDataValue(data, contents.findChild("value"),
|
||||||
contents.findChild("valueencoded").data().toInt());
|
contents.findChild("valueencoded").data().toInt());
|
||||||
@@ -3565,92 +3568,77 @@ void GdbEngine::handleDumpCustomValue2(const GdbResultRecord &record,
|
|||||||
//qDebug() << "HANDLE CUSTOM SUBCONTENTS:" << data1.toString();
|
//qDebug() << "HANDLE CUSTOM SUBCONTENTS:" << data1.toString();
|
||||||
insertData(data1);
|
insertData(data1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
//qDebug() << "HANDLE CUSTOM VALUE CONTENTS: " << data.toString();
|
|
||||||
} else if (record.resultClass == GdbResultError) {
|
|
||||||
// FIXME: Should not happen here, i.e. could be removed
|
|
||||||
QString msg = record.data.findChild("msg").data();
|
|
||||||
//qDebug() << "CUSTOM DUMPER ERROR MESSAGE: " << msg;
|
|
||||||
if (msg.startsWith("The program being debugged was sig"))
|
|
||||||
msg = strNotInScope;
|
|
||||||
if (msg.startsWith("The program being debugged stopped while"))
|
|
||||||
msg = strNotInScope;
|
|
||||||
data.setError(msg);
|
|
||||||
insertData(data);
|
|
||||||
} else {
|
|
||||||
qDebug() << "STRANGE CUSTOM DUMPER RESULT DATA: " << data.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::updateLocals()
|
void GdbEngine::updateLocals()
|
||||||
{
|
{
|
||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
|
|
||||||
m_pendingRequests = 0;
|
m_pendingRequests = 0;
|
||||||
PENDING_DEBUG("\nRESET PENDING");
|
PENDING_DEBUG("\nRESET PENDING");
|
||||||
m_toolTipCache.clear();
|
m_toolTipCache.clear();
|
||||||
m_toolTipExpression.clear();
|
m_toolTipExpression.clear();
|
||||||
qq->watchHandler()->reinitializeWatchers();
|
qq->watchHandler()->reinitializeWatchers();
|
||||||
|
|
||||||
int level = currentFrame();
|
int level = currentFrame();
|
||||||
// '2' is 'list with type and value'
|
// '2' is 'list with type and value'
|
||||||
QString cmd = QString("-stack-list-arguments 2 %1 %2").arg(level).arg(level);
|
QString cmd = QString("-stack-list-arguments 2 %1 %2").arg(level).arg(level);
|
||||||
sendSynchronizedCommand(cmd, StackListArguments); // stage 1/2
|
sendSynchronizedCommand(cmd, StackListArguments); // stage 1/2
|
||||||
// '2' is 'list with type and value'
|
// '2' is 'list with type and value'
|
||||||
sendSynchronizedCommand("-stack-list-locals 2", StackListLocals); // stage 2/2
|
sendSynchronizedCommand("-stack-list-locals 2", StackListLocals); // stage 2/2
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::handleStackListArguments(const GdbResultRecord &record)
|
void GdbEngine::handleStackListArguments(const GdbResultRecord &record)
|
||||||
{
|
{
|
||||||
// stage 1/2
|
// stage 1/2
|
||||||
|
|
||||||
// Linux:
|
// Linux:
|
||||||
// 12^done,stack-args=
|
// 12^done,stack-args=
|
||||||
// [frame={level="0",args=[
|
// [frame={level="0",args=[
|
||||||
// {name="argc",type="int",value="1"},
|
// {name="argc",type="int",value="1"},
|
||||||
// {name="argv",type="char **",value="(char **) 0x7..."}]}]
|
// {name="argv",type="char **",value="(char **) 0x7..."}]}]
|
||||||
// Mac:
|
// Mac:
|
||||||
// 78^done,stack-args=
|
// 78^done,stack-args=
|
||||||
// {frame={level="0",args={
|
// {frame={level="0",args={
|
||||||
// varobj=
|
// varobj=
|
||||||
// {exp="this",value="0x38a2fab0",name="var21",numchild="3",
|
// {exp="this",value="0x38a2fab0",name="var21",numchild="3",
|
||||||
// type="CurrentDocumentFind * const",typecode="PTR",
|
// type="CurrentDocumentFind * const",typecode="PTR",
|
||||||
// dynamic_type="",in_scope="true",block_start_addr="0x3938e946",
|
// dynamic_type="",in_scope="true",block_start_addr="0x3938e946",
|
||||||
// block_end_addr="0x3938eb2d"},
|
// block_end_addr="0x3938eb2d"},
|
||||||
// varobj=
|
// varobj=
|
||||||
// {exp="before",value="@0xbfffb9f8: {d = 0x3a7f2a70}",
|
// {exp="before",value="@0xbfffb9f8: {d = 0x3a7f2a70}",
|
||||||
// name="var22",numchild="1",type="const QString ...} }}}
|
// name="var22",numchild="1",type="const QString ...} }}}
|
||||||
//
|
//
|
||||||
// In both cases, iterating over the children of stack-args/frame/args
|
// In both cases, iterating over the children of stack-args/frame/args
|
||||||
// is ok.
|
// is ok.
|
||||||
m_currentFunctionArgs.clear();
|
m_currentFunctionArgs.clear();
|
||||||
if (record.resultClass == GdbResultDone) {
|
if (record.resultClass == GdbResultDone) {
|
||||||
const GdbMi list = record.data.findChild("stack-args");
|
const GdbMi list = record.data.findChild("stack-args");
|
||||||
const GdbMi frame = list.findChild("frame");
|
const GdbMi frame = list.findChild("frame");
|
||||||
const GdbMi args = frame.findChild("args");
|
const GdbMi args = frame.findChild("args");
|
||||||
m_currentFunctionArgs = args.children();
|
m_currentFunctionArgs = args.children();
|
||||||
} else if (record.resultClass == GdbResultError) {
|
} else if (record.resultClass == GdbResultError) {
|
||||||
qDebug() << "FIXME: GdbEngine::handleStackListArguments: should not happen";
|
qDebug() << "FIXME: GdbEngine::handleStackListArguments: should not happen";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::handleStackListLocals(const GdbResultRecord &record)
|
void GdbEngine::handleStackListLocals(const GdbResultRecord &record)
|
||||||
{
|
{
|
||||||
// stage 2/2
|
// stage 2/2
|
||||||
|
|
||||||
// There could be shadowed variables
|
// There could be shadowed variables
|
||||||
QList<GdbMi> locals = record.data.findChild("locals").children();
|
QList<GdbMi> locals = record.data.findChild("locals").children();
|
||||||
locals += m_currentFunctionArgs;
|
locals += m_currentFunctionArgs;
|
||||||
|
|
||||||
setLocals(locals);
|
setLocals(locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::setLocals(const QList<GdbMi> &locals)
|
void GdbEngine::setLocals(const QList<GdbMi> &locals)
|
||||||
{
|
{
|
||||||
//qDebug() << m_varToType;
|
//qDebug() << m_varToType;
|
||||||
QHash<QString, int> seen;
|
QHash<QString, int> seen;
|
||||||
|
|
||||||
foreach (const GdbMi &item, locals) {
|
foreach (const GdbMi &item, locals) {
|
||||||
// Local variables of inlined code are reported as
|
// Local variables of inlined code are reported as
|
||||||
// 26^done,locals={varobj={exp="this",value="",name="var4",exp="this",
|
// 26^done,locals={varobj={exp="this",value="",name="var4",exp="this",
|
||||||
// numchild="1",type="const QtSharedPointer::Basic<CPlusPlus::..."
|
// numchild="1",type="const QtSharedPointer::Basic<CPlusPlus::..."
|
||||||
|
Reference in New Issue
Block a user