/** * Initializes the tracing. * * @returns VBox status code * @param pVM The cross context VM structure. */ int dbgfR3TraceInit(PVM pVM) { /* * Initialize the trace buffer handles. */ Assert(NIL_RTTRACEBUF == (RTTRACEBUF)NULL); pVM->hTraceBufR3 = NIL_RTTRACEBUF; pVM->hTraceBufRC = NIL_RTRCPTR; pVM->hTraceBufR0 = NIL_RTR0PTR; /* * Check the config and enable tracing if requested. */ PCFGMNODE pDbgfNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "DBGF"); #if defined(DEBUG) || defined(RTTRACE_ENABLED) bool const fDefault = false; const char * const pszConfigDefault = ""; #else bool const fDefault = false; const char * const pszConfigDefault = ""; #endif bool fTracingEnabled; int rc = CFGMR3QueryBoolDef(pDbgfNode, "TracingEnabled", &fTracingEnabled, fDefault); AssertRCReturn(rc, rc); if (fTracingEnabled) { rc = dbgfR3TraceEnable(pVM, 0, 0); if (RT_SUCCESS(rc)) { if (pDbgfNode) { char *pszTracingConfig; rc = CFGMR3QueryStringAllocDef(pDbgfNode, "TracingConfig", &pszTracingConfig, pszConfigDefault); if (RT_SUCCESS(rc)) { rc = DBGFR3TraceConfig(pVM, pszTracingConfig); if (RT_FAILURE(rc)) rc = VMSetError(pVM, rc, RT_SRC_POS, "TracingConfig=\"%s\" -> %Rrc", pszTracingConfig, rc); MMR3HeapFree(pszTracingConfig); } } else { rc = DBGFR3TraceConfig(pVM, pszConfigDefault); if (RT_FAILURE(rc)) rc = VMSetError(pVM, rc, RT_SRC_POS, "TracingConfig=\"%s\" (default) -> %Rrc", pszConfigDefault, rc); } } } /* * Register a debug info item that will dump the trace buffer content. */ if (RT_SUCCESS(rc)) rc = DBGFR3InfoRegisterInternal(pVM, "tracebuf", "Display the trace buffer content. No arguments.", dbgfR3TraceInfo); return rc; }
/** * Same as dbgfR3AsSearchEnv, except that the path is taken from the DBGF config * (CFGM). * * Nothing is done if the CFGM variable isn't set. * * @returns VBox status code. * @param pszFilename The filename. * @param pszCfgValue The name of the config variable (under /DBGF/). * @param pfnOpen The open callback function. * @param pvUser User argument for the callback. */ static int dbgfR3AsSearchCfgPath(PVM pVM, const char *pszFilename, const char *pszCfgValue, PFNDBGFR3ASSEARCHOPEN pfnOpen, void *pvUser) { char *pszPath; int rc = CFGMR3QueryStringAllocDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "/DBGF"), pszCfgValue, &pszPath, NULL); if (RT_FAILURE(rc)) return rc; if (!pszPath) return VERR_FILE_NOT_FOUND; rc = dbgfR3AsSearchPath(pszFilename, pszPath, pfnOpen, pvUser); MMR3HeapFree(pszPath); return rc; }
/** * Initializes the address space parts of DBGF. * * @returns VBox status code. * @param pUVM The user mode VM handle. */ int dbgfR3AsInit(PUVM pUVM) { Assert(pUVM->pVM); /* * Create the semaphore. */ int rc = RTSemRWCreate(&pUVM->dbgf.s.hAsDbLock); AssertRCReturn(rc, rc); /* * Create the debugging config instance and set it up, defaulting to * deferred loading in order to keep things fast. */ rc = RTDbgCfgCreate(&pUVM->dbgf.s.hDbgCfg, NULL, true /*fNativePaths*/); AssertRCReturn(rc, rc); rc = RTDbgCfgChangeUInt(pUVM->dbgf.s.hDbgCfg, RTDBGCFGPROP_FLAGS, RTDBGCFGOP_PREPEND, RTDBGCFG_FLAGS_DEFERRED); AssertRCReturn(rc, rc); static struct { RTDBGCFGPROP enmProp; const char *pszEnvName; const char *pszCfgName; } const s_aProps[] = { { RTDBGCFGPROP_FLAGS, "VBOXDBG_FLAGS", "Flags" }, { RTDBGCFGPROP_PATH, "VBOXDBG_PATH", "Path" }, { RTDBGCFGPROP_SUFFIXES, "VBOXDBG_SUFFIXES", "Suffixes" }, { RTDBGCFGPROP_SRC_PATH, "VBOXDBG_SRC_PATH", "SrcPath" }, }; PCFGMNODE pCfgDbgf = CFGMR3GetChild(CFGMR3GetRootU(pUVM), "/DBGF"); for (unsigned i = 0; i < RT_ELEMENTS(s_aProps); i++) { char szEnvValue[8192]; rc = RTEnvGetEx(RTENV_DEFAULT, s_aProps[i].pszEnvName, szEnvValue, sizeof(szEnvValue), NULL); if (RT_SUCCESS(rc)) { rc = RTDbgCfgChangeString(pUVM->dbgf.s.hDbgCfg, s_aProps[i].enmProp, RTDBGCFGOP_PREPEND, szEnvValue); if (RT_FAILURE(rc)) return VMR3SetError(pUVM, rc, RT_SRC_POS, "DBGF Config Error: %s=%s -> %Rrc", s_aProps[i].pszEnvName, szEnvValue, rc); } else if (rc != VERR_ENV_VAR_NOT_FOUND) return VMR3SetError(pUVM, rc, RT_SRC_POS, "DBGF Config Error: Error querying env.var. %s: %Rrc", s_aProps[i].pszEnvName, rc); char *pszCfgValue; rc = CFGMR3QueryStringAllocDef(pCfgDbgf, s_aProps[i].pszCfgName, &pszCfgValue, NULL); if (RT_FAILURE(rc)) return VMR3SetError(pUVM, rc, RT_SRC_POS, "DBGF Config Error: Querying /DBGF/%s -> %Rrc", s_aProps[i].pszCfgName, rc); if (pszCfgValue) { rc = RTDbgCfgChangeString(pUVM->dbgf.s.hDbgCfg, s_aProps[i].enmProp, RTDBGCFGOP_PREPEND, pszCfgValue); if (RT_FAILURE(rc)) return VMR3SetError(pUVM, rc, RT_SRC_POS, "DBGF Config Error: /DBGF/%s=%s -> %Rrc", s_aProps[i].pszCfgName, pszCfgValue, rc); } } /* * Prepend the NoArch and VBoxDbgSyms directories to the path. */ char szPath[RTPATH_MAX]; rc = RTPathAppPrivateNoArch(szPath, sizeof(szPath)); AssertRCReturn(rc, rc); #ifdef RT_OS_DARWIN rc = RTPathAppend(szPath, sizeof(szPath), "../Resources/VBoxDbgSyms/"); #else rc = RTDbgCfgChangeString(pUVM->dbgf.s.hDbgCfg, RTDBGCFGPROP_PATH, RTDBGCFGOP_PREPEND, szPath); AssertRCReturn(rc, rc); rc = RTPathAppend(szPath, sizeof(szPath), "VBoxDbgSyms/"); #endif AssertRCReturn(rc, rc); rc = RTDbgCfgChangeString(pUVM->dbgf.s.hDbgCfg, RTDBGCFGPROP_PATH, RTDBGCFGOP_PREPEND, szPath); AssertRCReturn(rc, rc); /* * Create the standard address spaces. */ RTDBGAS hDbgAs; rc = RTDbgAsCreate(&hDbgAs, 0, RTGCPTR_MAX, "Global"); AssertRCReturn(rc, rc); rc = DBGFR3AsAdd(pUVM, hDbgAs, NIL_RTPROCESS); AssertRCReturn(rc, rc); RTDbgAsRetain(hDbgAs); pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_GLOBAL)] = hDbgAs; RTDbgAsRetain(hDbgAs); pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_KERNEL)] = hDbgAs; rc = RTDbgAsCreate(&hDbgAs, 0, RTGCPHYS_MAX, "Physical"); AssertRCReturn(rc, rc); rc = DBGFR3AsAdd(pUVM, hDbgAs, NIL_RTPROCESS); AssertRCReturn(rc, rc); RTDbgAsRetain(hDbgAs); pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_PHYS)] = hDbgAs; rc = RTDbgAsCreate(&hDbgAs, 0, RTRCPTR_MAX, "HyperRawMode"); AssertRCReturn(rc, rc); rc = DBGFR3AsAdd(pUVM, hDbgAs, NIL_RTPROCESS); AssertRCReturn(rc, rc); RTDbgAsRetain(hDbgAs); pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC)] = hDbgAs; RTDbgAsRetain(hDbgAs); pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC_AND_GC_GLOBAL)] = hDbgAs; rc = RTDbgAsCreate(&hDbgAs, 0, RTR0PTR_MAX, "HyperRing0"); AssertRCReturn(rc, rc); rc = DBGFR3AsAdd(pUVM, hDbgAs, NIL_RTPROCESS); AssertRCReturn(rc, rc); RTDbgAsRetain(hDbgAs); pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_R0)] = hDbgAs; return VINF_SUCCESS; }
static int pdmacFileInitialize(PPDMASYNCCOMPLETIONEPCLASS pClassGlobals, PCFGMNODE pCfgNode) { PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pClassGlobals; RTFILEAIOLIMITS AioLimits; /** < Async I/O limitations. */ int rc = RTFileAioGetLimits(&AioLimits); #ifdef DEBUG if (RT_SUCCESS(rc) && RTEnvExist("VBOX_ASYNC_IO_FAILBACK")) rc = VERR_ENV_VAR_NOT_FOUND; #endif if (RT_FAILURE(rc)) { LogRel(("AIO: Async I/O manager not supported (rc=%Rrc). Falling back to simple manager\n", rc)); pEpClassFile->enmMgrTypeOverride = PDMACEPFILEMGRTYPE_SIMPLE; pEpClassFile->enmEpBackendDefault = PDMACFILEEPBACKEND_BUFFERED; } else { pEpClassFile->uBitmaskAlignment = AioLimits.cbBufferAlignment ? ~((RTR3UINTPTR)AioLimits.cbBufferAlignment - 1) : RTR3UINTPTR_MAX; pEpClassFile->cReqsOutstandingMax = AioLimits.cReqsOutstandingMax; if (pCfgNode) { /* Query the default manager type */ char *pszVal = NULL; rc = CFGMR3QueryStringAllocDef(pCfgNode, "IoMgr", &pszVal, "Async"); AssertLogRelRCReturn(rc, rc); rc = pdmacFileMgrTypeFromName(pszVal, &pEpClassFile->enmMgrTypeOverride); MMR3HeapFree(pszVal); if (RT_FAILURE(rc)) return rc; LogRel(("AIOMgr: Default manager type is \"%s\"\n", pdmacFileMgrTypeToName(pEpClassFile->enmMgrTypeOverride))); /* Query default backend type */ rc = CFGMR3QueryStringAllocDef(pCfgNode, "FileBackend", &pszVal, "NonBuffered"); AssertLogRelRCReturn(rc, rc); rc = pdmacFileBackendTypeFromName(pszVal, &pEpClassFile->enmEpBackendDefault); MMR3HeapFree(pszVal); if (RT_FAILURE(rc)) return rc; LogRel(("AIOMgr: Default file backend is \"%s\"\n", pdmacFileBackendTypeToName(pEpClassFile->enmEpBackendDefault))); #ifdef RT_OS_LINUX if ( pEpClassFile->enmMgrTypeOverride == PDMACEPFILEMGRTYPE_ASYNC && pEpClassFile->enmEpBackendDefault == PDMACFILEEPBACKEND_BUFFERED) { LogRel(("AIOMgr: Linux does not support buffered async I/O, changing to non buffered\n")); pEpClassFile->enmEpBackendDefault = PDMACFILEEPBACKEND_NON_BUFFERED; } #endif } else { /* No configuration supplied, set defaults */ pEpClassFile->enmEpBackendDefault = PDMACFILEEPBACKEND_NON_BUFFERED; pEpClassFile->enmMgrTypeOverride = PDMACEPFILEMGRTYPE_ASYNC; } } /* Init critical section. */ rc = RTCritSectInit(&pEpClassFile->CritSect); #ifdef VBOX_WITH_DEBUGGER /* Install the error injection handler. */ if (RT_SUCCESS(rc)) { rc = DBGCRegisterCommands(&g_aCmds[0], RT_ELEMENTS(g_aCmds)); AssertRC(rc); } #ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY rc = TMR3TimerCreateInternal(pEpClassFile->Core.pVM, TMCLOCK_REAL, pdmacR3TimerCallback, pEpClassFile, "AC Delay", &pEpClassFile->pTimer); AssertRC(rc); pEpClassFile->cMilliesNext = UINT64_MAX; #endif #endif return rc; }