void MIFrameStackModel::handleThreadInfo(const ResultRecord& r) { const Value& threads = r["threads"]; // Traverse GDB threads in backward order -- since GDB // reports them in backward order. We want UI to // show thread IDs in the natural order. // FIXME: at least GDB 7.11 is reporting in the right order, // consider sort the list afterwards. QList<KDevelop::FrameStackModel::ThreadItem> threadsList; int gidx = threads.size()-1; for (; gidx >= 0; --gidx) { KDevelop::FrameStackModel::ThreadItem i; const Value & threadMI = threads[gidx]; i.nr = threadMI["id"].toInt(); if (threadMI["state"].literal() == "stopped") { i.name = getFunctionOrAddress(threads[gidx]["frame"]); } else { i.name = i18n("(running)"); } threadsList << i; } setThreads(threadsList); if (r.hasField("current-thread-id")) { int currentThreadId = r["current-thread-id"].toInt(); setCurrentThread(currentThreadId); if (session()->hasCrashed()) { setCrashedThreadIndex(currentThreadId); } } }
void MIFrameStackModel::handleThreadInfo(const ResultRecord& r) { const Value& threads = r["threads"]; QList<FrameStackModel::ThreadItem> threadsList; for (int i = 0; i!= threads.size(); ++i) { const auto &threadMI = threads[i]; FrameStackModel::ThreadItem threadItem; threadItem.nr = threadMI["id"].toInt(); if (threadMI["state"].literal() == "stopped") { threadItem.name = getFunctionOrAddress(threadMI["frame"]); } else { i18n("(running)"); } threadsList << threadItem; } // Sort the list by id, some old version of GDB // reports them in backward order. We want UI to // show thread IDs in the natural order. std::sort(threadsList.begin(), threadsList.end(), [](const FrameStackModel::ThreadItem &a, const FrameStackModel::ThreadItem &b){ return a.nr < b.nr; }); setThreads(threadsList); if (r.hasField("current-thread-id")) { int currentThreadId = r["current-thread-id"].toInt(); setCurrentThread(currentThreadId); if (session()->hasCrashed()) { setCrashedThreadIndex(currentThreadId); } } }
void handle(const ResultRecord &r) override { if (!m_variable) return; --m_activeCommands; MIVariable* variable = m_variable.data(); if (r.hasField("children")) { const Value& children = r["children"]; for (int i = 0; i < children.size(); ++i) { const Value& child = children[i]; const QString& exp = child["exp"].literal(); if (exp == "public" || exp == "protected" || exp == "private") { ++m_activeCommands; m_session->addCommand(VarListChildren, QString("--all-values \"%1\"").arg(child["name"].literal()), this/*use again as handler*/); } else { variable->createChild(child); // it's automatically appended to variable's children list } } } /* Note that we don't set hasMore to true if there are still active commands. The reason is that we don't want the user to have even theoretical ability to click on "..." item and confuse us. */ bool hasMore = false; if (r.hasField("has_more")) hasMore = r["has_more"].toInt(); variable->setHasMore(hasMore); if (m_activeCommands == 0) { variable->emitAllChildrenFetched(); delete this; } }
void handle(const ResultRecord &r) override { if (!m_variable) return; bool hasValue = false; MIVariable* variable = m_variable.data(); variable->deleteChildren(); variable->setInScope(true); if (r.reason == "error") { variable->setShowError(true); } else { variable->setVarobj(r["name"].literal()); bool hasMore = false; if (r.hasField("has_more") && r["has_more"].toInt()) // GDB swears there are more children. Trust it hasMore = true; else // There are no more children in addition to what // numchild reports. But, in KDevelop, the variable // is not yet expanded, and those numchild are not // fetched yet. So, if numchild != 0, hasMore should // be true. hasMore = r["numchild"].toInt() != 0; variable->setHasMore(hasMore); variable->setType(r["type"].literal()); variable->setValue(variable->formatValue(r["value"].literal())); hasValue = !r["value"].literal().isEmpty(); if (variable->isExpanded() && r["numchild"].toInt()) { variable->fetchMoreChildren(); } if (variable->format() != KDevelop::Variable::Natural) { //TODO doesn't work for children as they are not yet loaded variable->formatChanged(); } } if (m_callback && m_callbackMethod) { QMetaObject::invokeMethod(m_callback, m_callbackMethod, Q_ARG(bool, hasValue)); } }
void LldbFrameStackModel::handleThreadInfo(const ResultRecord& r) { const Value& threads = r["threads"]; QList<FrameStackModel::ThreadItem> threadsList; for (int gidx = 0; gidx != threads.size(); ++gidx) { FrameStackModel::ThreadItem i; const Value & threadMI = threads[gidx]; i.nr = threadMI["id"].toInt(); if (threadMI["state"].literal() == "stopped") { // lldb-mi returns multiple frame entry for each thread // so can't directly use threadMI["frame"] auto &th = dynamic_cast<const TupleValue&>(threadMI); Value *topFrame = nullptr; for (auto res : th.results) { if (res->variable == "frame") { if (!topFrame || (*res->value)["level"].toInt() < (*topFrame)["level"].toInt()) { topFrame = res->value; } } } i.name = getFunctionOrAddress(*topFrame); } else { i.name = i18n("(running)"); } threadsList << i; } setThreads(threadsList); if (r.hasField("current-thread-id")) { int currentThreadId = r["current-thread-id"].toInt(); setCurrentThread(currentThreadId); if (session()->hasCrashed()) { setCrashedThreadIndex(currentThreadId); } } // lldb-mi doesn't have current-thread-id field. Use the thread-id field when inferiorStopped if (stoppedAtThread != -1) { setCurrentThread(stoppedAtThread); } stoppedAtThread = -1; }
void handle(const ResultRecord &r) override { if(m_variable && r.hasField("value")) m_variable->setValue(m_variable->formatValue(r["value"].literal())); }