Beispiel #1
0
void GdbDebugger::handleResultStackListFrame(const GdbResponse &response, QMap<QString,QVariant> &map)
{
    //10000015^done,stack=[frame={level="0",addr="0x0040113f",func="main.main",file="F:/hg/debug_test/hello/main.go",fullname="F:/hg/debug_test/hello/main.go",line="36"},frame={level="1",addr="0x00401f8a",func="runtime.mainstart",file="386/asm.s",fullname="c:/go/src/pkg/runtime/386/asm.s",line="96"},frame={level="2",addr="0x0040bcfe",func="runtime.initdone",file="/go/src/pkg/runtime/proc.c",fullname="c:/go/src/pkg/runtime/proc.c",line="242"},frame={level="3",addr="0x00000000",func="??"}]
    m_framesModel->removeRows(0,m_framesModel->rowCount());
    if (response.resultClass != GdbResultDone) {
        return;
    }
    GdbMiValue stack = response.data.findChild("stack");
    if (stack.isList()) {
        for (int i = 0; i < stack.childCount(); i++) {
            GdbMiValue child = stack.childAt(i);
            if (child.isValid() && child.name() == "frame") {
                QString level = child.findChild("level").data();
                QString addr = child.findChild("addr").data();
                QString func = child.findChild("func").data();
                QString file = child.findChild("file").data();
                QString line = child.findChild("line").data();
                m_framesModel->appendRow(QList<QStandardItem*>()
                                         << new QStandardItem(level)
                                         << new QStandardItem(addr)
                                         << new QStandardItem(func)
                                         << new QStandardItem(file)
                                         << new QStandardItem(line)
                                         );
            }
        }
    }
}
Beispiel #2
0
void GdbDebugger::handleLibrary(const GdbMiValue &result)
{
    QString id = result.findChild("id").data();
    QString thread_group = result.findChild("thread-group").data();
    m_libraryModel->appendRow(QList<QStandardItem*>()
                              << new QStandardItem(id)
                              << new QStandardItem(thread_group)
                              );
}
Beispiel #3
0
void GdbDebugger::handleResultStackListVariables(const GdbResponse &response, QMap<QString,QVariant> &map)
{
    //10000014^done,variables=[{name="v"},{name="x"},{name="pt"},{name="str"},{name="sum1"},{name="y"}]
    if (response.resultClass != GdbResultDone) {
        return;
    }
    GdbMiValue vars = response.data.findChild("variables");
    if (vars.isList()) {
        foreach (const GdbMiValue &child, vars.m_children) {
            if (child.isValid()) {
                QString var = child.findChild("name").data();
                if (!m_varNameMap.contains(var)) {
                    createWatch(var,true,false);
                }
            }
        }
    }
Beispiel #4
0
void GdbDebugger::handleStopped(const GdbMiValue &result)
{
    QByteArray reason = result.findChild("reason").data();
    m_handleState.setReason(reason);
    m_handleState.setStopped(true);
    if (reason.startsWith("exited")) {
        m_handleState.setExited(true);
        m_handleState.setReason(reason);
        return;
    }
    GdbMiValue frame = result.findChild("frame");
    if (frame.isValid()) {
        QString fullname = frame.findChild("fullname").data();
        QString file = frame.findChild("file").data();
        QString line = frame.findChild("line").data();
        if (!fullname.isEmpty()) {
            emit setCurrentLine(fullname,line.toInt()-1);
        } else if (!file.isEmpty()) {
            //fix go build bug, not find fullname
            //file="C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist308287094/go/src/pkg/fmt/print.go"
            int i = file.indexOf("/go/src/pkg");
            if (i > 0) {
                QString fullname = LiteApi::getGoroot(m_liteApp)+file.right(file.length()-i-3);
                emit setCurrentLine(fullname,line.toInt()-1);
            }
        }
    }
}
Beispiel #5
0
static void GdbMiValueToItem(QStandardItem *item, const GdbMiValue &value)
{
    switch (value.type()) {
    case GdbMiValue::Invalid:
        item->appendRow(new QStandardItem("Invalid"));
        break;
    case GdbMiValue::Const:
        if (value.name().isEmpty()) {
            item->appendRow(new QStandardItem(QString(value.data())));
        } else {
            item->appendRow(new QStandardItem(QString(value.name()+"="+value.data())));
        }
        break;
    case GdbMiValue::List: {
            QStandardItem *in = new QStandardItem(QString(value.name()));
            item->appendRow(in);
            for (int i = 0; i < value.childCount(); i++) {
                QStandardItem *iv = new QStandardItem(QString("[%1]").arg(i));
                in->appendRow(iv);
                GdbMiValueToItem(iv,value.childAt(i));
            }
            break;
        }
    case GdbMiValue::Tuple: {
            QStandardItem *iv = item;
            if (!value.name().isEmpty()) {
                iv = new QStandardItem(QString(value.name()));
                item->appendRow(iv);
            }
            foreach (const GdbMiValue &v, value.children()) {
                GdbMiValueToItem(iv,v);
            }
            break;
       }
    }
}
Beispiel #6
0
void GdbDebugger::handleResponse(const QByteArray &buff)
{
    if (buff.isEmpty() || buff == "(gdb) ")
        return;

    const char *from = buff.constData();
    const char *to = from + buff.size();
    const char *inner;

    int token = -1;
    // Token is a sequence of numbers.
    for (inner = from; inner != to; ++inner)
        if (*inner < '0' || *inner > '9')
            break;
    if (from != inner) {
        token = QByteArray(from, inner - from).toInt();
        from = inner;
    }
    // Next char decides kind of response.
    const char c = *from++;
    switch (c) {
    case '*':
    case '+':
    case '=':
    {
        QByteArray asyncClass;
        for (; from != to; ++from) {
            const char c = *from;
            if (!isNameChar(c))
                break;
            asyncClass += *from;
        }
        GdbMiValue result;
        while (from != to) {
            GdbMiValue data;
            if (*from != ',') {
                // happens on archer where we get
                // 23^running <NL> *running,thread-id="all" <NL> (gdb)
                result.m_type = GdbMiValue::Tuple;
                break;
            }
            ++from; // skip ','
            data.parseResultOrValue(from, to);
            if (data.isValid()) {
                //qDebug() << "parsed result:" << data.toString();
                result.m_children += data;
                result.m_type = GdbMiValue::Tuple;
            }
        }
        handleAsyncClass(asyncClass,result);
        break;
    }
    case '~':
        handleConsoleStream(GdbMiValue::parseCString(from, to));
        break;
    case '@':
        handleTargetStream(GdbMiValue::parseCString(from, to));
        break;
    case '&':
        handleLogStream(GdbMiValue::parseCString(from, to));
        break;
    case '^': {
        GdbResponse response;

        response.token = token;

        for (inner = from; inner != to; ++inner)
            if (*inner < 'a' || *inner > 'z')
                break;

        QByteArray resultClass = QByteArray::fromRawData(from, inner - from);
        if (resultClass == "done") {
            response.resultClass = GdbResultDone;
        } else if (resultClass == "running") {
            response.resultClass = GdbResultRunning;
        } else if (resultClass == "connected") {
            response.resultClass = GdbResultConnected;
        } else if (resultClass == "error") {
            response.resultClass = GdbResultError;
        } else if (resultClass == "exit") {
            response.resultClass = GdbResultExit;
        } else {
            response.resultClass = GdbResultUnknown;
        }

        from = inner;
        if (from != to) {
            if (*from == ',') {
                ++from;
                response.data.parseTuple_helper(from, to);
                response.data.m_type = GdbMiValue::Tuple;
                response.data.m_name = "data";
            } else {
                // Archer has this.
                response.data.m_type = GdbMiValue::Tuple;
                response.data.m_name = "data";
            }
        }
        if (m_tokenCookieMap.contains(token)) {
            response.cookie = m_tokenCookieMap.take(token);
        }
        handleResultRecord(response);
        break;
    }
    default: {
        from--;
        QByteArray out(from,to-from);
        out.append("\n");
        emit debugLog(LiteApi::DebugApplationLog,QString::fromUtf8(out));
        break;
    }
    }
}