HRESULT SystemProperties::i_setLoggingLevel(const com::Utf8Str &aLoggingLevel) { Utf8Str useLoggingLevel(aLoggingLevel); if (useLoggingLevel.isEmpty()) useLoggingLevel = VBOXSVC_LOG_DEFAULT; int rc = RTLogGroupSettings(RTLogRelGetDefaultInstance(), useLoggingLevel.c_str()); // If failed and not the default logging level - try to use the default logging level. if (RT_FAILURE(rc)) { // If failed write message to the release log. LogRel(("Cannot set passed logging level=%s Error=%Rrc \n", useLoggingLevel.c_str(), rc)); // If attempted logging level not the default one then try the default one. if (!useLoggingLevel.equals(VBOXSVC_LOG_DEFAULT)) { rc = RTLogGroupSettings(RTLogRelGetDefaultInstance(), VBOXSVC_LOG_DEFAULT); // If failed report this to the release log. if (RT_FAILURE(rc)) LogRel(("Cannot set default logging level Error=%Rrc \n", rc)); } // On any failure - set default level as the one to be stored. useLoggingLevel = VBOXSVC_LOG_DEFAULT; } // Set to passed value or if default used/attempted (even if error condition) use empty string. m->strLoggingLevel = (useLoggingLevel.equals(VBOXSVC_LOG_DEFAULT) ? "" : useLoggingLevel); return RT_SUCCESS(rc) ? S_OK : E_FAIL; }
/** log and dbg_log parameter setter. */ static int vboxguestLinuxParamLogGrpSet(const char *pszValue, struct kernel_param *pParam) { if (g_fLoggerCreated) { PRTLOGGER pLogger = pParam->name[0] == 'd' ? RTLogDefaultInstance() : RTLogRelGetDefaultInstance(); if (pLogger) RTLogGroupSettings(pLogger, pszValue); } else if (pParam->name[0] != 'd') strlcpy(&g_szLogGrp[0], pszValue, sizeof(g_szLogGrp)); return 0; }
/** * EMT worker for DBGFR3LogModifyGroups. * * @returns VBox status code. * @param pUVM The user mode VM handle. * @param pszGroupSettings The group settings string. (VBOX_LOG) */ static DECLCALLBACK(int) dbgfR3LogModifyGroups(PUVM pUVM, const char *pszGroupSettings) { PRTLOGGER pLogger = dbgfR3LogResolvedLogger(&pszGroupSettings); if (!pLogger) return VINF_SUCCESS; int rc = RTLogGroupSettings(pLogger, pszGroupSettings); if (RT_SUCCESS(rc) && pUVM->pVM) { VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, VERR_INVALID_VM_HANDLE); rc = VMMR3UpdateLoggers(pUVM->pVM); } return rc; }
/** * Initialize module. * * @returns appropriate status code. */ static int __init vboxguestLinuxModInit(void) { static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; PRTLOGGER pRelLogger; int rc; /* * Initialize IPRT first. */ rc = RTR0Init(0); if (RT_FAILURE(rc)) { printk(KERN_ERR DEVICE_NAME ": RTR0Init failed, rc=%d.\n", rc); return -EINVAL; } /* * Create the release log. * (We do that here instead of common code because we want to log * early failures using the LogRel macro.) */ rc = RTLogCreate(&pRelLogger, 0 /* fFlags */, "all", "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_STDOUT | RTLOGDEST_DEBUGGER | RTLOGDEST_USER, NULL); if (RT_SUCCESS(rc)) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) RTLogGroupSettings(pRelLogger, g_szLogGrp); RTLogFlags(pRelLogger, g_szLogFlags); RTLogDestinations(pRelLogger, g_szLogDst); #endif RTLogRelSetDefaultInstance(pRelLogger); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) g_fLoggerCreated = true; #endif /* * Locate and initialize the PCI device. */ rc = pci_register_driver(&g_PciDriver); if (rc >= 0 && g_pPciDev) { /* * Register the interrupt service routine for it. */ rc = vboxguestLinuxInitISR(); if (rc >= 0) { /* * Call the common device extension initializer. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) && defined(RT_ARCH_X86) VBOXOSTYPE enmOSType = VBOXOSTYPE_Linux26; #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) && defined(RT_ARCH_AMD64) VBOXOSTYPE enmOSType = VBOXOSTYPE_Linux26_x64; #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) && defined(RT_ARCH_X86) VBOXOSTYPE enmOSType = VBOXOSTYPE_Linux24; #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) && defined(RT_ARCH_AMD64) VBOXOSTYPE enmOSType = VBOXOSTYPE_Linux24_x64; #else # warning "huh? which arch + version is this?" VBOXOSTYPE enmOsType = VBOXOSTYPE_Linux; #endif rc = VbgdCommonInitDevExt(&g_DevExt, g_IOPortBase, g_pvMMIOBase, g_cbMMIO, enmOSType, VMMDEV_EVENT_MOUSE_POSITION_CHANGED); if (RT_SUCCESS(rc)) { /* * Create the kernel session for this driver. */ rc = VbgdCommonCreateKernelSession(&g_DevExt, &g_pKernelSession); if (RT_SUCCESS(rc)) { /* * Create the kernel input device. */ #ifdef VBOXGUEST_WITH_INPUT_DRIVER rc = vboxguestLinuxCreateInputDevice(); if (rc >= 0) { #endif /* * Finally, create the device nodes. */ rc = vboxguestLinuxInitDeviceNodes(); if (rc >= 0) { /* some useful information for the user but don't show this on the console */ LogRel((DEVICE_NAME ": misc device minor %d, IRQ %d, I/O port %RTiop, MMIO at %RHp (size 0x%x)\n", g_MiscDevice.minor, g_pPciDev->irq, g_IOPortBase, g_MMIOPhysAddr, g_cbMMIO)); printk(KERN_DEBUG DEVICE_NAME ": Successfully loaded version " VBOX_VERSION_STRING " (interface " RT_XSTR(VMMDEV_VERSION) ")\n"); return rc; } /* bail out */ #ifdef VBOXGUEST_WITH_INPUT_DRIVER vboxguestLinuxTermInputDevice(); } else { LogRel((DEVICE_NAME ": vboxguestCreateInputDevice failed with rc=%Rrc\n", rc)); rc = RTErrConvertFromErrno(rc); } #endif VbgdCommonCloseSession(&g_DevExt, g_pKernelSession); } VbgdCommonDeleteDevExt(&g_DevExt); } else { LogRel((DEVICE_NAME ": VbgdCommonInitDevExt failed with rc=%Rrc\n", rc)); rc = RTErrConvertFromErrno(rc); } vboxguestLinuxTermISR(); } } else { LogRel((DEVICE_NAME ": PCI device not found, probably running on physical hardware.\n")); rc = -ENODEV; } pci_unregister_driver(&g_PciDriver); RTLogDestroy(RTLogRelSetDefaultInstance(NULL)); RTLogDestroy(RTLogSetDefaultInstance(NULL)); RTR0Term(); return rc; }
/** * Creates the default logger instance for a VBox process. * * @returns Pointer to the logger instance. */ RTDECL(PRTLOGGER) RTLogDefaultInit(void) { /* * Initialize the default logger instance. * Take care to do this once and not recursively. */ static volatile uint32_t fInitializing = 0; PRTLOGGER pLogger; int rc; if (g_pLogger || !ASMAtomicCmpXchgU32(&fInitializing, 1, 0)) return g_pLogger; #ifdef IN_RING3 /* * Assert the group definitions. */ #define ASSERT_LOG_GROUP(grp) ASSERT_LOG_GROUP2(LOG_GROUP_##grp, #grp) #define ASSERT_LOG_GROUP2(def, str) \ do { if (strcmp(g_apszGroups[def], str)) {printf("%s='%s' expects '%s'\n", #def, g_apszGroups[def], str); RTAssertDoPanic(); } } while (0) ASSERT_LOG_GROUP(DEFAULT); ASSERT_LOG_GROUP(AUDIO_MIXER); ASSERT_LOG_GROUP(AUDIO_MIXER_BUFFER); ASSERT_LOG_GROUP(CFGM); ASSERT_LOG_GROUP(CPUM); ASSERT_LOG_GROUP(CSAM); ASSERT_LOG_GROUP(DBGC); ASSERT_LOG_GROUP(DBGF); ASSERT_LOG_GROUP(DBGF_INFO); ASSERT_LOG_GROUP(DEV); ASSERT_LOG_GROUP(DEV_AC97); ASSERT_LOG_GROUP(DEV_ACPI); ASSERT_LOG_GROUP(DEV_APIC); ASSERT_LOG_GROUP(DEV_FDC); ASSERT_LOG_GROUP(DEV_HDA); ASSERT_LOG_GROUP(DEV_HDA_CODEC); ASSERT_LOG_GROUP(DEV_HPET); ASSERT_LOG_GROUP(DEV_IDE); ASSERT_LOG_GROUP(DEV_KBD); ASSERT_LOG_GROUP(DEV_LPC); ASSERT_LOG_GROUP(DEV_NE2000); ASSERT_LOG_GROUP(DEV_PC); ASSERT_LOG_GROUP(DEV_PC_ARCH); ASSERT_LOG_GROUP(DEV_PC_BIOS); ASSERT_LOG_GROUP(DEV_PCI); ASSERT_LOG_GROUP(DEV_PCNET); ASSERT_LOG_GROUP(DEV_PIC); ASSERT_LOG_GROUP(DEV_PIT); ASSERT_LOG_GROUP(DEV_RTC); ASSERT_LOG_GROUP(DEV_SB16); ASSERT_LOG_GROUP(DEV_SERIAL); ASSERT_LOG_GROUP(DEV_SMC); ASSERT_LOG_GROUP(DEV_VGA); ASSERT_LOG_GROUP(DEV_VMM); ASSERT_LOG_GROUP(DEV_VMM_STDERR); ASSERT_LOG_GROUP(DIS); ASSERT_LOG_GROUP(DRV); ASSERT_LOG_GROUP(DRV_ACPI); ASSERT_LOG_GROUP(DRV_AUDIO); ASSERT_LOG_GROUP(DRV_BLOCK); ASSERT_LOG_GROUP(DRV_FLOPPY); ASSERT_LOG_GROUP(DRV_HOST_AUDIO); ASSERT_LOG_GROUP(DRV_HOST_DVD); ASSERT_LOG_GROUP(DRV_HOST_FLOPPY); ASSERT_LOG_GROUP(DRV_ISO); ASSERT_LOG_GROUP(DRV_KBD_QUEUE); ASSERT_LOG_GROUP(DRV_MOUSE_QUEUE); ASSERT_LOG_GROUP(DRV_NAT); ASSERT_LOG_GROUP(DRV_RAW_IMAGE); ASSERT_LOG_GROUP(DRV_TUN); ASSERT_LOG_GROUP(DRV_USBPROXY); ASSERT_LOG_GROUP(DRV_VBOXHDD); ASSERT_LOG_GROUP(DRV_VRDE_AUDIO); ASSERT_LOG_GROUP(DRV_VSWITCH); ASSERT_LOG_GROUP(DRV_VUSB); ASSERT_LOG_GROUP(EM); ASSERT_LOG_GROUP(GUI); ASSERT_LOG_GROUP(HGCM); ASSERT_LOG_GROUP(HM); ASSERT_LOG_GROUP(IOM); ASSERT_LOG_GROUP(LWIP); ASSERT_LOG_GROUP(MAIN); ASSERT_LOG_GROUP(MM); ASSERT_LOG_GROUP(MM_HEAP); ASSERT_LOG_GROUP(MM_HYPER); ASSERT_LOG_GROUP(MM_HYPER_HEAP); ASSERT_LOG_GROUP(MM_PHYS); ASSERT_LOG_GROUP(MM_POOL); ASSERT_LOG_GROUP(NAT_SERVICE); ASSERT_LOG_GROUP(NET_SERVICE); ASSERT_LOG_GROUP(PATM); ASSERT_LOG_GROUP(PDM); ASSERT_LOG_GROUP(PDM_DEVICE); ASSERT_LOG_GROUP(PDM_DRIVER); ASSERT_LOG_GROUP(PDM_LDR); ASSERT_LOG_GROUP(PDM_QUEUE); ASSERT_LOG_GROUP(PGM); ASSERT_LOG_GROUP(PGM_POOL); ASSERT_LOG_GROUP(REM); ASSERT_LOG_GROUP(REM_DISAS); ASSERT_LOG_GROUP(REM_HANDLER); ASSERT_LOG_GROUP(REM_IOPORT); ASSERT_LOG_GROUP(REM_MMIO); ASSERT_LOG_GROUP(REM_PRINTF); ASSERT_LOG_GROUP(REM_RUN); ASSERT_LOG_GROUP(SELM); ASSERT_LOG_GROUP(SSM); ASSERT_LOG_GROUP(STAM); ASSERT_LOG_GROUP(SUP); ASSERT_LOG_GROUP(TM); ASSERT_LOG_GROUP(TRPM); ASSERT_LOG_GROUP(VM); ASSERT_LOG_GROUP(VMM); ASSERT_LOG_GROUP(VRDP); #undef ASSERT_LOG_GROUP #undef ASSERT_LOG_GROUP2 #endif /* IN_RING3 */ /* * Create the default logging instance. */ #ifdef IN_RING3 # ifndef IN_GUEST char szExecName[RTPATH_MAX]; if (!RTProcGetExecutablePath(szExecName, sizeof(szExecName))) strcpy(szExecName, "VBox"); RTTIMESPEC TimeSpec; RTTIME Time; RTTimeExplode(&Time, RTTimeNow(&TimeSpec)); rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_FILE, "./%04d-%02d-%02d-%02d-%02d-%02d.%03d-%s-%d.log", Time.i32Year, Time.u8Month, Time.u8MonthDay, Time.u8Hour, Time.u8Minute, Time.u8Second, Time.u32Nanosecond / 10000000, RTPathFilename(szExecName), RTProcSelf()); if (RT_SUCCESS(rc)) { /* * Write a log header. */ char szBuf[RTPATH_MAX]; RTTimeSpecToString(&TimeSpec, szBuf, sizeof(szBuf)); RTLogLoggerEx(pLogger, 0, ~0U, "Log created: %s\n", szBuf); RTLogLoggerEx(pLogger, 0, ~0U, "Executable: %s\n", szExecName); /* executable and arguments - tricky and all platform specific. */ # if defined(RT_OS_WINDOWS) RTLogLoggerEx(pLogger, 0, ~0U, "Commandline: %ls\n", GetCommandLineW()); # elif defined(RT_OS_SOLARIS) psinfo_t psi; char szArgFileBuf[80]; RTStrPrintf(szArgFileBuf, sizeof(szArgFileBuf), "/proc/%ld/psinfo", (long)getpid()); FILE* pFile = fopen(szArgFileBuf, "rb"); if (pFile) { if (fread(&psi, sizeof(psi), 1, pFile) == 1) { # if 0 /* 100% safe:*/ RTLogLoggerEx(pLogger, 0, ~0U, "Args: %s\n", psi.pr_psargs); # else /* probably safe: */ const char * const *argv = (const char * const *)psi.pr_argv; for (int iArg = 0; iArg < psi.pr_argc; iArg++) RTLogLoggerEx(pLogger, 0, ~0U, "Arg[%d]: %s\n", iArg, argv[iArg]); # endif } fclose(pFile); } # elif defined(RT_OS_LINUX) FILE *pFile = fopen("/proc/self/cmdline", "r"); if (pFile) { /* braindead */ unsigned iArg = 0; int ch; bool fNew = true; while (!feof(pFile) && (ch = fgetc(pFile)) != EOF) { if (fNew) { RTLogLoggerEx(pLogger, 0, ~0U, "Arg[%u]: ", iArg++); fNew = false; } if (ch) RTLogLoggerEx(pLogger, 0, ~0U, "%c", ch); else { RTLogLoggerEx(pLogger, 0, ~0U, "\n"); fNew = true; } } if (!fNew) RTLogLoggerEx(pLogger, 0, ~0U, "\n"); fclose(pFile); } # elif defined(RT_OS_HAIKU) team_info info; if (get_team_info(0, &info) == B_OK) { /* there is an info.argc, but no way to know arg boundaries */ RTLogLoggerEx(pLogger, 0, ~0U, "Commandline: %.64s\n", info.args); } # elif defined(RT_OS_FREEBSD) /* Retrieve the required length first */ int aiName[4]; aiName[0] = CTL_KERN; aiName[1] = KERN_PROC; aiName[2] = KERN_PROC_ARGS; /* Introduced in FreeBSD 4.0 */ aiName[3] = getpid(); size_t cchArgs = 0; int rcBSD = sysctl(aiName, RT_ELEMENTS(aiName), NULL, &cchArgs, NULL, 0); if (cchArgs > 0) { char *pszArgFileBuf = (char *)RTMemAllocZ(cchArgs + 1 /* Safety */); if (pszArgFileBuf) { /* Retrieve the argument list */ rcBSD = sysctl(aiName, RT_ELEMENTS(aiName), pszArgFileBuf, &cchArgs, NULL, 0); if (!rcBSD) { unsigned iArg = 0; size_t off = 0; while (off < cchArgs) { size_t cchArg = strlen(&pszArgFileBuf[off]); RTLogLoggerEx(pLogger, 0, ~0U, "Arg[%u]: %s\n", iArg, &pszArgFileBuf[off]); /* advance */ off += cchArg + 1; iArg++; } } RTMemFree(pszArgFileBuf); } } # elif defined(RT_OS_OS2) || defined(RT_OS_DARWIN) /* commandline? */ # else # error needs porting. # endif } # else /* IN_GUEST */ /* The user destination is backdoor logging. */ rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_USER, "VBox.log"); # endif /* IN_GUEST */ #else /* IN_RING0 */ /* Some platforms has trouble allocating memory with interrupts and/or preemption disabled. Check and fail before we panic. */ # if defined(RT_OS_DARWIN) if ( !ASMIntAreEnabled() || !RTThreadPreemptIsEnabled(NIL_RTTHREAD)) return NULL; # endif # ifndef IN_GUEST rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_FILE, "VBox-ring0.log"); # else /* IN_GUEST */ rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_USER, "VBox-ring0.log"); # endif /* IN_GUEST */ if (RT_SUCCESS(rc)) { /* * This is where you set your ring-0 logging preferences. * * On platforms which don't differ between debugger and kernel * log printing, STDOUT is gonna be a stub and the DEBUGGER * destination is the one doing all the work. On platforms * that do differ (like Darwin), STDOUT is the kernel log. */ # if defined(DEBUG_bird) /*RTLogGroupSettings(pLogger, "all=~0 -default.l6.l5.l4.l3");*/ RTLogFlags(pLogger, "enabled unbuffered pid tid"); # ifndef IN_GUEST pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT; # endif # endif # if defined(DEBUG_sandervl) && !defined(IN_GUEST) RTLogGroupSettings(pLogger, "+all"); RTLogFlags(pLogger, "enabled unbuffered"); pLogger->fDestFlags |= RTLOGDEST_DEBUGGER; # endif # if defined(DEBUG_ramshankar) /* Guest ring-0 as well */ RTLogGroupSettings(pLogger, "+all.e.l.f"); RTLogFlags(pLogger, "enabled unbuffered"); pLogger->fDestFlags |= RTLOGDEST_DEBUGGER; # endif # if defined(DEBUG_aleksey) /* Guest ring-0 as well */ //RTLogGroupSettings(pLogger, "net_flt_drv.e.l.f.l3.l4.l5 +net_adp_drv.e.l.f.l3.l4.l5"); RTLogGroupSettings(pLogger, "net_flt_drv.e.l.f.l3.l4.l5.l6"); RTLogFlags(pLogger, "enabled unbuffered"); pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT; # endif # if defined(DEBUG_andy) /* Guest ring-0 as well */ RTLogGroupSettings(pLogger, "+all.e.l.f"); RTLogFlags(pLogger, "enabled unbuffered pid tid"); pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT; # endif # if defined(DEBUG_misha) /* Guest ring-0 as well */ RTLogFlags(pLogger, "enabled unbuffered"); pLogger->fDestFlags |= RTLOGDEST_DEBUGGER; # endif # if defined(DEBUG_michael) && defined(IN_GUEST) RTLogGroupSettings(pLogger, "+vga.e.l.f"); RTLogFlags(pLogger, "enabled unbuffered"); pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT; # endif # if 0 /* vboxdrv logging - ATTENTION: this is what we're referring to guys! Change to '# if 1'. */ RTLogGroupSettings(pLogger, "all=~0 -default.l6.l5.l4.l3"); RTLogFlags(pLogger, "enabled unbuffered tid"); pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT; # endif } #endif /* IN_RING0 */ return g_pLogger = RT_SUCCESS(rc) ? pLogger : NULL; }
int main(int argc, char **argv) { int rcRet = 1; int rc; RTR3InitAndSUPLib(); /* * Parse input. */ if (argc <= 1) { syntax(); return 1; } bool fPowerOn = false; uint32_t u32WarpDrive = 100; /* % */ uint64_t cbMem = ~0ULL; const char *pszSavedState = NULL; const char *pszRawMem = NULL; uint64_t offRawMem = 0; const char *pszScript = NULL; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { /* check that it's on short form */ if (argv[i][2]) { if ( strcmp(argv[i], "--help") && strcmp(argv[i], "-help")) RTPrintf("tstAnimate: Syntax error: Unknown argument '%s'.\n", argv[i]); else syntax(); return 1; } /* check for 2nd argument */ switch (argv[i][1]) { case 'r': case 'o': case 'c': case 'm': case 'w': case 'z': if (i + 1 < argc) break; RTPrintf("tstAnimate: Syntax error: '%s' takes a 2nd argument.\n", argv[i]); return 1; } /* process argument */ switch (argv[i][1]) { case 'r': pszRawMem = argv[++i]; break; case 'z': pszSavedState = argv[++i]; break; case 'o': { rc = RTStrToUInt64Ex(argv[++i], NULL, 0, &offRawMem); if (RT_FAILURE(rc)) { RTPrintf("tstAnimate: Syntax error: Invalid offset given to -o.\n"); return 1; } break; } case 'm': { char *pszNext; rc = RTStrToUInt64Ex(argv[++i], &pszNext, 0, &cbMem); if (RT_FAILURE(rc)) { RTPrintf("tstAnimate: Syntax error: Invalid memory size given to -m.\n"); return 1; } switch (*pszNext) { case 'G': cbMem *= _1G; pszNext++; break; case 'M': cbMem *= _1M; pszNext++; break; case 'K': cbMem *= _1K; pszNext++; break; case '\0': break; default: RTPrintf("tstAnimate: Syntax error: Invalid memory size given to -m.\n"); return 1; } if (*pszNext) { RTPrintf("tstAnimate: Syntax error: Invalid memory size given to -m.\n"); return 1; } break; } case 's': pszScript = argv[++i]; break; case 'p': fPowerOn = true; break; case 'w': { rc = RTStrToUInt32Ex(argv[++i], NULL, 0, &u32WarpDrive); if (RT_FAILURE(rc)) { RTPrintf("tstAnimate: Syntax error: Invalid number given to -w.\n"); return 1; } break; } case 'h': case 'H': case '?': syntax(); return 1; default: RTPrintf("tstAnimate: Syntax error: Unknown argument '%s'.\n", argv[i]); return 1; } } else { RTPrintf("tstAnimate: Syntax error at arg no. %d '%s'.\n", i, argv[i]); syntax(); return 1; } } /* * Check that the basic requirements are met. */ if (pszRawMem && pszSavedState) { RTPrintf("tstAnimate: Syntax error: Either -z or -r, not both.\n"); return 1; } if (!pszRawMem && !pszSavedState) { RTPrintf("tstAnimate: Syntax error: The -r argument is compulsory.\n"); return 1; } /* * Open the files. */ RTFILE FileRawMem = NIL_RTFILE; if (pszRawMem) { rc = RTFileOpen(&FileRawMem, pszRawMem, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); if (RT_FAILURE(rc)) { RTPrintf("tstAnimate: error: Failed to open '%s': %Rrc\n", pszRawMem, rc); return 1; } } RTFILE FileScript = NIL_RTFILE; if (pszScript) { rc = RTFileOpen(&FileScript, pszScript, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); if (RT_FAILURE(rc)) { RTPrintf("tstAnimate: error: Failed to open '%s': %Rrc\n", pszScript, rc); return 1; } } /* * Figure the memsize if not specified. */ if (cbMem == ~0ULL) { if (FileRawMem != NIL_RTFILE) { rc = RTFileGetSize(FileRawMem, &cbMem); AssertReleaseRC(rc); cbMem -= offRawMem; cbMem &= ~(PAGE_SIZE - 1); } else { RTPrintf("tstAnimate: error: too lazy to figure out the memsize in a saved state.\n"); return 1; } } RTPrintf("tstAnimate: info: cbMem=0x%llx bytes\n", cbMem); /* * Open a release log. */ static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; PRTLOGGER pRelLogger; rc = RTLogCreate(&pRelLogger, RTLOGFLAGS_PREFIX_TIME_PROG, "all", "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_FILE, "./tstAnimate.log"); if (RT_SUCCESS(rc)) RTLogRelSetDefaultInstance(pRelLogger); else RTPrintf("tstAnimate: rtLogCreateEx failed - %Rrc\n", rc); /* * Create empty VM. */ PVM pVM; rc = VMR3Create(1, NULL, NULL, NULL, cfgmR3CreateDefault, &cbMem, &pVM); if (RT_SUCCESS(rc)) { /* * Load memory. */ if (FileRawMem != NIL_RTFILE) rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)loadMem, 3, pVM, FileRawMem, &offRawMem); else rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)SSMR3Load, 7, pVM, pszSavedState, (uintptr_t)NULL /*pStreamOps*/, (uintptr_t)NULL /*pvUser*/, SSMAFTER_DEBUG_IT, (uintptr_t)NULL /*pfnProgress*/, (uintptr_t)NULL /*pvProgressUser*/); if (RT_SUCCESS(rc)) { /* * Load register script. */ if (FileScript != NIL_RTFILE) rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)scriptRun, 2, pVM, FileScript); if (RT_SUCCESS(rc)) { if (fPowerOn) { /* * Adjust warpspeed? */ if (u32WarpDrive != 100) { rc = TMR3SetWarpDrive(pVM, u32WarpDrive); if (RT_FAILURE(rc)) RTPrintf("warning: TMVirtualSetWarpDrive(,%u) -> %Rrc\n", u32WarpDrive, rc); } /* * Start the thing with single stepping and stuff enabled. * (Try make sure we don't execute anything in raw mode.) */ RTPrintf("info: powering on the VM...\n"); RTLogGroupSettings(NULL, "+REM_DISAS.e.l.f"); rc = REMR3DisasEnableStepping(pVM, true); if (RT_SUCCESS(rc)) { rc = EMR3SetExecutionPolicy(pVM, EMEXECPOLICY_RECOMPILE_RING0, true); AssertReleaseRC(rc); rc = EMR3SetExecutionPolicy(pVM, EMEXECPOLICY_RECOMPILE_RING3, true); AssertReleaseRC(rc); DBGFR3Info(pVM, "cpumguest", "verbose", NULL); if (fPowerOn) rc = VMR3PowerOn(pVM); if (RT_SUCCESS(rc)) { RTPrintf("info: VM is running\n"); signal(SIGINT, SigInterrupt); while (!g_fSignaled) RTThreadSleep(1000); } else RTPrintf("error: Failed to power on the VM: %Rrc\n", rc); } else RTPrintf("error: Failed to enabled singlestepping: %Rrc\n", rc); } else { /* * Don't start it, just enter the debugger. */ RTPrintf("info: entering debugger...\n"); DBGFR3Info(pVM, "cpumguest", "verbose", NULL); signal(SIGINT, SigInterrupt); while (!g_fSignaled) RTThreadSleep(1000); } RTPrintf("info: shutting down the VM...\n"); } /* execScript complains */ } else if (FileRawMem == NIL_RTFILE) /* loadMem complains, SSMR3Load doesn't */ RTPrintf("tstAnimate: error: SSMR3Load failed: rc=%Rrc\n", rc); rcRet = RT_SUCCESS(rc) ? 0 : 1; /* * Cleanup. */ rc = VMR3Destroy(pVM); if (!RT_SUCCESS(rc)) { RTPrintf("tstAnimate: error: failed to destroy vm! rc=%Rrc\n", rc); rcRet++; } } else { RTPrintf("tstAnimate: fatal error: failed to create vm! rc=%Rrc\n", rc); rcRet++; } return rcRet; }