예제 #1
0
    virtual void handle(const GDBMI::ResultRecord &r)
    {
        kDebug() << controller->m_dirty[breakpoint];

        if (r.reason == "error") {
            controller->error(breakpoint, r["msg"].literal(), KDevelop::Breakpoint::LocationColumn);
            kWarning() << r["msg"].literal();
        } else {
            controller->m_errors[breakpoint].remove(KDevelop::Breakpoint::LocationColumn);
            if (r.hasField("bkpt")) {
                controller->update(breakpoint, r["bkpt"]);
            } else if (r.hasField("wpt")) {
                // For watchpoint creation, GDB basically does not say
                // anything.  Just record id.
                controller->m_ids[breakpoint] = r["wpt"]["number"].literal();
            } else if (r.hasField("hw-rwpt")) {
                controller->m_ids[breakpoint] = r["hw-rwpt"]["number"].literal();
            } else if (r.hasField("hw-awpt")) {
                controller->m_ids[breakpoint] = r["hw-awpt"]["number"].literal();
            }
            Q_ASSERT(!controller->m_ids[breakpoint].isEmpty());
            kDebug() << "breakpoint id" << breakpoint << controller->m_ids[breakpoint];
        }
        controller->m_dirty[breakpoint].remove(KDevelop::Breakpoint::LocationColumn);
        controller->breakpointStateChanged(breakpoint);
        controller->sendMaybe(breakpoint);
    }
void VariableItem::varobjCreated(const GDBMI::ResultRecord& r)
{
    // If we've tried to recreate varobj (for example for watched expression)
    // after step, and it's no longer valid, it's fine.
    if (r.reason == "error")
    {
        varobjName_ = "";
        return;
    }
    setAliveRecursively(true);

    QString oldType = originalValueType_;
    originalValueType_ = r["type"].literal();
    if (!oldType.isEmpty() && oldType != originalValueType_)
    {
        deleteAllChildren();
    }

    if (r.hasField("exp"))
        expression_ = r["exp"].literal();

    numChildren_ = r["numchild"].literal().toInt();
    currentAddress_ = lastObtainedAddress_;

    setVarobjName(varobjName_);
}
예제 #3
0
void GdbFrameStackModel::handleThreadInfo(const GDBMI::ResultRecord& r)
{
    const GDBMI::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: make the code independent of whatever craziness
    // gdb might have tomorrow.

    QList<KDevelop::FrameStackModel::ThreadItem> threadsList;
    int gidx = threads.size()-1;
    for (; gidx >= 0; --gidx) {
        KDevelop::FrameStackModel::ThreadItem i;
        const GDBMI::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);
        }
    }
}
    virtual void handle(const GDBMI::ResultRecord &r)
    {
        if (!m_variable) return;
        --m_activeCommands;

        if (r.hasField("children"))
        {
            const GDBMI::Value& children = r["children"];
            for (int i = 0; i < children.size(); ++i) {
                const GDBMI::Value& child = children[i];
                const QString& exp = child["exp"].literal();
                if (exp == "public" || exp == "protected" || exp == "private") {
                    ++m_activeCommands;
                    m_session->addCommand(
                        new GDBCommand(GDBMI::VarListChildren,
                                       QString("--all-values \"%1\"")
                                       .arg(child["name"].literal()),
                                       this/*use again as handler*/));
                } else {
                    KDevelop::Variable* xvar = m_session->variableController()->
                        createVariable(m_variable->model(), m_variable, 
                                       child["exp"].literal());
                    GdbVariable* var = static_cast<GdbVariable*>(xvar);
                    var->setTopLevel(false);
                    var->setVarobj(child["name"].literal());
                    var->setHasMoreInitial(child["numchild"].toInt());
                    m_variable->appendChild(var);
                    var->setValue(child["value"].literal());
                }
            }
        }

        /* 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();

        m_variable->setHasMore(hasMore);
        if (m_activeCommands == 0) {
            delete this;
        }
    }
예제 #5
0
void Breakpoint::handleSet(const GDBMI::ResultRecord& r)
{
    // Try to find gdb id. It's a bit harder that it should be,
    // because field names differ depending on breakpoint type.

    int id = -1;
    
    if (r.hasField("bkpt"))
        id = r["bkpt"]["number"].literal().toInt();
    else if (r.hasField("wpt"))
        id = r["wpt"]["number"].literal().toInt();
    else if (r.hasField("hw-rwpt"))
        id = r["hw-rwpt"]["number"].literal().toInt();
    // We don't have access watchpoints in UI yet, but
    // for future.
    else if (r.hasField("hw-awpt"))
        id = r["hw-awpt"]["number"].literal().toInt();
    
    if (id == -1)
    {
        // If can't set because file not found yet,
        // will need to try later.
        setPending(true);
    }
    else
    {
        setActive(0 /* unused m_activeFlag */, id);
    }
    
    // Need to do this so that if breakpoint is not set
    // (because the file is not found)
    // we unset isDbgProcessing flag, so that breakpoint can
    // be set on next stop.
    setDbgProcessing(false);

    // Immediately call modifyBreakpoint to set all breakpoint
    // properties, such as condition.
    modifyBreakpoint();

    emit modified(this);
}
예제 #6
0
void BreakpointController::programStopped(const GDBMI::ResultRecord& r)
{
    QString reason;
    if (r.hasField("reason")) {
        reason = r["reason"].literal();
    }
    kDebug() << reason;

    /* This method will not do the right thing if we hit a breakpoint
        that is added in GDB outside kdevelop.  In this case we'll
        first try to find the breakpoint, and fail, and only then
        update the breakpoint table and notice the new one.  */

    QString id;
    if (reason == "breakpoint-hit") {
        id = r["bkptno"].literal();
    } else if (reason == "watchpoint-trigger") {
        id = r["wpt"]["number"].literal();
    } else if (reason == "read-watchpoint-trigger") {
        id = r["hw-rwpt"]["number"].literal();
    } else if (reason == "access-watchpoint-trigger") {
        id = r["hw-awpt"]["number"].literal();
    }
    if (!id.isEmpty()) {
        QString msg;
        if (r.hasField("value")) {
            if (r["value"].hasField("old")) {
                msg += i18n("<br>Old value: %1", r["value"]["old"].literal());
            }
            if (r["value"].hasField("new")) {
                msg += i18n("<br>New value: %1", r["value"]["new"].literal());
            }
        }
        KDevelop::Breakpoint* b = m_ids.key(id);
        if (b) {
            hit(b, msg);
        }
    }
}
예제 #7
0
void QListVariableItem::handleAttributes(const GDBMI::ResultRecord& r)
{
    // TODO support comma separated attr list when more than 2 flags
    if (!r.hasField("attr") || r["attr"].literal() != "editable") {
        setResult("<out of scope>");
        return;
    }

    addCommand(
        new GDBCommand(DataEvaluateExpression, QString("%1.d.begin").arg(gdbExpression()),
                        this, &QListVariableItem::handleBegin));

    addCommand(
        new GDBCommand(DataEvaluateExpression, QString("%1.d.end").arg(gdbExpression()),
                        this, &QListVariableItem::handleEnd));
}
예제 #8
0
void FilePosBreakpoint::handleSet(const GDBMI::ResultRecord& r)
{
    // Below logic gets filename and line from gdb response, and
    // allows us to show breakpoint marker even for function
    // breakpoints. Unfortunately, 'fullname' field is available only in 
    // post-6.4 versions of gdb and if we try to use 'file', then
    // KDevelop won't be able to find that file to show the marker.
    if (r.hasField("bkpt"))
    {
        const GDBMI::Value& v = r["bkpt"];
        if (v.hasField("fullname") && v.hasField("line"))
        {
            fileName_ = v["fullname"].literal();
            line_ = v["line"].literal().toInt();
        }
    }

    Breakpoint::handleSet(r);
}
예제 #9
0
void QListVariableItem::handleEnd(const GDBMI::ResultRecord& r)
{
    if (r.hasField("value")) {
        m_end = r["value"].toInt();

        QRegExp childParser("QList<([^>])>");
        if (!childParser.isValid())
            kWarning() << childParser.errorString();

        QString childType;
        if (childParser.indexIn(type()))
            childType = childParser.cap(1);

        kDebug() << "Child type " << childType;

        for (int i = m_begin; i < m_end; ++i)
            addChild(QString("%1.d.array[%2]").arg(gdbExpression()).arg(i), childType);

        setResult(i18n("<%1 items>", m_end - m_begin));
    }
}
예제 #10
0
void GdbFrameStackModel::handleThreadInfo(const GDBMI::ResultRecord& r)
{
    const GDBMI::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: make the code independent of whatever craziness
    // gdb might have tomorrow.

    QList<KDevelop::FrameStackModel::ThreadItem> threadsList;
    int gidx = threads.size()-1;
    for (; gidx >= 0; --gidx) {
        KDevelop::FrameStackModel::ThreadItem i;
        i.nr = threads[gidx]["id"].toInt();
        i.name = getFunctionOrAddress(threads[gidx]["frame"]);
        threadsList << i;
    }
    setThreads(threadsList);
    if (r.hasField("current-thread-id"))
        setCurrentThread(r["current-thread-id"].toInt());
}
    virtual void handle(const GDBMI::ResultRecord &r)
    {
        if (!m_variable) return;
        bool hasValue = false;
        if (r.reason == "error") {
            /* Probably should mark this disabled, or something.  */
        } else {
            m_variable->deleteChildren();
            m_variable->setInScope(true);
            m_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;

            m_variable->setHasMore(hasMore);

            m_variable->setValue(r["value"].literal());
            hasValue = !r["value"].literal().isEmpty();
            if (m_variable->isExpanded() && r["numchild"].toInt()) {
                m_variable->fetchMoreChildren();
            }
        }

        if (m_callback && m_callbackMethod) {
            QMetaObject::invokeMethod(m_callback, m_callbackMethod, Q_ARG(bool, hasValue));
        }
    }
void VariableItem::createChildren(const GDBMI::ResultRecord& r,
                             bool children_of_fake)
{
    if (!r.hasField("children"))
        return;

    const GDBMI::Value& children = r["children"];

    /* In order to figure out which variable objects correspond
       to base class subobject, we first must detect if *this
       is a structure type. We use present of 'public'/'private'/'protected'
       fake child as an indicator. */
    bool structureType = false;
    if (!children_of_fake && children.size() > 0)
    {
        QString exp = children[0]["exp"].literal();
        bool ok = false;
        exp.toInt(&ok);
        if (!ok || exp[0] != '*')
        {
            structureType = true;
        }
    }

    for (int i = 0; i < children.size(); ++i)
    {
        QString exp = children[i]["exp"].literal();
        // For artificial accessibility nodes,
        // fetch their children.
        if (exp == "public" || exp == "protected" || exp == "private")
        {
            QString name = children[i]["name"].literal();
            addCommand(new GDBCommand(VarListChildren,
                                        "\"" +
                                        name + "\"",
                                        this,
                                        &VariableItem::childrenOfFakesDone));
        }
        else
        {
            /* All children of structures that are not artifical
               are base subobjects. */
            bool baseObject = structureType;

            VariableItem* existing = 0;
            foreach (AbstractVariableItem* child, AbstractVariableItem::children())
            {
                VariableItem* v = qobject_cast<VariableItem*>(child);
                kDebug(9012) << "Child exp:" << v->expression_ <<
                    "new exp" << exp;

                if (v->expression_ == exp)
                {
                    existing = v;
                }
            }

            if (existing)
            {
                existing->setVarobjName(children[i]["name"].literal());
            }
            else
            {
                kDebug(9012) << "Creating new varobj" << exp << baseObject;
                // Propagate format from parent.

                VariableItem* v = 0;
                QString type;
                if (children[i].hasField("type"))
                    type = children[i]["type"].literal();

                v = collection()->createVariableItem(type, this);

                v->setVariableObject(children[i], format_, baseObject);
                addChild(v);
            }
        }
    }
예제 #13
0
void QListVariableItem::handleBegin(const GDBMI::ResultRecord& r)
{
    if (r.hasField("value")) {
        m_begin = r["value"].toInt();
    }
}