VMMGuruMeditation.cpp revision f56ded1f052329131497b327d6b2ad74c4c37d4f
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper/* $Id$ */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper/** @file
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * VMM - The Virtual Machine Monitor, Guru Meditation Code.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper/*
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Copyright (C) 2006-2007 Sun Microsystems, Inc.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper *
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * This file is part of VirtualBox Open Source Edition (OSE), as
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * available from http://www.virtualbox.org. This file is free software;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * you can redistribute it and/or modify it under the terms of the GNU
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * General Public License (GPL) as published by the Free Software
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Foundation, in version 2 as it comes in the "COPYING" file of the
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper *
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Clara, CA 95054 USA or visit http://www.sun.com if you need
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * additional information or have any questions.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper/*******************************************************************************
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper* Header Files *
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper*******************************************************************************/
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#define LOG_GROUP LOG_GROUP_VMM
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#include <VBox/vmm.h>
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#include <VBox/pdmapi.h>
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#include <VBox/trpm.h>
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#include <VBox/dbgf.h>
8f2e32e3c8f43b9b84cfd30b36477d4fb69acb71Mark de Reeper#include "VMMInternal.h"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#include <VBox/vm.h>
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#include <VBox/err.h>
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#include <VBox/param.h>
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#include <VBox/version.h>
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#include <VBox/hwaccm.h>
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#include <iprt/assert.h>
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#include <iprt/time.h>
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#include <iprt/stream.h>
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#include <iprt/string.h>
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#include <iprt/stdarg.h>
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper/*******************************************************************************
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper* Structures and Typedefs *
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper*******************************************************************************/
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper/**
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Structure to pass to DBGFR3Info() and for doing all other
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * output during fatal dump.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reepertypedef struct VMMR3FATALDUMPINFOHLP
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper{
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /** The helper core. */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper DBGFINFOHLP Core;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /** The release logger instance. */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper PRTLOGGER pRelLogger;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /** The saved release logger flags. */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RTUINT fRelLoggerFlags;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /** The logger instance. */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper PRTLOGGER pLogger;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /** The saved logger flags. */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RTUINT fLoggerFlags;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /** The saved logger destination flags. */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RTUINT fLoggerDestFlags;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /** Whether to output to stderr or not. */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper bool fStdErr;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper} VMMR3FATALDUMPINFOHLP, *PVMMR3FATALDUMPINFOHLP;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper/** Pointer to a VMMR3FATALDUMPINFOHLP structure. */
80c77071c6700660c39046da32a0d7953620f608Mark de Reepertypedef const VMMR3FATALDUMPINFOHLP *PCVMMR3FATALDUMPINFOHLP;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper/**
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Print formatted string.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper *
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * @param pHlp Pointer to this structure.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * @param pszFormat The format string.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * @param ... Arguments.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeperstatic DECLCALLBACK(void) vmmR3FatalDumpInfoHlp_pfnPrintf(PCDBGFINFOHLP pHlp, const char *pszFormat, ...)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper{
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper va_list args;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper va_start(args, pszFormat);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintfV(pHlp, pszFormat, args);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper va_end(args);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper}
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper/**
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Print formatted string.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper *
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * @param pHlp Pointer to this structure.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * @param pszFormat The format string.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * @param args Argument list.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeperstatic DECLCALLBACK(void) vmmR3FatalDumpInfoHlp_pfnPrintfV(PCDBGFINFOHLP pHlp, const char *pszFormat, va_list args)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper{
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper PCVMMR3FATALDUMPINFOHLP pMyHlp = (PCVMMR3FATALDUMPINFOHLP)pHlp;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (pMyHlp->pRelLogger)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper va_list args2;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper va_copy(args2, args);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RTLogLoggerV(pMyHlp->pRelLogger, pszFormat, args2);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper va_end(args2);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (pMyHlp->pLogger)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper va_list args2;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper va_copy(args2, args);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RTLogLoggerV(pMyHlp->pLogger, pszFormat, args);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper va_end(args2);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (pMyHlp->fStdErr)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper va_list args2;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper va_copy(args2, args);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RTStrmPrintfV(g_pStdErr, pszFormat, args);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper va_end(args2);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper}
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper/**
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Initializes the fatal dump output helper.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper *
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * @param pHlp The structure to initialize.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeperstatic void vmmR3FatalDumpInfoHlpInit(PVMMR3FATALDUMPINFOHLP pHlp)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper{
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper memset(pHlp, 0, sizeof(*pHlp));
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->Core.pfnPrintf = vmmR3FatalDumpInfoHlp_pfnPrintf;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->Core.pfnPrintfV = vmmR3FatalDumpInfoHlp_pfnPrintfV;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /*
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * The loggers.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pRelLogger = RTLogRelDefaultInstance();
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#ifndef LOG_ENABLED
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (!pHlp->pRelLogger)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#endif
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pLogger = RTLogDefaultInstance();
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (pHlp->pRelLogger)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->fRelLoggerFlags = pHlp->pRelLogger->fFlags;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pRelLogger->fFlags &= ~(RTLOGFLAGS_BUFFERED | RTLOGFLAGS_DISABLED);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (pHlp->pLogger)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->fLoggerFlags = pHlp->pLogger->fFlags;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->fLoggerDestFlags = pHlp->pLogger->fDestFlags;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pLogger->fFlags &= ~(RTLOGFLAGS_BUFFERED | RTLOGFLAGS_DISABLED);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#ifndef DEBUG_sandervl
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pLogger->fDestFlags |= RTLOGDEST_DEBUGGER;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#endif
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /*
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Check if we need write to stderr.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#ifdef DEBUG_sandervl
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->fStdErr = false; /* takes too long to display here */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#else
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->fStdErr = (!pHlp->pRelLogger || !(pHlp->pRelLogger->fDestFlags & (RTLOGDEST_STDOUT | RTLOGDEST_STDERR)))
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper && (!pHlp->pLogger || !(pHlp->pLogger->fDestFlags & (RTLOGDEST_STDOUT | RTLOGDEST_STDERR)));
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper#endif
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper}
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper/**
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Deletes the fatal dump output helper.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper *
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * @param pHlp The structure to delete.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeperstatic void vmmR3FatalDumpInfoHlpDelete(PVMMR3FATALDUMPINFOHLP pHlp)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper{
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (pHlp->pRelLogger)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RTLogFlush(pHlp->pRelLogger);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pRelLogger->fFlags = pHlp->fRelLoggerFlags;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (pHlp->pLogger)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RTLogFlush(pHlp->pLogger);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pLogger->fFlags = pHlp->fLoggerFlags;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pLogger->fDestFlags = pHlp->fLoggerDestFlags;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper}
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper/**
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Dumps the VM state on a fatal error.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper *
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * @param pVM VM Handle.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * @param pVCpu VMCPU Handle.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * @param rcErr VBox status code.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de ReeperVMMR3DECL(void) VMMR3FatalDump(PVM pVM, PVMCPU pVCpu, int rcErr)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper{
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /*
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Create our output helper and sync it with the log settings.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * This helper will be used for all the output.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper VMMR3FATALDUMPINFOHLP Hlp;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper PCDBGFINFOHLP pHlp = &Hlp.Core;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper vmmR3FatalDumpInfoHlpInit(&Hlp);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /*
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Header.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!!\n"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!! Guru Meditation %d (%Rrc)\n"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!!\n",
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper rcErr, rcErr);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /*
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Continue according to context.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper bool fDoneHyper = false;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper switch (rcErr)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /*
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Hypervisor errors.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper case VERR_VMM_RING0_ASSERTION:
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper case VINF_EM_DBG_HYPER_ASSERTION:
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper const char *pszMsg1 = VMMR3GetRZAssertMsg1(pVM);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper while (pszMsg1 && *pszMsg1 == '\n')
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pszMsg1++;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper const char *pszMsg2 = VMMR3GetRZAssertMsg2(pVM);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper while (pszMsg2 && *pszMsg2 == '\n')
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pszMsg2++;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "%s"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "%s",
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pszMsg1,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pszMsg2);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if ( !pszMsg2
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper || !*pszMsg2
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper || strchr(pszMsg2, '\0')[-1] != '\n')
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp, "\n");
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp, "!!\n");
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /* fall thru */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper case VERR_TRPM_DONT_PANIC:
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper case VERR_TRPM_PANIC:
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper case VINF_EM_RAW_STALE_SELECTOR:
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper case VINF_EM_RAW_IRET_TRAP:
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper case VINF_EM_DBG_HYPER_BREAKPOINT:
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper case VINF_EM_DBG_HYPER_STEPPED:
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /*
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Active trap? This is only of partial interest when in hardware
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * assisted virtualization mode, thus the different messages.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper uint32_t uEIP = CPUMGetHyperEIP(pVCpu);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper TRPMEVENT enmType;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper uint8_t u8TrapNo = 0xce;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RTGCUINT uErrorCode = 0xdeadface;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RTGCUINTPTR uCR2 = 0xdeadface;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper int rc2 = TRPMQueryTrapAll(pVCpu, &u8TrapNo, &enmType, &uErrorCode, &uCR2);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (!HWACCMR3IsActive(pVM))
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (RT_SUCCESS(rc2))
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!! TRAP=%02x ERRCD=%RGv CR2=%RGv EIP=%RX32 Type=%d\n",
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper u8TrapNo, uErrorCode, uCR2, uEIP, enmType);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper else
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!! EIP=%RX32 NOTRAP\n",
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper uEIP);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper else if (RT_SUCCESS(rc2))
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!! ACTIVE TRAP=%02x ERRCD=%RGv CR2=%RGv PC=%RGr Type=%d (Guest!)\n",
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper u8TrapNo, uErrorCode, uCR2, CPUMGetGuestRIP(pVCpu), enmType);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /*
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * The hypervisor dump is not relevant when we're in VT-x/AMD-V mode.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (HWACCMR3IsActive(pVM))
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp, "\n");
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper else
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /*
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Try figure out where eip is.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /* core code? */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (uEIP - (RTGCUINTPTR)pVM->vmm.s.pvCoreCodeRC < pVM->vmm.s.cbCoreCode)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!! EIP is in CoreCode, offset %#x\n",
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper uEIP - (RTGCUINTPTR)pVM->vmm.s.pvCoreCodeRC);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper else
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { /* ask PDM */ /** @todo ask DBGFR3Sym later? */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper char szModName[64];
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RTRCPTR RCPtrMod;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper char szNearSym1[260];
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RTRCPTR RCPtrNearSym1;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper char szNearSym2[260];
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RTRCPTR RCPtrNearSym2;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper int rc = PDMR3LdrQueryRCModFromPC(pVM, uEIP,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper &szModName[0], sizeof(szModName), &RCPtrMod,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper &szNearSym1[0], sizeof(szNearSym1), &RCPtrNearSym1,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper &szNearSym2[0], sizeof(szNearSym2), &RCPtrNearSym2);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (RT_SUCCESS(rc))
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!! EIP in %s (%RRv) at rva %x near symbols:\n"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!! %RRv rva %RRv off %08x %s\n"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!! %RRv rva %RRv off -%08x %s\n",
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper szModName, RCPtrMod, (unsigned)(uEIP - RCPtrMod),
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RCPtrNearSym1, RCPtrNearSym1 - RCPtrMod, (unsigned)(uEIP - RCPtrNearSym1), szNearSym1,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RCPtrNearSym2, RCPtrNearSym2 - RCPtrMod, (unsigned)(RCPtrNearSym2 - uEIP), szNearSym2);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper else
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!! EIP is not in any code known to VMM!\n");
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /* Disassemble the instruction. */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper char szInstr[256];
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper rc2 = DBGFR3DisasInstrEx(pVM, pVCpu->idCpu, 0, 0, DBGF_DISAS_FLAGS_CURRENT_HYPER, &szInstr[0], sizeof(szInstr), NULL);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (RT_SUCCESS(rc2))
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!! %s\n", szInstr);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /* Dump the hypervisor cpu state. */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!!\n"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!!\n"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!!\n");
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper rc2 = DBGFR3Info(pVM, "cpumhyper", "verbose", pHlp);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper fDoneHyper = true;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /* Callstack. */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper PCDBGFSTACKFRAME pFirstFrame;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper rc2 = DBGFR3StackWalkBeginHyper(pVM, 0, &pFirstFrame);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (RT_SUCCESS(rc2))
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!!\n"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!! Call Stack:\n"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!!\n"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "EBP Ret EBP Ret CS:EIP Arg0 Arg1 Arg2 Arg3 CS:EIP Symbol [line]\n");
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper for (PCDBGFSTACKFRAME pFrame = pFirstFrame;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pFrame;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pFrame = DBGFR3StackWalkNext(pFrame))
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "%08RX32 %08RX32 %04RX32:%08RX32 %08RX32 %08RX32 %08RX32 %08RX32",
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper (uint32_t)pFrame->AddrFrame.off,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper (uint32_t)pFrame->AddrReturnFrame.off,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper (uint32_t)pFrame->AddrReturnPC.Sel,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper (uint32_t)pFrame->AddrReturnPC.off,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pFrame->Args.au32[0],
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pFrame->Args.au32[1],
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pFrame->Args.au32[2],
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pFrame->Args.au32[3]);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp, " %RTsel:%08RGv", pFrame->AddrPC.Sel, pFrame->AddrPC.off);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (pFrame->pSymPC)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper RTGCINTPTR offDisp = pFrame->AddrPC.FlatPtr - pFrame->pSymPC->Value;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (offDisp > 0)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp, " %s+%llx", pFrame->pSymPC->szName, (int64_t)offDisp);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper else if (offDisp < 0)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp, " %s-%llx", pFrame->pSymPC->szName, -(int64_t)offDisp);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper else
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp, " %s", pFrame->pSymPC->szName);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (pFrame->pLinePC)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp, " [%s @ 0i%d]", pFrame->pLinePC->szFilename, pFrame->pLinePC->uLineNo);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp, "\n");
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper DBGFR3StackWalkEnd(pFirstFrame);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /* raw stack */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!!\n"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!! Raw stack (mind the direction). pbEMTStackRC=%RRv pbEMTStackBottomRC=%RRv\n"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!!\n"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "%.*Rhxd\n",
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pVM->vmm.s.pbEMTStackRC, pVM->vmm.s.pbEMTStackBottomRC,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper VMM_STACK_SIZE, pVM->vmm.s.pbEMTStackR3);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper } /* !HWACCMR3IsActive */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper break;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper default:
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper break;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper } /* switch (rcErr) */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /*
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Generic info dumper loop.
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper static struct
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper const char *pszInfo;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper const char *pszArgs;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper } const aInfo[] =
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "mappings", NULL },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "hma", NULL },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "cpumguest", "verbose" },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "cpumguestinstr", "verbose" },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "cpumhyper", "verbose" },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "cpumhost", "verbose" },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "mode", "all" },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "cpuid", "verbose" },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "gdt", NULL },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "ldt", NULL },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper //{ "tss", NULL },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "ioport", NULL },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "mmio", NULL },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "phys", NULL },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper //{ "pgmpd", NULL }, - doesn't always work at init time...
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "timers", NULL },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "activetimers", NULL },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "handlers", "phys virt hyper stats" },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper { "cfgm", NULL },
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper };
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper for (unsigned i = 0; i < RT_ELEMENTS(aInfo); i++)
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper {
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper if (fDoneHyper && !strcmp(aInfo[i].pszInfo, "cpumhyper"))
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper continue;
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!!\n"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!! {%s, %s}\n"
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!!\n",
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper aInfo[i].pszInfo, aInfo[i].pszArgs);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper DBGFR3Info(pVM, aInfo[i].pszInfo, aInfo[i].pszArgs, pHlp);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper }
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /* done */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper pHlp->pfnPrintf(pHlp,
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper /*
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper * Delete the output instance (flushing and restoring of flags).
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper */
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper vmmR3FatalDumpInfoHlpDelete(&Hlp);
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper}
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper
80c77071c6700660c39046da32a0d7953620f608Mark de Reeper