예제 #1
0
/**
 * @callback_method_impl{FNDBGFHANDLERINT, Info handler for displaying the trace buffer content.}
 */
static DECLCALLBACK(void) dbgfR3TraceInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
{
    RTTRACEBUF hTraceBuf = pVM->hTraceBufR3;
    if (hTraceBuf == NIL_RTTRACEBUF)
        pHlp->pfnPrintf(pHlp, "Tracing is disable\n");
    else
    {
        pHlp->pfnPrintf(pHlp, "Trace buffer %p - %u entries of %u bytes\n",
                        hTraceBuf, RTTraceBufGetEntryCount(hTraceBuf), RTTraceBufGetEntrySize(hTraceBuf));
        RTTraceBufEnumEntries(hTraceBuf, dbgfR3TraceInfoDumpEntry, (void *)pHlp);
    }
    NOREF(pszArgs);
}
예제 #2
0
dbgfR3TraceInfoDumpEntry(RTTRACEBUF hTraceBuf, uint32_t iEntry, uint64_t NanoTS, RTCPUID idCpu, const char *pszMsg, void *pvUser)
{
    PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;
    pHlp->pfnPrintf(pHlp, "#%04u/%'llu/%02x: %s\n", iEntry, NanoTS, idCpu, pszMsg);
    NOREF(hTraceBuf);
    return VINF_SUCCESS;
}
예제 #3
0
/**
 * Info handler, internal version.
 *
 * @param   pVM         Pointer to the VM.
 * @param   pHlp        Callback functions for doing output.
 * @param   pszArgs     Argument string. Optional and specific to the handler.
 */
static DECLCALLBACK(void) dbgfR3InfoHelp(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
{
    LogFlow(("dbgfR3InfoHelp: pszArgs=%s\n", pszArgs));

    /*
     * Enter and enumerate.
     */
    PUVM pUVM = pVM->pUVM;
    int rc = RTCritSectEnter(&pUVM->dbgf.s.InfoCritSect);
    AssertRC(rc);

    if (pszArgs && *pszArgs)
    {
        for (PDBGFINFO pInfo = pUVM->dbgf.s.pInfoFirst; pInfo; pInfo = pInfo->pNext)
        {
            const char *psz = strstr(pszArgs, pInfo->szName);
            if (    psz
                &&  (   psz == pszArgs
                     || RT_C_IS_SPACE(psz[-1]))
                &&  (   !psz[pInfo->cchName]
                     || RT_C_IS_SPACE(psz[pInfo->cchName])))
                pHlp->pfnPrintf(pHlp, "%-16s  %s\n",
                                pInfo->szName, pInfo->pszDesc);
        }
    }
    else
    {
        for (PDBGFINFO pInfo = pUVM->dbgf.s.pInfoFirst; pInfo; pInfo = pInfo->pNext)
            pHlp->pfnPrintf(pHlp, "%-16s  %s\n",
                            pInfo->szName, pInfo->pszDesc);
    }

    /*
     * Leave and exit.
     */
    rc = RTCritSectLeave(&pUVM->dbgf.s.InfoCritSect);
    AssertRC(rc);
}
예제 #4
0
/**
 * Debug device info handler. Prints basic auxiliary device state.
 *
 * @param   pDevIns     Device instance which registered the info.
 * @param   pHlp        Callback functions for doing output.
 * @param   pszArgs     Argument string. Optional and specific to the handler.
 */
static DECLCALLBACK(void) ps2mInfoState(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
{
    static const char   *pcszModes[] = { "normal", "reset", "wrap" };
    static const char   *pcszProtocols[] = { "PS/2", NULL, NULL, "ImPS/2", "ImEx" };
    PPS2M   pThis = KBDGetPS2MFromDevIns(pDevIns);
    NOREF(pszArgs);

    Assert(pThis->enmMode <= RT_ELEMENTS(pcszModes));
    Assert(pThis->enmProtocol <= RT_ELEMENTS(pcszProtocols));
    pHlp->pfnPrintf(pHlp, "PS/2 mouse state: %s, %s mode, reporting %s\n",
                    pcszModes[pThis->enmMode],
                    pThis->u8State & AUX_STATE_REMOTE  ? "remote"  : "stream",
                    pThis->u8State & AUX_STATE_ENABLED ? "enabled" : "disabled");
    pHlp->pfnPrintf(pHlp, "Protocol: %s, scaling %u:1\n",
                    pcszProtocols[pThis->enmProtocol], pThis->u8State & AUX_STATE_SCALING ? 2 : 1);
    pHlp->pfnPrintf(pHlp, "Active command %02X\n", pThis->u8CurrCmd);
    pHlp->pfnPrintf(pHlp, "Sampling rate %u reports/sec, resolution %u counts/mm\n",
                    pThis->u8SampleRate, 1 << pThis->u8Resolution);
    pHlp->pfnPrintf(pHlp, "Command queue: %d items (%d max)\n",
                    pThis->cmdQ.cUsed, pThis->cmdQ.cSize);
    pHlp->pfnPrintf(pHlp, "Event queue  : %d items (%d max)\n",
                    pThis->evtQ.cUsed, pThis->evtQ.cSize);
}
예제 #5
0
/**
 * Display several info items.
 *
 * This is intended used by the fatal error dump only.
 *
 * @returns
 * @param   pVM             Pointer to the VM.
 * @param   pszIncludePat   Simple string pattern of info items to include.
 * @param   pszExcludePat   Simple string pattern of info items to exclude.
 * @param   pszSepFmt       Item separator format string.  The item name will be
 *                          given as parameter.
 * @param   pHlp            The output helper functions.  If NULL the logger
 *                          will be used.
 *
 * @threads EMT
 */
VMMR3DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *pszExcludePat, const char *pszSepFmt,
                               PCDBGFINFOHLP pHlp)
{
    /*
     * Validate input.
     */
    VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
    AssertPtrReturn(pszIncludePat, VERR_INVALID_POINTER);
    AssertPtrReturn(pszExcludePat, VERR_INVALID_POINTER);
    if (pHlp)
    {
        AssertPtrReturn(pHlp->pfnPrintf, VERR_INVALID_POINTER);
        AssertPtrReturn(pHlp->pfnPrintfV, VERR_INVALID_POINTER);
    }
    else
        pHlp = &g_dbgfR3InfoLogHlp;

    size_t const cchIncludePat = strlen(pszIncludePat);
    size_t const cchExcludePat = strlen(pszExcludePat);
    const char *pszArgs = "";

    /*
     * Enumerate the info handlers and call the ones matching.
     * Note! We won't leave the critical section here...
     */
    int rc = RTCritSectEnter(&pVM->dbgf.s.InfoCritSect);
    AssertRC(rc);
    rc = VWRN_NOT_FOUND;
    for (PDBGFINFO pInfo = pVM->dbgf.s.pInfoFirst; pInfo; pInfo = pInfo->pNext)
    {
        if (   RTStrSimplePatternMultiMatch(pszIncludePat, cchIncludePat, pInfo->szName, pInfo->cchName, NULL)
            && !RTStrSimplePatternMultiMatch(pszExcludePat, cchExcludePat, pInfo->szName, pInfo->cchName, NULL))
        {
            pHlp->pfnPrintf(pHlp, pszSepFmt, pInfo->szName);
            rc = VINF_SUCCESS;
            switch (pInfo->enmType)
            {
                case DBGFINFOTYPE_DEV:
                    if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
                        rc = VMR3ReqCallVoidWait(pVM, VMCPUID_ANY, (PFNRT)pInfo->u.Dev.pfnHandler, 3, pInfo->u.Dev.pDevIns, pHlp, pszArgs);
                    else
                        pInfo->u.Dev.pfnHandler(pInfo->u.Dev.pDevIns, pHlp, pszArgs);
                    break;

                case DBGFINFOTYPE_DRV:
                    if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
                        rc = VMR3ReqCallVoidWait(pVM, VMCPUID_ANY, (PFNRT)pInfo->u.Drv.pfnHandler, 3, pInfo->u.Drv.pDrvIns, pHlp, pszArgs);
                    else
                        pInfo->u.Drv.pfnHandler(pInfo->u.Drv.pDrvIns, pHlp, pszArgs);
                    break;

                case DBGFINFOTYPE_INT:
                    if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
                        rc = VMR3ReqCallVoidWait(pVM, VMCPUID_ANY, (PFNRT)pInfo->u.Int.pfnHandler, 3, pVM, pHlp, pszArgs);
                    else
                        pInfo->u.Int.pfnHandler(pVM, pHlp, pszArgs);
                    break;

                case DBGFINFOTYPE_EXT:
                    if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
                        rc = VMR3ReqCallVoidWait(pVM, VMCPUID_ANY, (PFNRT)pInfo->u.Ext.pfnHandler, 3, pInfo->u.Ext.pvUser, pHlp, pszArgs);
                    else
                        pInfo->u.Ext.pfnHandler(pInfo->u.Ext.pvUser, pHlp, pszArgs);
                    break;

                default:
                    AssertMsgFailedReturn(("Invalid info type enmType=%d\n", pInfo->enmType), VERR_IPE_NOT_REACHED_DEFAULT_CASE);
            }
        }
    }
    int rc2 = RTCritSectLeave(&pVM->dbgf.s.InfoCritSect);
    AssertRC(rc2);

    return rc;
}