/** * atexit callback. * * This makes sure any loggers are flushed and will later also work the * termination callback chain. */ static void rtR3ExitCallback(void) { ASMAtomicWriteBool(&g_frtAtExitCalled, true); if (g_cUsers > 0) { PRTLOGGER pLogger = RTLogGetDefaultInstance(); if (pLogger) RTLogFlush(pLogger); pLogger = RTLogRelGetDefaultInstance(); if (pLogger) RTLogFlush(pLogger); } }
/** * Creates the default release logger outputting to the specified file. * * @return IPRT status code. * @param pszLogFile Filename for log output. Optional. */ static int VBoxServiceLogCreate(const char *pszLogFile) { /* Create release logger (stdout + file). */ static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; RTUINT fFlags = RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG; #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) fFlags |= RTLOGFLAGS_USECRLF; #endif char szError[RTPATH_MAX + 128] = ""; int rc = RTLogCreateEx(&g_pLoggerRelease, fFlags, "all", "VBOXSERVICE_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_STDOUT, VBoxServiceLogHeaderFooter, g_cHistory, g_uHistoryFileSize, g_uHistoryFileTime, szError, sizeof(szError), pszLogFile); if (RT_SUCCESS(rc)) { /* register this logger as the release logger */ RTLogRelSetDefaultInstance(g_pLoggerRelease); /* Explicitly flush the log in case of VBOXSERVICE_RELEASE_LOG=buffered. */ RTLogFlush(g_pLoggerRelease); } return rc; }
int VBoxSVCLogRelCreate(const char *pszLogFile, uint32_t cHistory, uint32_t uHistoryFileTime, uint64_t uHistoryFileSize) { /* create release logger */ PRTLOGGER pLoggerReleaseFile; static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; RTUINT fFlags = RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG; #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) fFlags |= RTLOGFLAGS_USECRLF; #endif char szError[RTPATH_MAX + 128] = ""; int vrc = RTLogCreateEx(&pLoggerReleaseFile, fFlags, "all", "VBOXSVC_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, 0 /* fDestFlags */, vboxsvcHeaderFooter, cHistory, uHistoryFileSize, uHistoryFileTime, szError, sizeof(szError), pszLogFile); if (RT_SUCCESS(vrc)) { /* register this logger as the release logger */ RTLogRelSetDefaultInstance(pLoggerReleaseFile); /* Explicitly flush the log in case of VBOXWEBSRV_RELEASE_LOG=buffered. */ RTLogFlush(pLoggerReleaseFile); } else { /* print a message, but do not fail */ RTMsgError("failed to open release log (%s, %Rrc)", szError, vrc); } return vrc; }
int VBoxLogRelCreate(const char *pcszEntity, const char *pcszLogFile, uint32_t fFlags, const char *pcszGroupSettings, const char *pcszEnvVarBase, uint32_t fDestFlags, uint32_t cMaxEntriesPerGroup, uint32_t cHistory, uint32_t uHistoryFileTime, uint64_t uHistoryFileSize, char *pszError, size_t cbError) { Assert(cbError >= RTPATH_MAX + 128); /* create release logger */ PRTLOGGER pReleaseLogger; static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) fFlags |= RTLOGFLAGS_USECRLF; #endif g_pszLogEntity = pcszEntity; int vrc = RTLogCreateEx(&pReleaseLogger, fFlags, "all all.restrict default.unrestricted", pcszEnvVarBase, RT_ELEMENTS(s_apszGroups), s_apszGroups, fDestFlags, vboxHeaderFooter, cHistory, uHistoryFileSize, uHistoryFileTime, pszError, cbError, pcszLogFile); if (RT_SUCCESS(vrc)) { /* make sure that we don't flood logfiles */ RTLogSetGroupLimit(pReleaseLogger, cMaxEntriesPerGroup); /* explicitly flush the log, to have some info when buffering */ RTLogFlush(pReleaseLogger); /* register this logger as the release logger */ RTLogRelSetDefaultInstance(pReleaseLogger); } return vrc; }
/** * Creates the default release logger outputting to the specified file. * * Pass NULL to disabled logging. * * @return IPRT status code. * @param pszLogFile Filename for log output. NULL disables logging * (r=bird: No, it doesn't!). */ int VGSvcLogCreate(const char *pszLogFile) { /* Create release logger (stdout + file). */ static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; RTUINT fFlags = RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG; #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) fFlags |= RTLOGFLAGS_USECRLF; #endif int rc = RTLogCreateEx(&g_pLoggerRelease, fFlags, "all", #ifdef DEBUG "VBOXSERVICE_LOG", #else "VBOXSERVICE_RELEASE_LOG", #endif RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_STDOUT | RTLOGDEST_USER, vgsvcLogHeaderFooter, g_cHistory, g_uHistoryFileSize, g_uHistoryFileTime, NULL /*pErrInfo*/, "%s", pszLogFile ? pszLogFile : ""); if (RT_SUCCESS(rc)) { /* register this logger as the release logger */ RTLogRelSetDefaultInstance(g_pLoggerRelease); /* Explicitly flush the log in case of VBOXSERVICE_RELEASE_LOG=buffered. */ RTLogFlush(g_pLoggerRelease); } return rc; }
/** * Create default logger in order to print output to the specified file. * * @return IPRT status code. */ static int vbclInitLogger(char *szLogFileName) { int rc; uint32_t fFlags = RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG; static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; uint32_t fDestFlags = RTLOGDEST_STDOUT; rc = RTLogCreateEx(&g_pLogger, fFlags, /* Logger instance flags, a combination of the RTLOGFLAGS_* values */ "all", /* The initial group settings */ "VBOXCLIENT_RELEASE_LOG", /* Base name for the environment variables for this instance */ RT_ELEMENTS(s_apszGroups), /* Number of groups in the array */ s_apszGroups, /* Pointer to array of groups. This must stick around for the life of the logger instance */ fDestFlags, /* The destination flags */ NULL, /* Callback function for starting logging and for ending or starting a new file for log history rotation */ szLogFileName ? 10 : 0, /* Number of old log files to keep when performing log history rotation */ szLogFileName ? 100 * _1M : 0, /* Maximum size of log file when performing history rotation */ szLogFileName ? RT_SEC_1DAY : 0, /* Maximum time interval per log file when performing history rotation */ 0, /* A buffer which is filled with an error message if something fails */ 0, /* The size of the error message buffer */ szLogFileName /* Log filename format string */ ); AssertReturn(RT_SUCCESS(rc), rc); /* Register this logger as the release logger */ RTLogRelSetDefaultInstance(g_pLogger); /* Explicitly flush the log in case of VBOXCLIENT_RELEASE_LOG=buffered. */ RTLogFlush(g_pLogger); return rc; }
int main() { RTR3Init(); printf("tstLog: Requires manual inspection of the log output!\n"); RTLogPrintf("%%Rrc %d: %Rrc\n", VERR_INVALID_PARAMETER, VERR_INVALID_PARAMETER); RTLogPrintf("%%Rrs %d: %Rrs\n", VERR_INVALID_PARAMETER, VERR_INVALID_PARAMETER); RTLogPrintf("%%Rrf %d: %Rrf\n", VERR_INVALID_PARAMETER, VERR_INVALID_PARAMETER); RTLogPrintf("%%Rra %d: %Rra\n", VERR_INVALID_PARAMETER, VERR_INVALID_PARAMETER); static uint8_t au8Hex[256]; for (unsigned iHex = 0; iHex < sizeof(au8Hex); iHex++) au8Hex[iHex] = (uint8_t)iHex; RTLogPrintf("%%Rhxs : %Rhxs\n", &au8Hex[0]); RTLogPrintf("%%.32Rhxs: %.32Rhxs\n", &au8Hex[0]); RTLogPrintf("%%Rhxd :\n%Rhxd\n", &au8Hex[0]); RTLogPrintf("%%.64Rhxd:\n%.64Rhxd\n", &au8Hex[0]); RTLogPrintf("%%.*Rhxd:\n%.*Rhxd\n", 64, &au8Hex[0]); RTLogPrintf("%%32.256Rhxd : \n%32.256Rhxd\n", &au8Hex[0]); RTLogPrintf("%%32.*Rhxd : \n%32.*Rhxd\n", 256, &au8Hex[0]); RTLogPrintf("%%7.32Rhxd : \n%7.32Rhxd\n", &au8Hex[0]); RTLogPrintf("%%7.*Rhxd : \n%7.*Rhxd\n", 32, &au8Hex[0]); RTLogPrintf("%%*.*Rhxd : \n%*.*Rhxd\n", 7, 32, &au8Hex[0]); RTLogPrintf("%%RGp: %RGp\n", (RTGCPHYS)0x87654321); RTLogPrintf("%%RGv: %RGv\n", (RTGCPTR)0x87654321); RTLogPrintf("%%RHp: %RHp\n", (RTGCPHYS)0x87654321); RTLogPrintf("%%RHv: %RHv\n", (RTGCPTR)0x87654321); RTLogPrintf("%%RI8 : %RI8\n", (uint8_t)808); RTLogPrintf("%%RI16: %RI16\n", (uint16_t)16016); RTLogPrintf("%%RI32: %RI32\n", _1G); RTLogPrintf("%%RI64: %RI64\n", _1E); RTLogPrintf("%%RU8 : %RU8\n", (uint8_t)808); RTLogPrintf("%%RU16: %RU16\n", (uint16_t)16016); RTLogPrintf("%%RU32: %RU32\n", _2G32); RTLogPrintf("%%RU64: %RU64\n", _2E); RTLogPrintf("%%RX8 : %RX8 %#RX8\n", (uint8_t)808, (uint8_t)808); RTLogPrintf("%%RX16: %RX16 %#RX16\n", (uint16_t)16016, (uint16_t)16016); RTLogPrintf("%%RX32: %RX32 %#RX32\n", _2G32, _2G32); RTLogPrintf("%%RX64: %RX64 %#RX64\n", _2E, _2E); RTLogFlush(NULL); return 0; }
/** * Executes hardware accelerated raw code. (Intel VT-x & AMD-V) * * This function contains the raw-mode version of the inner * execution loop (the outer loop being in EMR3ExecuteVM()). * * @returns VBox status code. The most important ones are: VINF_EM_RESCHEDULE, VINF_EM_RESCHEDULE_RAW, * VINF_EM_RESCHEDULE_REM, VINF_EM_SUSPEND, VINF_EM_RESET and VINF_EM_TERMINATE. * * @param pVM The cross context VM structure. * @param pVCpu The cross context virtual CPU structure. * @param pfFFDone Where to store an indicator telling whether or not * FFs were done before returning. */ int emR3HmExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone) { int rc = VERR_IPE_UNINITIALIZED_STATUS; PCPUMCTX pCtx = pVCpu->em.s.pCtx; LogFlow(("emR3HmExecute%d: (cs:eip=%04x:%RGv)\n", pVCpu->idCpu, pCtx->cs.Sel, (RTGCPTR)pCtx->rip)); *pfFFDone = false; STAM_COUNTER_INC(&pVCpu->em.s.StatHmExecuteEntry); #ifdef EM_NOTIFY_HM HMR3NotifyScheduled(pVCpu); #endif /* * Spin till we get a forced action which returns anything but VINF_SUCCESS. */ for (;;) { STAM_PROFILE_ADV_START(&pVCpu->em.s.StatHmEntry, a); /* Check if a forced reschedule is pending. */ if (HMR3IsRescheduleRequired(pVM, pCtx)) { rc = VINF_EM_RESCHEDULE; break; } /* * Process high priority pre-execution raw-mode FFs. */ #ifdef VBOX_WITH_RAW_MODE Assert(!VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT)); #endif if ( VM_FF_IS_PENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK) || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK)) { rc = emR3HmForcedActions(pVM, pVCpu, pCtx); if (rc != VINF_SUCCESS) break; } #ifdef LOG_ENABLED /* * Log important stuff before entering GC. */ if (TRPMHasTrap(pVCpu)) Log(("CPU%d: Pending hardware interrupt=0x%x cs:rip=%04X:%RGv\n", pVCpu->idCpu, TRPMGetTrapNo(pVCpu), pCtx->cs.Sel, (RTGCPTR)pCtx->rip)); uint32_t cpl = CPUMGetGuestCPL(pVCpu); if (pVM->cCpus == 1) { if (pCtx->eflags.Bits.u1VM) Log(("HWV86: %08X IF=%d\n", pCtx->eip, pCtx->eflags.Bits.u1IF)); else if (CPUMIsGuestIn64BitCodeEx(pCtx)) Log(("HWR%d: %04X:%RGv ESP=%RGv IF=%d IOPL=%d CR0=%x CR4=%x EFER=%x\n", cpl, pCtx->cs.Sel, (RTGCPTR)pCtx->rip, pCtx->rsp, pCtx->eflags.Bits.u1IF, pCtx->eflags.Bits.u2IOPL, (uint32_t)pCtx->cr0, (uint32_t)pCtx->cr4, (uint32_t)pCtx->msrEFER)); else Log(("HWR%d: %04X:%08X ESP=%08X IF=%d IOPL=%d CR0=%x CR4=%x EFER=%x\n", cpl, pCtx->cs.Sel, pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, pCtx->eflags.Bits.u2IOPL, (uint32_t)pCtx->cr0, (uint32_t)pCtx->cr4, (uint32_t)pCtx->msrEFER)); } else { if (pCtx->eflags.Bits.u1VM) Log(("HWV86-CPU%d: %08X IF=%d\n", pVCpu->idCpu, pCtx->eip, pCtx->eflags.Bits.u1IF)); else if (CPUMIsGuestIn64BitCodeEx(pCtx)) Log(("HWR%d-CPU%d: %04X:%RGv ESP=%RGv IF=%d IOPL=%d CR0=%x CR4=%x EFER=%x\n", cpl, pVCpu->idCpu, pCtx->cs.Sel, (RTGCPTR)pCtx->rip, pCtx->rsp, pCtx->eflags.Bits.u1IF, pCtx->eflags.Bits.u2IOPL, (uint32_t)pCtx->cr0, (uint32_t)pCtx->cr4, (uint32_t)pCtx->msrEFER)); else Log(("HWR%d-CPU%d: %04X:%08X ESP=%08X IF=%d IOPL=%d CR0=%x CR4=%x EFER=%x\n", cpl, pVCpu->idCpu, pCtx->cs.Sel, pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, pCtx->eflags.Bits.u2IOPL, (uint32_t)pCtx->cr0, (uint32_t)pCtx->cr4, (uint32_t)pCtx->msrEFER)); } #endif /* LOG_ENABLED */ /* * Execute the code. */ STAM_PROFILE_ADV_STOP(&pVCpu->em.s.StatHmEntry, a); if (RT_LIKELY(emR3IsExecutionAllowed(pVM, pVCpu))) { STAM_PROFILE_START(&pVCpu->em.s.StatHmExec, x); rc = VMMR3HmRunGC(pVM, pVCpu); STAM_PROFILE_STOP(&pVCpu->em.s.StatHmExec, x); } else { /* Give up this time slice; virtual time continues */ STAM_REL_PROFILE_ADV_START(&pVCpu->em.s.StatCapped, u); RTThreadSleep(5); STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatCapped, u); rc = VINF_SUCCESS; } /* * Deal with high priority post execution FFs before doing anything else. */ VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK); if ( VM_FF_IS_PENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK) || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_POST_MASK)) rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc); /* * Process the returned status code. */ if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST) break; rc = emR3HmHandleRC(pVM, pVCpu, pCtx, rc); if (rc != VINF_SUCCESS) break; /* * Check and execute forced actions. */ #ifdef VBOX_HIGH_RES_TIMERS_HACK TMTimerPollVoid(pVM, pVCpu); #endif if ( VM_FF_IS_PENDING(pVM, VM_FF_ALL_MASK) || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_ALL_MASK)) { rc = emR3ForcedActions(pVM, pVCpu, rc); VBOXVMM_EM_FF_ALL_RET(pVCpu, rc); if ( rc != VINF_SUCCESS && rc != VINF_EM_RESCHEDULE_HM) { *pfFFDone = true; break; } } } /* * Return to outer loop. */ #if defined(LOG_ENABLED) && defined(DEBUG) RTLogFlush(NULL); #endif return rc; }
/** * Entry point. */ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp) { /* * Init runtime. */ RTR3InitExe(argc, &argv, 0); /* * Create empty VM structure and call MMR3Init(). */ PVM pVM; RTR0PTR pvR0; SUPPAGE aPages[RT_ALIGN_Z(sizeof(*pVM) + NUM_CPUS * sizeof(VMCPU), PAGE_SIZE) >> PAGE_SHIFT]; int rc = SUPR3Init(NULL); if (RT_SUCCESS(rc)) rc = SUPR3LowAlloc(RT_ELEMENTS(aPages), (void **)&pVM, &pvR0, &aPages[0]); if (RT_FAILURE(rc)) { RTPrintf("Fatal error: SUP Failure! rc=%Rrc\n", rc); return 1; } memset(pVM, 0, sizeof(*pVM)); /* wtf? */ pVM->paVMPagesR3 = aPages; pVM->pVMR0 = pvR0; static UVM s_UVM; PUVM pUVM = &s_UVM; pUVM->pVM = pVM; pVM->pUVM = pUVM; pVM->cCpus = NUM_CPUS; pVM->cbSelf = RT_UOFFSETOF(VM, aCpus[pVM->cCpus]); rc = STAMR3InitUVM(pUVM); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: STAMR3Init failed. rc=%Rrc\n", rc); return 1; } rc = MMR3InitUVM(pUVM); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: STAMR3Init failed. rc=%Rrc\n", rc); return 1; } rc = CFGMR3Init(pVM, NULL, NULL); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3Init failed. rc=%Rrc\n", rc); return 1; } rc = MMR3Init(pVM); if (RT_FAILURE(rc)) { RTPrintf("Fatal error: MMR3Init failed! rc=%Rrc\n", rc); return 1; } /* * Try allocate. */ static struct { size_t cb; unsigned uAlignment; void *pvAlloc; unsigned iFreeOrder; } aOps[] = { { 16, 0, NULL, 0 }, { 16, 4, NULL, 1 }, { 16, 8, NULL, 2 }, { 16, 16, NULL, 5 }, { 16, 32, NULL, 4 }, { 32, 0, NULL, 3 }, { 31, 0, NULL, 6 }, { 1024, 0, NULL, 8 }, { 1024, 32, NULL, 10 }, { 1024, 32, NULL, 12 }, { PAGE_SIZE, PAGE_SIZE, NULL, 13 }, { 1024, 32, NULL, 9 }, { PAGE_SIZE, 32, NULL, 11 }, { PAGE_SIZE, PAGE_SIZE, NULL, 14 }, { 16, 0, NULL, 15 }, { 9, 0, NULL, 7 }, { 16, 0, NULL, 7 }, { 36, 0, NULL, 7 }, { 16, 0, NULL, 7 }, { 12344, 0, NULL, 7 }, { 50, 0, NULL, 7 }, { 16, 0, NULL, 7 }, }; unsigned i; #ifdef DEBUG MMHyperHeapDump(pVM); #endif size_t cbBefore = MMHyperHeapGetFreeSize(pVM); static char szFill[] = "01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; /* allocate */ for (i = 0; i < RT_ELEMENTS(aOps); i++) { rc = MMHyperAlloc(pVM, aOps[i].cb, aOps[i].uAlignment, MM_TAG_VM, &aOps[i].pvAlloc); if (RT_FAILURE(rc)) { RTPrintf("Failure: MMHyperAlloc(, %#x, %#x,) -> %d i=%d\n", aOps[i].cb, aOps[i].uAlignment, rc, i); return 1; } memset(aOps[i].pvAlloc, szFill[i], aOps[i].cb); if (RT_ALIGN_P(aOps[i].pvAlloc, (aOps[i].uAlignment ? aOps[i].uAlignment : 8)) != aOps[i].pvAlloc) { RTPrintf("Failure: MMHyperAlloc(, %#x, %#x,) -> %p, invalid alignment!\n", aOps[i].cb, aOps[i].uAlignment, aOps[i].pvAlloc); return 1; } } /* free and allocate the same node again. */ for (i = 0; i < RT_ELEMENTS(aOps); i++) { if ( !aOps[i].pvAlloc || aOps[i].uAlignment == PAGE_SIZE) continue; //size_t cbBeforeSub = MMHyperHeapGetFreeSize(pVM); rc = MMHyperFree(pVM, aOps[i].pvAlloc); if (RT_FAILURE(rc)) { RTPrintf("Failure: MMHyperFree(, %p,) -> %d i=%d\n", aOps[i].pvAlloc, rc, i); return 1; } //RTPrintf("debug: i=%d cbBeforeSub=%d now=%d\n", i, cbBeforeSub, MMHyperHeapGetFreeSize(pVM)); void *pv; rc = MMHyperAlloc(pVM, aOps[i].cb, aOps[i].uAlignment, MM_TAG_VM_REQ, &pv); if (RT_FAILURE(rc)) { RTPrintf("Failure: MMHyperAlloc(, %#x, %#x,) -> %d i=%d\n", aOps[i].cb, aOps[i].uAlignment, rc, i); return 1; } if (pv != aOps[i].pvAlloc) { RTPrintf("Failure: Free+Alloc returned different address. new=%p old=%p i=%d (doesn't work with delayed free)\n", pv, aOps[i].pvAlloc, i); //return 1; } aOps[i].pvAlloc = pv; #if 0 /* won't work :/ */ size_t cbAfterSub = MMHyperHeapGetFreeSize(pVM); if (cbBeforeSub != cbAfterSub) { RTPrintf("Failure: cbBeforeSub=%d cbAfterSub=%d. i=%d\n", cbBeforeSub, cbAfterSub, i); return 1; } #endif } /* free it in a specific order. */ int cFreed = 0; for (i = 0; i < RT_ELEMENTS(aOps); i++) { unsigned j; for (j = 0; j < RT_ELEMENTS(aOps); j++) { if ( aOps[j].iFreeOrder != i || !aOps[j].pvAlloc) continue; RTPrintf("j=%d i=%d free=%d cb=%d pv=%p\n", j, i, MMHyperHeapGetFreeSize(pVM), aOps[j].cb, aOps[j].pvAlloc); if (aOps[j].uAlignment == PAGE_SIZE) cbBefore -= aOps[j].cb; else { rc = MMHyperFree(pVM, aOps[j].pvAlloc); if (RT_FAILURE(rc)) { RTPrintf("Failure: MMHyperFree(, %p,) -> %d j=%d i=%d\n", aOps[j].pvAlloc, rc, i, j); return 1; } } aOps[j].pvAlloc = NULL; cFreed++; } } Assert(cFreed == RT_ELEMENTS(aOps)); RTPrintf("i=done free=%d\n", MMHyperHeapGetFreeSize(pVM)); /* check that we're back at the right amount of free memory. */ size_t cbAfter = MMHyperHeapGetFreeSize(pVM); if (cbBefore != cbAfter) { RTPrintf("Warning: Either we've split out an alignment chunk at the start, or we've got\n" " an alloc/free accounting bug: cbBefore=%d cbAfter=%d\n", cbBefore, cbAfter); #ifdef DEBUG MMHyperHeapDump(pVM); #endif } RTPrintf("tstMMHyperHeap: Success\n"); #ifdef LOG_ENABLED RTLogFlush(NULL); #endif return 0; }
/** * Worker for RTAssertMsg2V and RTAssertMsg2AddV * * @param fInitial True if it's RTAssertMsg2V, otherwise false. * @param pszFormat The message format string. * @param va The format arguments. */ static void rtAssertMsg2Worker(bool fInitial, const char *pszFormat, va_list va) { va_list vaCopy; size_t cch; /* * The global first. */ if (fInitial) { va_copy(vaCopy, va); cch = RTStrPrintfV(g_szRTAssertMsg2, sizeof(g_szRTAssertMsg2), pszFormat, vaCopy); ASMAtomicWriteU32(&g_cchRTAssertMsg2, (uint32_t)cch); va_end(vaCopy); } else { cch = ASMAtomicReadU32(&g_cchRTAssertMsg2); if (cch < sizeof(g_szRTAssertMsg2) - 4) { va_copy(vaCopy, va); cch += RTStrPrintfV(&g_szRTAssertMsg2[cch], sizeof(g_szRTAssertMsg2) - cch, pszFormat, vaCopy); ASMAtomicWriteU32(&g_cchRTAssertMsg2, (uint32_t)cch); va_end(vaCopy); } } /* * If not quiet, make some noise. */ if (!RTAssertAreQuiet()) { RTERRVARS SavedErrVars; RTErrVarsSave(&SavedErrVars); #ifdef IN_RING0 # ifdef IN_GUEST_R0 va_copy(vaCopy, va); RTLogBackdoorPrintfV(pszFormat, vaCopy); va_end(vaCopy); # endif /** @todo fully integrate this with the logger... play safe a bit for now. */ rtR0AssertNativeMsg2V(fInitial, pszFormat, va); #else /* !IN_RING0 */ # if !defined(IN_RING3) && !defined(LOG_NO_COM) # if 0 /* Enable this iff you have a COM port and really want this debug info. */ va_copy(vaCopy, va); RTLogComPrintfV(pszFormat, vaCopy); va_end(vaCopy); # endif # endif PRTLOGGER pLog = RTLogRelGetDefaultInstance(); if (pLog) { va_copy(vaCopy, va); RTLogRelPrintfV(pszFormat, vaCopy); va_end(vaCopy); # ifndef IN_RC /* flushing is done automatically in RC */ RTLogFlush(pLog); # endif } pLog = RTLogDefaultInstance(); if (pLog) { va_copy(vaCopy, va); RTLogPrintfV(pszFormat, vaCopy); va_end(vaCopy); # ifndef IN_RC /* flushing is done automatically in RC */ RTLogFlush(pLog); #endif } # ifdef IN_RING3 /* print to stderr, helps user and gdb debugging. */ char szMsg[sizeof(g_szRTAssertMsg2)]; va_copy(vaCopy, va); RTStrPrintfV(szMsg, sizeof(szMsg), pszFormat, vaCopy); va_end(vaCopy); fprintf(stderr, "%s", szMsg); fflush(stderr); # endif #endif /* !IN_RING0 */ RTErrVarsRestore(&SavedErrVars); } }
RTDECL(void) RTAssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction) { /* * Fill in the globals. */ ASMAtomicUoWritePtr(&g_pszRTAssertExpr, pszExpr); ASMAtomicUoWritePtr(&g_pszRTAssertFile, pszFile); ASMAtomicUoWritePtr(&g_pszRTAssertFunction, pszFunction); ASMAtomicUoWriteU32(&g_u32RTAssertLine, uLine); RTStrPrintf(g_szRTAssertMsg1, sizeof(g_szRTAssertMsg1), "\n!!Assertion Failed!!\n" "Expression: %s\n" "Location : %s(%d) %s\n", pszExpr, pszFile, uLine, pszFunction); /* * If not quiet, make noise. */ if (!RTAssertAreQuiet()) { RTERRVARS SavedErrVars; RTErrVarsSave(&SavedErrVars); #ifdef IN_RING0 # ifdef IN_GUEST_R0 RTLogBackdoorPrintf("\n!!Assertion Failed!!\n" "Expression: %s\n" "Location : %s(%d) %s\n", pszExpr, pszFile, uLine, pszFunction); # endif /** @todo fully integrate this with the logger... play safe a bit for now. */ rtR0AssertNativeMsg1(pszExpr, uLine, pszFile, pszFunction); #else /* !IN_RING0 */ # if !defined(IN_RING3) && !defined(LOG_NO_COM) # if 0 /* Enable this iff you have a COM port and really want this debug info. */ RTLogComPrintf("\n!!Assertion Failed!!\n" "Expression: %s\n" "Location : %s(%d) %s\n", pszExpr, pszFile, uLine, pszFunction); # endif # endif PRTLOGGER pLog = RTLogRelGetDefaultInstance(); if (pLog) { RTLogRelPrintf("\n!!Assertion Failed!!\n" "Expression: %s\n" "Location : %s(%d) %s\n", pszExpr, pszFile, uLine, pszFunction); # ifndef IN_RC /* flushing is done automatically in RC */ RTLogFlush(pLog); # endif } # ifndef LOG_ENABLED if (!pLog) # endif { pLog = RTLogDefaultInstance(); if (pLog) { RTLogPrintf("\n!!Assertion Failed!!\n" "Expression: %s\n" "Location : %s(%d) %s\n", pszExpr, pszFile, uLine, pszFunction); # ifndef IN_RC /* flushing is done automatically in RC */ RTLogFlush(pLog); # endif } } # ifdef IN_RING3 /* print to stderr, helps user and gdb debugging. */ fprintf(stderr, "\n!!Assertion Failed!!\n" "Expression: %s\n" "Location : %s(%d) %s\n", VALID_PTR(pszExpr) ? pszExpr : "<none>", VALID_PTR(pszFile) ? pszFile : "<none>", uLine, VALID_PTR(pszFunction) ? pszFunction : ""); fflush(stderr); # endif #endif /* !IN_RING0 */ RTErrVarsRestore(&SavedErrVars); } }