VirtualBox

Changeset 84707 in vbox for trunk


Ignore:
Timestamp:
Jun 5, 2020 6:12:41 PM (5 years ago)
Author:
vboxsync
Message:

Debugger/DBGCGdbRemoteStub: Started with SMP support, bugref:5217

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Debugger/DBGCGdbRemoteStub.cpp

    r84694 r84707  
    154154     * Means we have to track all registration so we can remove them later on. */
    155155    RTLISTANCHOR                LstTps;
     156    /** Flag whether a ThreadInfo query was started. */
     157    bool                        fInThrdInfoQuery;
     158    /** Next ID to return in the current ThreadInfo query. */
     159    VMCPUID                     idCpuNextThrdInfoQuery;
    156160} GDBSTUBCTX;
    157161/** Pointer to the GDB stub context data. */
     
    582586static int dbgcGdbStubCtxReplySendSigTrap(PGDBSTUBCTX pThis)
    583587{
    584     uint8_t achSigTrap[3] = { 'S', '0', '5' };
    585     return dbgcGdbStubCtxReplySend(pThis, &achSigTrap[0], sizeof(achSigTrap));
     588    char achReply[32];
     589    ssize_t cchStr = RTStrPrintf2(&achReply[0], sizeof(achReply), "T05thread:%02x;", pThis->Dbgc.idCpu + 1);
     590    return dbgcGdbStubCtxReplySend(pThis, &achReply[0], cchStr);
    586591}
    587592
     
    793798    /** @todo Enhance. */
    794799    if (pThis->fFeatures & GDBSTUBCTX_FEATURES_F_TGT_DESC)
    795         return dbgcGdbStubCtxReplySend(pThis, "qXfer:features:read+", sizeof("qXfer:features:read+") - 1);
     800        return dbgcGdbStubCtxReplySend(pThis, "qXfer:features:read+;vContSupported+", sizeof("qXfer:features:read+;vContSupported+") - 1);
    796801
    797802    return dbgcGdbStubCtxReplySend(pThis, NULL, 0);
     
    11281133
    11291134/**
     1135 * Processes the 'C' query (query current thread ID).
     1136 *
     1137 * @returns Status code.
     1138 * @param   pThis               The GDB stub context.
     1139 * @param   pbArgs              Pointer to the start of the arguments in the packet.
     1140 * @param   cbArgs              Size of arguments in bytes.
     1141 */
     1142static int dbgcGdbStubCtxPktProcessQueryThreadId(PGDBSTUBCTX pThis, const uint8_t *pbArgs, size_t cbArgs)
     1143{
     1144    RT_NOREF(pbArgs, cbArgs);
     1145
     1146    int rc = VERR_BUFFER_OVERFLOW;
     1147    char achReply[32];
     1148    ssize_t cchStr = RTStrPrintf(&achReply[0], sizeof(achReply), "QC %02x", pThis->Dbgc.idCpu + 1);
     1149    if (cchStr > 0)
     1150        rc = dbgcGdbStubCtxReplySend(pThis, &achReply[0], cchStr);
     1151
     1152    return rc;
     1153}
     1154
     1155
     1156/**
     1157 * Processes the 'Attached' query.
     1158 *
     1159 * @returns Status code.
     1160 * @param   pThis               The GDB stub context.
     1161 * @param   pbArgs              Pointer to the start of the arguments in the packet.
     1162 * @param   cbArgs              Size of arguments in bytes.
     1163 */
     1164static int dbgcGdbStubCtxPktProcessQueryAttached(PGDBSTUBCTX pThis, const uint8_t *pbArgs, size_t cbArgs)
     1165{
     1166    RT_NOREF(pbArgs, cbArgs);
     1167
     1168    /* We always report attached so that the VM doesn't get killed when GDB quits. */
     1169    uint8_t bAttached = '1';
     1170    return dbgcGdbStubCtxReplySend(pThis, &bAttached, sizeof(bAttached));
     1171}
     1172
     1173
     1174/**
    11301175 * Processes the 'Xfer:features:read' query.
    11311176 *
     
    12341279
    12351280/**
     1281 * Worker for both 'qfThreadInfo' and 'qsThreadInfo'.
     1282 *
     1283 * @returns VBox status code.
     1284 * @param   pThis               The GDB stub context.
     1285 */
     1286static int dbgcGdbStubCtxPktProcessQueryThreadInfoWorker(PGDBSTUBCTX pThis)
     1287{
     1288    int rc = dbgcGdbStubCtxReplySendBegin(pThis);
     1289    if (RT_SUCCESS(rc))
     1290    {
     1291        uint8_t bReplyStart = { 'm' };
     1292        rc = dbgcGdbStubCtxReplySendData(pThis, &bReplyStart, sizeof(bReplyStart));
     1293        if (RT_SUCCESS(rc))
     1294        {
     1295            char achReply[32];
     1296            ssize_t cchStr = RTStrPrintf(&achReply[0], sizeof(achReply), "%02x", pThis->idCpuNextThrdInfoQuery + 1);
     1297            if (cchStr <= 0)
     1298                rc = VERR_BUFFER_OVERFLOW;
     1299
     1300            if (RT_SUCCESS(rc))
     1301                rc = dbgcGdbStubCtxReplySendData(pThis, &achReply[0], cchStr);
     1302            pThis->idCpuNextThrdInfoQuery++;
     1303        }
     1304
     1305        rc = dbgcGdbStubCtxReplySendEnd(pThis);
     1306    }
     1307
     1308    return rc;
     1309}
     1310
     1311
     1312/**
     1313 * Processes the 'fThreadInfo' query.
     1314 *
     1315 * @returns Status code.
     1316 * @param   pThis               The GDB stub context.
     1317 * @param   pbArgs              Pointer to the start of the arguments in the packet.
     1318 * @param   cbArgs              Size of arguments in bytes.
     1319 */
     1320static int dbgcGdbStubCtxPktProcessQueryThreadInfoStart(PGDBSTUBCTX pThis, const uint8_t *pbArgs, size_t cbArgs)
     1321{
     1322    RT_NOREF(pbArgs, cbArgs);
     1323
     1324    pThis->idCpuNextThrdInfoQuery = 0;
     1325    pThis->fInThrdInfoQuery = true;
     1326    return dbgcGdbStubCtxPktProcessQueryThreadInfoWorker(pThis);
     1327}
     1328
     1329
     1330/**
     1331 * Processes the 'fThreadInfo' query.
     1332 *
     1333 * @returns Status code.
     1334 * @param   pThis               The GDB stub context.
     1335 * @param   pbArgs              Pointer to the start of the arguments in the packet.
     1336 * @param   cbArgs              Size of arguments in bytes.
     1337 */
     1338static int dbgcGdbStubCtxPktProcessQueryThreadInfoCont(PGDBSTUBCTX pThis, const uint8_t *pbArgs, size_t cbArgs)
     1339{
     1340    RT_NOREF(pbArgs, cbArgs);
     1341
     1342    /* If we are in a thread info query we just send the end of list specifier (all thread IDs where sent previously already). */
     1343    if (!pThis->fInThrdInfoQuery)
     1344        return dbgcGdbStubCtxReplySendErrSts(pThis, VERR_NET_PROTOCOL_ERROR);
     1345
     1346    VMCPUID cCpus = DBGFR3CpuGetCount(pThis->Dbgc.pUVM);
     1347    if (pThis->idCpuNextThrdInfoQuery == cCpus)
     1348    {
     1349        pThis->fInThrdInfoQuery = false;
     1350        uint8_t bEoL = 'l';
     1351        return dbgcGdbStubCtxReplySend(pThis, &bEoL, sizeof(bEoL));
     1352    }
     1353
     1354    return dbgcGdbStubCtxPktProcessQueryThreadInfoWorker(pThis);
     1355}
     1356
     1357
     1358/**
     1359 * Processes the 'ThreadExtraInfo' query.
     1360 *
     1361 * @returns Status code.
     1362 * @param   pThis               The GDB stub context.
     1363 * @param   pbArgs              Pointer to the start of the arguments in the packet.
     1364 * @param   cbArgs              Size of arguments in bytes.
     1365 */
     1366static int dbgcGdbStubCtxPktProcessQueryThreadExtraInfo(PGDBSTUBCTX pThis, const uint8_t *pbArgs, size_t cbArgs)
     1367{
     1368    /* Skip the , following the qThreadExtraInfo start. */
     1369    if (   cbArgs < 1
     1370        || pbArgs[0] != ',')
     1371        return VERR_NET_PROTOCOL_ERROR;
     1372
     1373    cbArgs--;
     1374    pbArgs++;
     1375
     1376    /* We know there is an # character denoting the end so the following must return with VWRN_TRAILING_CHARS. */
     1377    VMCPUID idCpu;
     1378    int rc = RTStrToUInt32Ex((const char *)pbArgs, NULL /*ppszNext*/, 16, &idCpu);
     1379    if (   rc == VWRN_TRAILING_CHARS
     1380        && idCpu > 0)
     1381    {
     1382        idCpu--;
     1383
     1384        VMCPUID cCpus = DBGFR3CpuGetCount(pThis->Dbgc.pUVM);
     1385        if (idCpu < cCpus)
     1386        {
     1387            const char *pszCpuState = DBGFR3CpuGetState(pThis->Dbgc.pUVM, idCpu);
     1388            size_t cchCpuState = strlen(pszCpuState);
     1389
     1390            if (!pszCpuState)
     1391                pszCpuState = "DBGFR3CpuGetState() -> NULL";
     1392
     1393            rc = dbgcGdbStubCtxReplySendBegin(pThis);
     1394            if (RT_SUCCESS(rc))
     1395            {
     1396                /* Convert the characters to hex. */
     1397                const char *pachCur = pszCpuState;
     1398
     1399                while (   cchCpuState
     1400                       && RT_SUCCESS(rc))
     1401                {
     1402                    uint8_t achHex[512 + 1];
     1403                    size_t cbThisSend = RT_MIN((sizeof(achHex) - 1) / 2, cchCpuState); /* Each character needs two bytes. */
     1404
     1405                    rc = dbgcGdbStubCtxEncodeBinaryAsHex(&achHex[0], cbThisSend * 2 + 1, pachCur, cbThisSend);
     1406                    if (RT_SUCCESS(rc))
     1407                        rc = dbgcGdbStubCtxReplySendData(pThis, &achHex[0], cbThisSend * 2);
     1408
     1409                    pachCur     += cbThisSend;
     1410                    cchCpuState -= cbThisSend;
     1411                }
     1412
     1413                dbgcGdbStubCtxReplySendEnd(pThis);
     1414            }
     1415        }
     1416        else
     1417            rc = dbgcGdbStubCtxReplySendErrSts(pThis, VERR_NET_PROTOCOL_ERROR);
     1418    }
     1419    else if (   RT_SUCCESS(rc)
     1420             || !idCpu)
     1421        rc = dbgcGdbStubCtxReplySendErrSts(pThis, VERR_NET_PROTOCOL_ERROR);
     1422
     1423    return rc;
     1424}
     1425
     1426
     1427/**
    12361428 * List of supported query packets.
    12371429 */
     
    12391431{
    12401432#define GDBSTUBQPKTPROC_INIT(a_Name, a_pfnProc) { a_Name, sizeof(a_Name) - 1, a_pfnProc }
     1433    GDBSTUBQPKTPROC_INIT("C",                  dbgcGdbStubCtxPktProcessQueryThreadId),
     1434    GDBSTUBQPKTPROC_INIT("Attached",           dbgcGdbStubCtxPktProcessQueryAttached),
    12411435    GDBSTUBQPKTPROC_INIT("TStatus",            dbgcGdbStubCtxPktProcessQueryTStatus),
    12421436    GDBSTUBQPKTPROC_INIT("Supported",          dbgcGdbStubCtxPktProcessQuerySupported),
    12431437    GDBSTUBQPKTPROC_INIT("Xfer:features:read", dbgcGdbStubCtxPktProcessQueryXferFeatRead),
    12441438    GDBSTUBQPKTPROC_INIT("Rcmd",               dbgcGdbStubCtxPktProcessQueryRcmd),
     1439    GDBSTUBQPKTPROC_INIT("fThreadInfo",        dbgcGdbStubCtxPktProcessQueryThreadInfoStart),
     1440    GDBSTUBQPKTPROC_INIT("sThreadInfo",        dbgcGdbStubCtxPktProcessQueryThreadInfoCont),
     1441    GDBSTUBQPKTPROC_INIT("ThreadExtraInfo",    dbgcGdbStubCtxPktProcessQueryThreadExtraInfo),
    12451442#undef GDBSTUBQPKTPROC_INIT
    12461443};
     
    13811578
    13821579/**
     1580 * Processes a 'H<op><thread-id>' packet, sending the appropriate reply.
     1581 *
     1582 * @returns Status code.
     1583 * @param   pThis               The GDB stub context.
     1584 * @param   pbPktRem            The remaining packet data (without the 'H').
     1585 * @param   cbPktRem            Size of the remaining packet in bytes.
     1586 */
     1587static int dbgcGdbStubCtxPktProcessH(PGDBSTUBCTX pThis, const uint8_t *pbPktRem, size_t cbPktRem)
     1588{
     1589    int rc = VINF_SUCCESS;
     1590
     1591    if (*pbPktRem == 'g')
     1592    {
     1593        cbPktRem--;
     1594        pbPktRem++;
     1595
     1596        /* We know there is an # character denoting the end so the following must return with VWRN_TRAILING_CHARS. */
     1597        VMCPUID idCpu;
     1598        rc = RTStrToUInt32Ex((const char *)pbPktRem, NULL /*ppszNext*/, 16, &idCpu);
     1599        if (   rc == VWRN_TRAILING_CHARS
     1600            && idCpu > 0)
     1601        {
     1602            idCpu--;
     1603
     1604            VMCPUID cCpus = DBGFR3CpuGetCount(pThis->Dbgc.pUVM);
     1605            if (idCpu < cCpus)
     1606            {
     1607                pThis->Dbgc.idCpu = idCpu;
     1608                rc = dbgcGdbStubCtxReplySendOk(pThis);
     1609            }
     1610            else
     1611                rc = dbgcGdbStubCtxReplySendErrSts(pThis, VERR_NET_PROTOCOL_ERROR);
     1612        }
     1613        else
     1614            rc = dbgcGdbStubCtxReplySendErrSts(pThis, VERR_NET_PROTOCOL_ERROR);
     1615    }
     1616    else /* Do not support the 'c' operation for now (will be handled through vCont later on anyway). */
     1617        rc = dbgcGdbStubCtxReplySend(pThis, NULL, 0);
     1618
     1619    return rc;
     1620}
     1621
     1622
     1623/**
    13831624 * Processes a completely received packet.
    13841625 *
     
    14201661                if (DBGFR3IsHalted(pThis->Dbgc.pUVM))
    14211662                    DBGFR3Resume(pThis->Dbgc.pUVM);
     1663                break;
     1664            }
     1665            case 'H':
     1666            {
     1667                rc = dbgcGdbStubCtxPktProcessH(pThis, &pThis->pbPktBuf[2], pThis->cbPkt - 1);
     1668                break;
     1669            }
     1670            case 'T':
     1671            {
     1672                rc = dbgcGdbStubCtxReplySendOk(pThis);
    14221673                break;
    14231674            }
     
    21512402        }
    21522403
    2153 #if 0
    21542404        default:
    21552405        {
     
    22122462    }
    22132463
    2214     /*
    2215      * Prompt, anyone?
    2216      */
    2217     if (fPrintPrompt && RT_SUCCESS(rc))
    2218     {
    2219         rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "VBoxDbg> ");
    2220         pDbgc->fReady = true;
    2221         if (RT_SUCCESS(rc))
    2222             pDbgc->pBack->pfnSetReady(pDbgc->pBack, true);
    2223         pDbgc->cMultiStepsLeft = 0;
    2224     }
    2225 #else
    2226         default:
    2227             break;
    2228     }
    2229 #endif
    2230 
    22312464    return rc;
    22322465}
     
    24252658
    24262659    /* Init the GDB stub specific parts. */
    2427     pThis->cbPktBufMax     = 0;
    2428     pThis->pbPktBuf        = NULL;
    2429     pThis->fFeatures       = GDBSTUBCTX_FEATURES_F_TGT_DESC;
    2430     pThis->pachTgtXmlDesc  = NULL;
    2431     pThis->cbTgtXmlDesc    = 0;
    2432     pThis->fExtendedMode   = false;
    2433     pThis->fOutput         = false;
     2660    pThis->cbPktBufMax      = 0;
     2661    pThis->pbPktBuf         = NULL;
     2662    pThis->fFeatures        = GDBSTUBCTX_FEATURES_F_TGT_DESC;
     2663    pThis->pachTgtXmlDesc   = NULL;
     2664    pThis->cbTgtXmlDesc     = 0;
     2665    pThis->fExtendedMode    = false;
     2666    pThis->fOutput          = false;
     2667    pThis->fInThrdInfoQuery = false;
    24342668    RTListInit(&pThis->LstTps);
    24352669    dbgcGdbStubCtxReset(pThis);
     
    25012735            pThis->Dbgc.pUVM  = pUVM;
    25022736            pThis->Dbgc.idCpu = 0;
    2503             rc = pThis->Dbgc.CmdHlp.pfnPrintf(&pThis->Dbgc.CmdHlp, NULL,
    2504                                               "Current VM is %08x, CPU #%u\n" /** @todo get and print the VM name! */
    2505                                               , pThis->Dbgc.pVM, pThis->Dbgc.idCpu);
    25062737        }
    25072738        else
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette