diff --git a/plugins/debuggercommon/miframestackmodel.cpp b/plugins/debuggercommon/miframestackmodel.cpp index 643ef28076..5abbe2bb39 100644 --- a/plugins/debuggercommon/miframestackmodel.cpp +++ b/plugins/debuggercommon/miframestackmodel.cpp @@ -1,155 +1,155 @@ /* * Implementation of thread and frame model that are common to debuggers using MI. * * Copyright 2009 Vladimir Prus * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "miframestackmodel.h" #include "midebugsession.h" #include "mi/micommand.h" #include #include using namespace KDevelop; using namespace KDevMI; using namespace KDevMI::MI; QString getFunctionOrAddress(const Value &frame) { if (frame.hasField(QStringLiteral("func"))) return frame[QStringLiteral("func")].literal(); else return frame[QStringLiteral("addr")].literal(); } QPair getSource(const Value &frame) { QPair ret(QString(), -1); if (frame.hasField(QStringLiteral("fullname"))) ret=qMakePair(frame[QStringLiteral("fullname")].literal(), frame[QStringLiteral("line")].toInt()-1); else if (frame.hasField(QStringLiteral("file"))) ret=qMakePair(frame[QStringLiteral("file")].literal(), frame[QStringLiteral("line")].toInt()-1); else if (frame.hasField(QStringLiteral("from"))) ret.first=frame[QStringLiteral("from")].literal(); return ret; } MIFrameStackModel::MIFrameStackModel(MIDebugSession * session) : FrameStackModel(session) { } MIDebugSession * MIFrameStackModel::session() { return static_cast(FrameStackModel::session()); } void MIFrameStackModel::fetchThreads() { session()->addCommand(ThreadInfo, QLatin1String(""), this, &MIFrameStackModel::handleThreadInfo); } void MIFrameStackModel::handleThreadInfo(const ResultRecord& r) { const Value& threads = r[QStringLiteral("threads")]; QList threadsList; for (int i = 0; i!= threads.size(); ++i) { const auto &threadMI = threads[i]; FrameStackModel::ThreadItem threadItem; threadItem.nr = threadMI[QStringLiteral("id")].toInt(); if (threadMI[QStringLiteral("state")].literal() == QLatin1String("stopped")) { threadItem.name = getFunctionOrAddress(threadMI[QStringLiteral("frame")]); } else { - i18n("(running)"); + threadItem.name = 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(QStringLiteral("current-thread-id"))) { int currentThreadId = r[QStringLiteral("current-thread-id")].toInt(); setCurrentThread(currentThreadId); if (session()->hasCrashed()) { setCrashedThreadIndex(currentThreadId); } } } struct FrameListHandler : public MICommandHandler { FrameListHandler(MIFrameStackModel* model, int thread, int to) : model(model), m_thread(thread) , m_to(to) {} void handle(const ResultRecord &r) override { const Value& stack = r[QStringLiteral("stack")]; int first = stack[0][QStringLiteral("level")].toInt(); QList frames; for (int i = 0; i< stack.size(); ++i) { const Value& frame = stack[i]; KDevelop::FrameStackModel::FrameItem f; f.nr = frame[QStringLiteral("level")].toInt(); f.name = getFunctionOrAddress(frame); QPair loc = getSource(frame); f.file = QUrl::fromLocalFile(loc.first).adjusted(QUrl::NormalizePathSegments); f.line = loc.second; frames << f; } bool hasMore = false; if (!frames.isEmpty()) { if (frames.last().nr == m_to+1) { frames.takeLast(); hasMore = true; } } if (first == 0) { model->setFrames(m_thread, frames); } else { model->insertFrames(m_thread, frames); } model->setHasMoreFrames(m_thread, hasMore); } private: MIFrameStackModel* model; int m_thread; int m_to; }; void MIFrameStackModel::fetchFrames(int threadNumber, int from, int to) { //to+1 so we know if there are more QString arg = QStringLiteral("%1 %2").arg(from).arg(to+1); MICommand *c = session()->createCommand(StackListFrames, arg); c->setHandler(new FrameListHandler(this, threadNumber, to)); c->setThread(threadNumber); session()->addCommand(c); }