/** * Does a full invalidation of the VM display and instructs the VM * to update it immediately. * * @returns COM status code */ STDMETHODIMP Display::InvalidateAndUpdate() { LogFlow (("Display::InvalidateAndUpdate(): BEGIN\n")); HRESULT rc = S_OK; LogFlow (("Display::InvalidateAndUpdate(): sending DPYUPDATE request\n")); Assert(gpVM); /* pdm.h says that this has to be called from the EMT thread */ int rcVBox = VMR3ReqCallVoidWait(gpVM, VMCPUID_ANY, (PFNRT)Display::doInvalidateAndUpdate, 1, mpDrv); if (RT_FAILURE(rcVBox)) rc = E_FAIL; LogFlow (("Display::InvalidateAndUpdate(): END: rc=%08X\n", rc)); return rc; }
int main(int argc, char **argv) { int rcRet = 0; /* error count. */ RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB); /* * Create empty VM. */ PVM pVM; int rc = VMR3Create(1, NULL, NULL, NULL, NULL, NULL, &pVM); if (RT_SUCCESS(rc)) { /* * Do testing. */ rc = VMR3ReqCallVoidWait(pVM, VMCPUID_ANY, (PFNRT)doit, 1, pVM); AssertRC(rc); STAMR3Dump(pVM, "*"); /* * Cleanup. */ rc = VMR3Destroy(pVM); if (!RT_SUCCESS(rc)) { RTPrintf(TESTCASE ": error: failed to destroy vm! rc=%d\n", rc); rcRet++; } } else { RTPrintf(TESTCASE ": fatal error: failed to create vm! rc=%d\n", rc); rcRet++; } return rcRet; }
/** * 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; }
/** * Worker for DBGFR3Info and DBGFR3InfoEx. * * @returns VBox status code. * @param pVM Pointer to the VM. * @param idCpu Which CPU to run EMT bound handlers on. * VMCPUID_ANY or a valid CPU ID. * @param pszName What to dump. * @param pszArgs Arguments, optional. * @param pHlp Output helper, optional. */ static DECLCALLBACK(int) dbgfR3Info(PVM pVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp) { /* * Validate input. */ AssertPtrReturn(pszName, VERR_INVALID_POINTER); if (pHlp) { if ( !pHlp->pfnPrintf || !pHlp->pfnPrintfV) { AssertMsgFailed(("A pHlp member is missing!\n")); return VERR_INVALID_PARAMETER; } } else pHlp = &g_dbgfR3InfoLogHlp; /* * Find the info handler. */ size_t cchName = strlen(pszName); int rc = RTCritSectEnter(&pVM->dbgf.s.InfoCritSect); AssertRC(rc); PDBGFINFO pInfo = pVM->dbgf.s.pInfoFirst; for (; pInfo; pInfo = pInfo->pNext) if ( pInfo->cchName == cchName && !memcmp(pInfo->szName, pszName, cchName)) break; if (pInfo) { /* * Found it. * Make a copy of it on the stack so we can leave the crit sect. * Switch on the type and invoke the handler. */ DBGFINFO Info = *pInfo; rc = RTCritSectLeave(&pVM->dbgf.s.InfoCritSect); AssertRC(rc); rc = VINF_SUCCESS; switch (Info.enmType) { case DBGFINFOTYPE_DEV: if (Info.fFlags & DBGFINFO_FLAGS_RUN_ON_EMT) rc = VMR3ReqCallVoidWait(pVM, idCpu, (PFNRT)Info.u.Dev.pfnHandler, 3, Info.u.Dev.pDevIns, pHlp, pszArgs); else Info.u.Dev.pfnHandler(Info.u.Dev.pDevIns, pHlp, pszArgs); break; case DBGFINFOTYPE_DRV: if (Info.fFlags & DBGFINFO_FLAGS_RUN_ON_EMT) rc = VMR3ReqCallVoidWait(pVM, idCpu, (PFNRT)Info.u.Drv.pfnHandler, 3, Info.u.Drv.pDrvIns, pHlp, pszArgs); else Info.u.Drv.pfnHandler(Info.u.Drv.pDrvIns, pHlp, pszArgs); break; case DBGFINFOTYPE_INT: if (Info.fFlags & DBGFINFO_FLAGS_RUN_ON_EMT) rc = VMR3ReqCallVoidWait(pVM, idCpu, (PFNRT)Info.u.Int.pfnHandler, 3, pVM, pHlp, pszArgs); else Info.u.Int.pfnHandler(pVM, pHlp, pszArgs); break; case DBGFINFOTYPE_EXT: if (Info.fFlags & DBGFINFO_FLAGS_RUN_ON_EMT) rc = VMR3ReqCallVoidWait(pVM, idCpu, (PFNRT)Info.u.Ext.pfnHandler, 3, Info.u.Ext.pvUser, pHlp, pszArgs); else Info.u.Ext.pfnHandler(Info.u.Ext.pvUser, pHlp, pszArgs); break; default: AssertMsgFailedReturn(("Invalid info type enmType=%d\n", Info.enmType), VERR_IPE_NOT_REACHED_DEFAULT_CASE); } } else { rc = RTCritSectLeave(&pVM->dbgf.s.InfoCritSect); AssertRC(rc); rc = VERR_FILE_NOT_FOUND; } return rc; }