// Parse extension command listing breakpoints. // Note that not all fields are returned, since file, line, function are encoded // in the expression (that is in addition deleted on resolving for a bp-type breakpoint). void parseBreakPoint(const GdbMi &gdbmi, BreakpointResponse *r, QString *expression /* = 0 */) { gdbmiChildToBool(gdbmi, "enabled", &(r->enabled)); gdbmiChildToBool(gdbmi, "deferred", &(r->pending)); r->id = BreakpointResponseId(); // Might not be valid if there is not id r->id = cdbIdToBreakpointResponseId(gdbmi["id"]); const GdbMi moduleG = gdbmi["module"]; if (moduleG.isValid()) r->module = QString::fromLocal8Bit(moduleG.data()); const GdbMi sourceFileName = gdbmi["srcfile"]; if (sourceFileName.isValid()) { r->fileName = QString::fromLocal8Bit(sourceFileName.data()); const GdbMi lineNumber = gdbmi["srcline"]; if (lineNumber.isValid()) r->lineNumber = lineNumber.data().toULongLong(0, 0); } if (expression) { const GdbMi expressionG = gdbmi["expression"]; if (expressionG.isValid()) *expression = QString::fromLocal8Bit(expressionG.data()); } const GdbMi addressG = gdbmi["address"]; if (addressG.isValid()) r->address = addressG.data().toULongLong(0, 0); if (gdbmiChildToInt(gdbmi, "passcount", &(r->ignoreCount))) r->ignoreCount--; gdbmiChildToInt(gdbmi, "thread", &(r->threadSpec)); }
// Parse extension command listing breakpoints. // Note that not all fields are returned, since file, line, function are encoded // in the expression (that is in addition deleted on resolving for a bp-type breakpoint). void parseBreakPoint(const GdbMi &gdbmi, BreakpointResponse *r, QString *expression /* = 0 */) { gdbmiChildToBool(gdbmi, "enabled", &(r->enabled)); gdbmiChildToBool(gdbmi, "deferred", &(r->pending)); r->id = BreakpointResponseId(); const GdbMi idG = gdbmi.findChild("id"); if (idG.isValid()) { // Might not be valid if there is not id bool ok; const int id = idG.data().toInt(&ok); if (ok) r->id = BreakpointResponseId(id); } const GdbMi moduleG = gdbmi.findChild("module"); if (moduleG.isValid()) r->module = QString::fromLocal8Bit(moduleG.data()); if (expression) { const GdbMi expressionG = gdbmi.findChild("expression"); if (expressionG.isValid()) *expression = QString::fromLocal8Bit(expressionG.data()); } const GdbMi addressG = gdbmi.findChild("address"); if (addressG.isValid()) r->address = addressG.data().toULongLong(0, 0); if (gdbmiChildToInt(gdbmi, "passcount", &(r->ignoreCount))) r->ignoreCount--; gdbmiChildToInt(gdbmi, "thread", &(r->threadSpec)); }
void WatchItem::parse(const GdbMi &data) { iname = data["iname"].data(); GdbMi wname = data["wname"]; if (wname.isValid()) // Happens (only) for watched expressions. name = QString::fromUtf8(QByteArray::fromHex(wname.data())); else name = QString::fromLatin1(data["name"].data()); parseHelper(data); if (wname.isValid()) exp = name.toUtf8(); }
void TermGdbAdapter::handleEntryPoint(const GdbResponse &response) { if (response.resultClass == GdbResultDone) { GdbMi stack = response.data.findChild("stack"); if (stack.isValid() && stack.childCount() == 1) m_engine->m_entryPoint = stack.childAt(0).findChild("addr").data(); } }
// Helper to retrieve an bool child from GDBMI static inline bool gdbmiChildToBool(const GdbMi &parent, const char *childName, bool *target) { const GdbMi childBA = parent[childName]; if (childBA.isValid()) { *target = childBA.data() == "true"; return true; } return false; }
inline ModelId cdbIdToBreakpointId(const GdbMi &data) { if (data.isValid()) { // Might not be valid if there is not id bool ok; const int id = data.data().toInt(&ok); if (ok) return cdbIdToBreakpointId<ModelId>(id); } return ModelId(); }
void WinException::fromGdbMI(const GdbMi &gdbmi) { exceptionCode = gdbmi["exceptionCode"].data().toUInt(); exceptionFlags = gdbmi["exceptionFlags"].data().toUInt(); exceptionAddress = gdbmi["exceptionAddress"].data().toULongLong(); firstChance = gdbmi["firstChance"].data() != "0"; const GdbMi ginfo1 = gdbmi["exceptionInformation0"]; if (ginfo1.isValid()) { info1 = ginfo1.data().toULongLong(); const GdbMi ginfo2 = gdbmi["exceptionInformation1"]; if (ginfo2.isValid()) info2 = ginfo1.data().toULongLong(); } const GdbMi gLineNumber = gdbmi["exceptionLine"]; if (gLineNumber.isValid()) { lineNumber = gLineNumber.toInt(); file = gdbmi["exceptionFile"].data(); } function = gdbmi["exceptionFunction"].data(); }
// Helper to retrieve an int child from GDBMI static inline bool gdbmiChildToInt(const GdbMi &parent, const char *childName, int *target) { const GdbMi childBA = parent[childName]; if (childBA.isValid()) { bool ok; const int v = childBA.data().toInt(&ok); if (ok) { *target = v; return true; } } return false; }
void ThreadsHandler::updateThreads(const GdbMi &data) { // ^done,threads=[{id="1",target-id="Thread 0xb7fdc710 (LWP 4264)", // frame={level="0",addr="0x080530bf",func="testQString",args=[], // file="/.../app.cpp",fullname="/../app.cpp",line="1175"}, // state="stopped",core="0"}],current-thread-id="1" // Emit changed for previous frame. if (m_currentIndex != -1) { dataChanged(m_currentIndex); m_currentIndex = -1; } ThreadId currentId; const GdbMi current = data["current-thread-id"]; if (current.isValid()) currentId = ThreadId(current.data().toLongLong()); const QList<GdbMi> items = data["threads"].children(); const int n = items.size(); for (int index = 0; index != n; ++index) { const GdbMi item = items.at(index); const GdbMi frame = item["frame"]; ThreadData thread; thread.id = ThreadId(item["id"].toInt()); thread.targetId = item["target-id"].toLatin1(); thread.details = item["details"].toLatin1(); thread.core = item["core"].toLatin1(); thread.state = item["state"].toLatin1(); thread.address = frame["addr"].toAddress(); thread.function = frame["func"].toLatin1(); thread.fileName = frame["fullname"].toLatin1(); thread.lineNumber = frame["line"].toInt(); thread.module = QString::fromLocal8Bit(frame["from"].data()); thread.stopped = true; thread.name = item["name"].toLatin1(); if (thread.state == QLatin1String("running")) thread.stopped = false; if (thread.id == currentId) m_currentIndex = index; updateThread(thread); } if (m_currentIndex != -1) dataChanged(m_currentIndex); updateThreadBox(); }
void GdbMi::parseList(const char *&from, const char *to) { //qDebug() << "parseList: " << QByteArray(from, to - from); QTC_CHECK(*from == '['); ++from; m_type = List; skipCommas(from, to); while (from < to) { if (*from == ']') { ++from; break; } GdbMi child; child.parseResultOrValue(from, to); if (child.isValid()) m_children += child; skipCommas(from, to); } }
void GdbMi::parseTuple_helper(const char *&from, const char *to) { skipCommas(from, to); //qDebug() << "parseTuple_helper: " << QByteArray(from, to - from); m_type = Tuple; while (from < to) { if (*from == '}') { ++from; break; } GdbMi child; child.parseResultOrValue(from, to); //qDebug() << "\n=======\n" << qPrintable(child.toString()) << "\n========\n"; if (!child.isValid()) return; m_children += child; skipCommas(from, to); } }
void WatchItem::parseHelper(const GdbMi &input) { setChildrenUnneeded(); GdbMi mi = input["type"]; if (mi.isValid()) setType(mi.data()); editvalue = input["editvalue"].data(); editformat = DebuggerDisplay(input["editformat"].toInt()); editencoding = DebuggerEncoding(input["editencoding"].data()); mi = input["valueelided"]; if (mi.isValid()) elided = mi.toInt(); mi = input["bitpos"]; if (mi.isValid()) bitpos = mi.toInt(); mi = input["bitsize"]; if (mi.isValid()) bitsize = mi.toInt(); mi = input["origaddr"]; if (mi.isValid()) origaddr = mi.toAddress(); mi = input["address"]; if (mi.isValid()) { address = mi.toAddress(); if (exp.isEmpty()) { if (iname.startsWith("local.") && iname.count('.') == 1) // Solve one common case of adding 'class' in // *(class X*)0xdeadbeef for gdb. exp = name.toLatin1(); else exp = "*(" + gdbQuoteTypes(type) + "*)" + hexAddress(); } } mi = input["value"]; QByteArray enc = input["valueencoded"].data(); if (mi.isValid() || !enc.isEmpty()) { setValue(decodeData(mi.data(), enc)); } else { setValueNeeded(); } mi = input["size"]; if (mi.isValid()) size = mi.toInt(); mi = input["exp"]; if (mi.isValid()) exp = mi.data(); mi = input["valueenabled"]; if (mi.data() == "true") valueEnabled = true; else if (mi.data() == "false") valueEnabled = false; mi = input["valueeditable"]; if (mi.data() == "true") valueEditable = true; else if (mi.data() == "false") valueEditable = false; mi = input["numchild"]; // GDB/MI if (mi.isValid()) setHasChildren(mi.toInt() > 0); mi = input["haschild"]; // native-mixed if (mi.isValid()) setHasChildren(mi.toInt() > 0); mi = input["arraydata"]; if (mi.isValid()) { DebuggerEncoding encoding(input["arrayencoding"].data()); QByteArray childType = input["childtype"].data(); decodeArrayData(this, mi.data(), encoding, childType); } else { const GdbMi children = input["children"]; if (children.isValid()) { bool ok = false; // Try not to repeat data too often. const GdbMi childType = input["childtype"]; const GdbMi childNumChild = input["childnumchild"]; qulonglong addressBase = input["addrbase"].data().toULongLong(&ok, 0); qulonglong addressStep = input["addrstep"].data().toULongLong(&ok, 0); for (int i = 0, n = int(children.children().size()); i != n; ++i) { const GdbMi &subinput = children.children().at(i); WatchItem *child = new WatchItem; if (childType.isValid()) child->setType(childType.data()); if (childNumChild.isValid()) child->setHasChildren(childNumChild.toInt() > 0); GdbMi name = subinput["name"]; QByteArray nn; if (name.isValid()) { nn = name.data(); child->name = QString::fromLatin1(nn); } else { nn.setNum(i); child->name = QString::fromLatin1("[%1]").arg(i); } GdbMi iname = subinput["iname"]; if (iname.isValid()) child->iname = iname.data(); else child->iname = this->iname + '.' + nn; if (addressStep) { child->address = addressBase + i * addressStep; child->exp = "*(" + gdbQuoteTypes(child->type) + "*)" + child->hexAddress(); } QByteArray key = subinput["key"].data(); if (!key.isEmpty()) child->name = decodeData(key, subinput["keyencoded"].data()); child->parseHelper(subinput); appendChild(child); } } } }