DBGConsole.cpp revision bb5391c96a16b4ba7f86878998710d4a8e7fce53
46f059bea92bedbd395793702c73946ead235586vboxsync * DBGC - Debugger Console.
46f059bea92bedbd395793702c73946ead235586vboxsync * Copyright (C) 2006-2011 Oracle Corporation
46f059bea92bedbd395793702c73946ead235586vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
46f059bea92bedbd395793702c73946ead235586vboxsync * available from http://www.virtualbox.org. This file is free software;
46f059bea92bedbd395793702c73946ead235586vboxsync * you can redistribute it and/or modify it under the terms of the GNU
46f059bea92bedbd395793702c73946ead235586vboxsync * General Public License (GPL) as published by the Free Software
46f059bea92bedbd395793702c73946ead235586vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
46f059bea92bedbd395793702c73946ead235586vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync/** @page pg_dbgc DBGC - The Debug Console
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * The debugger console is an early attempt to make some interactive
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * debugging facilities for the VirtualBox VMM. It was initially only
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * accessible thru a telnet session on debug builds. Later it was hastily
46f059bea92bedbd395793702c73946ead235586vboxsync * built into the VBoxDbg module with a very simple Qt wrapper around it.
46f059bea92bedbd395793702c73946ead235586vboxsync * The debugger is optional and presently not built into release builds
46f059bea92bedbd395793702c73946ead235586vboxsync * of VirtualBox. It is therefore necessary to enclose code related to it
46f059bea92bedbd395793702c73946ead235586vboxsync * in \#ifdef VBOX_WITH_DEBUGGER blocks. This is mandatory for components
46f059bea92bedbd395793702c73946ead235586vboxsync * that register extenral commands.
46f059bea92bedbd395793702c73946ead235586vboxsync * @section sec_dbgc_op Operation (intentions)
46f059bea92bedbd395793702c73946ead235586vboxsync * The console will process commands in a manner similar to the OS/2 and
46f059bea92bedbd395793702c73946ead235586vboxsync * windows kernel debuggers. This means ';' is a command separator and
46f059bea92bedbd395793702c73946ead235586vboxsync * that when possible we'll use the same command names as these two uses.
46f059bea92bedbd395793702c73946ead235586vboxsync * @subsection sec_dbg_op_numbers Numbers
46f059bea92bedbd395793702c73946ead235586vboxsync * Numbers are hexadecimal unless specified with a prefix indicating
46f059bea92bedbd395793702c73946ead235586vboxsync * elsewise. Prefixes:
46f059bea92bedbd395793702c73946ead235586vboxsync * - '0x' - hexadecimal.
46f059bea92bedbd395793702c73946ead235586vboxsync * - '0i' - decimal
46f059bea92bedbd395793702c73946ead235586vboxsync * - '0t' - octal.
46f059bea92bedbd395793702c73946ead235586vboxsync * - '0y' - binary.
46f059bea92bedbd395793702c73946ead235586vboxsync * Some of the prefixes are a bit uncommon, the reason for this that
46f059bea92bedbd395793702c73946ead235586vboxsync * the typical binary prefix '0b' can also be a hexadecimal value since
46f059bea92bedbd395793702c73946ead235586vboxsync * no prefix or suffix is required for such values. Ditto for '0d' and
46f059bea92bedbd395793702c73946ead235586vboxsync * '0' for decimal and octal.
46f059bea92bedbd395793702c73946ead235586vboxsync * @subsection sec_dbg_op_address Addressing modes
46f059bea92bedbd395793702c73946ead235586vboxsync * - Default is flat. For compatibility '%' also means flat.
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * - Segmented addresses are specified selector:offset.
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * - Physical addresses are specified using '%%'.
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * - The default target for the addressing is the guest context, the '#'
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * will override this and set it to the host.
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * Note that several operations won't work on host addresses.
46f059bea92bedbd395793702c73946ead235586vboxsync * The '%', '%%' and '#' prefixes is implemented as unary operators, while ':'
46f059bea92bedbd395793702c73946ead235586vboxsync * is a binary operator. Operator precedence takes care of evaluation order.
46f059bea92bedbd395793702c73946ead235586vboxsync * @subsection sec_dbg_op_evalution Evaluation
46f059bea92bedbd395793702c73946ead235586vboxsync * Most unary and binary C operators are supported, check the help text for
46f059bea92bedbd395793702c73946ead235586vboxsync * details. However, some of these are not yet implemented because this is
46f059bea92bedbd395793702c73946ead235586vboxsync * tiresome and annoying work. So, if something is missing and you need it
1bef0d3fd3b2fe689a4eaa9ebf0647b8bf7c662evboxsync * you implement it or complain to bird. (Ditto for missing functions.)
46f059bea92bedbd395793702c73946ead235586vboxsync * Simple variable support is provided thru the 'set' and 'unset' commands and
46f059bea92bedbd395793702c73946ead235586vboxsync * the unary '$' operator.
46f059bea92bedbd395793702c73946ead235586vboxsync * The unary '@' operator will indicate function calls. Commands and functions
46f059bea92bedbd395793702c73946ead235586vboxsync * are the same thing, except that functions has a return type.
46f059bea92bedbd395793702c73946ead235586vboxsync * @subsection sec_dbg_op_registers Registers
46f059bea92bedbd395793702c73946ead235586vboxsync * Registers are addressed using their name. Some registers which have several fields
46f059bea92bedbd395793702c73946ead235586vboxsync * (like gdtr) will have separate names indicating the different fields. The default
46f059bea92bedbd395793702c73946ead235586vboxsync * register set is the guest one. To access the hypervisor register one have to
46f059bea92bedbd395793702c73946ead235586vboxsync * prefix the register names with '.'.
46f059bea92bedbd395793702c73946ead235586vboxsync * The registers are implemented as built-in symbols. For making gdb guys more at
46f059bea92bedbd395793702c73946ead235586vboxsync * home it is possible to access them with the '$' operator, i.e. as a variable.
46f059bea92bedbd395793702c73946ead235586vboxsync * @subsection sec_dbg_op_commands Commands and Functions
46f059bea92bedbd395793702c73946ead235586vboxsync * Commands and functions are the same thing, except that functions may return a
46f059bea92bedbd395793702c73946ead235586vboxsync * value. So, functions may be used as commands. The command/function handlers
46f059bea92bedbd395793702c73946ead235586vboxsync * can detect whether they are invoked as a command or function by checking whether
46f059bea92bedbd395793702c73946ead235586vboxsync * there is a return variable or not.
46f059bea92bedbd395793702c73946ead235586vboxsync * The command/function names are all lowercase, case sensitive, and starting
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * with a letter. Operator characters are not permitted in the names of course.
46f059bea92bedbd395793702c73946ead235586vboxsync * Space is allowed, but must be flagged so the parser can check for multiple
46f059bea92bedbd395793702c73946ead235586vboxsync * spaces and tabs. (This feature is for 'dump xyz' and for emulating the
46f059bea92bedbd395793702c73946ead235586vboxsync * gdb 'info abc'.)
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * The '.' prefix indicates the set of external commands. External commands are
46f059bea92bedbd395793702c73946ead235586vboxsync * command registered by VMM components.
46f059bea92bedbd395793702c73946ead235586vboxsync * @section sec_dbgc_logging Logging
46f059bea92bedbd395793702c73946ead235586vboxsync * The idea is to be able to pass thru debug and release logs to the console
46f059bea92bedbd395793702c73946ead235586vboxsync * if the user so wishes. This feature requires some kind of hook into the
46f059bea92bedbd395793702c73946ead235586vboxsync * logger instance and while this was sketched it hasn't yet been implemented
46f059bea92bedbd395793702c73946ead235586vboxsync * (dbgcProcessLog and DBGC::fLog).
46f059bea92bedbd395793702c73946ead235586vboxsync * @section sec_dbgc_linking Linking and API
46f059bea92bedbd395793702c73946ead235586vboxsync * The DBGC code is linked into the VBoxVMM module. (At present it is also
46f059bea92bedbd395793702c73946ead235586vboxsync * linked into VBoxDbg, but this is obviously very wrong.)
46f059bea92bedbd395793702c73946ead235586vboxsync * A COM object will be created for the DBGC so it can be operated remotely
46f059bea92bedbd395793702c73946ead235586vboxsync * without using TCP. VBoxDbg is the intended audience for this usage. Some
46f059bea92bedbd395793702c73946ead235586vboxsync * questions about callbacks (for output) and security (you may wish to
46f059bea92bedbd395793702c73946ead235586vboxsync * restrict users from debugging a VM) needs to be answered first though.
46f059bea92bedbd395793702c73946ead235586vboxsync/*******************************************************************************
46f059bea92bedbd395793702c73946ead235586vboxsync* Header Files *
46f059bea92bedbd395793702c73946ead235586vboxsync*******************************************************************************/
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync/*******************************************************************************
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync* Internal Functions *
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync*******************************************************************************/
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * Resolves a symbol (or tries to do so at least).
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * @returns 0 on success.
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * @returns VBox status on failure.
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * @param pDbgc The debug console instance.
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * @param pszSymbol The symbol name.
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * @param enmType The result type. Specifying DBGCVAR_TYPE_GC_FAR may
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * cause failure, avoid it.
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * @param pResult Where to store the result.
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsyncint dbgcSymbolGet(PDBGC pDbgc, const char *pszSymbol, DBGCVARTYPE enmType, PDBGCVAR pResult)
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync PCDBGCSYM pSymDesc = dbgcLookupRegisterSymbol(pDbgc, pszSymbol);
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync return pSymDesc->pfnGet(pSymDesc, &pDbgc->CmdHlp, enmType, pResult);
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * A typical register? (Guest only)
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync static const char s_szSixLetterRegisters[] =
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "rflags;eflags;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync static const char s_szThreeLetterRegisters[] =
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "eax;rax;" "r10;" "r8d;r8w;r8b;" "cr0;" "dr0;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "ebx;rbx;" "r11;" "r9d;r9w;r8b;" "dr1;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "ecx;rcx;" "r12;" "cr2;" "dr2;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "edx;rdx;" "r13;" "cr3;" "dr3;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "edi;rdi;dil;" "r14;" "cr4;" "dr4;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "esi;rsi;sil;" "r15;" "cr8;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "esp;rsp;" "dr6;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "rip;eip;" "dr7;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync static const char s_szTwoLetterRegisters[] =
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "ax;al;ah;" "r8;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "bx;bl;bh;" "r9;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "cx;cl;ch;" "cs;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "dx;dl;dh;" "ds;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "di;" "es;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "si;" "fs;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "bp;" "gs;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync "sp;" "ss;"
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync if ( (cchSymbol == 2 && strstr(s_szTwoLetterRegisters, pszSymbol))
194a8ad893b721dfc22ac5f955671f09db015a3fvboxsync || (cchSymbol == 3 && strstr(s_szThreeLetterRegisters, pszSymbol))
194a8ad893b721dfc22ac5f955671f09db015a3fvboxsync || (cchSymbol == 6 && strstr(s_szSixLetterRegisters, pszSymbol)))
57134cc31d26d91192e87a4541b4f82fbdb2c297vboxsync rc = dbgcOpRegister(pDbgc, &Var, DBGCVAR_CAT_ANY, pResult);
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync return DBGCCmdHlpConvert(&pDbgc->CmdHlp, &Var, enmType, false /*fConvSyms*/, pResult);
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync /** @todo resolve symbols using PDM. */
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * Ask the debug info manager.
57134cc31d26d91192e87a4541b4f82fbdb2c297vboxsync rc = DBGFR3AsSymbolByName(pDbgc->pVM, pDbgc->hDbgAs, pszSymbol, &Symbol, NULL);
57134cc31d26d91192e87a4541b4f82fbdb2c297vboxsync * Default return is a flat gc address.
57134cc31d26d91192e87a4541b4f82fbdb2c297vboxsync DBGCVAR_SET_RANGE(pResult, DBGCVAR_RANGE_BYTES, Symbol.cb);
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync /* nothing to do. */
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync /* impossible at the moment. */
46f059bea92bedbd395793702c73946ead235586vboxsync /* simply make it numeric. */
46f059bea92bedbd395793702c73946ead235586vboxsync /* cast it. */
46f059bea92bedbd395793702c73946ead235586vboxsync return DBGCCmdHlpConvert(&pDbgc->CmdHlp, pResult, enmType, false /*fConvSyms*/, pResult);
46f059bea92bedbd395793702c73946ead235586vboxsync AssertMsgFailed(("Internal error enmType=%d\n", enmType));
46f059bea92bedbd395793702c73946ead235586vboxsync * Process all commands currently in the buffer.
46f059bea92bedbd395793702c73946ead235586vboxsync * @returns VBox status code. Any error indicates the termination of the console session.
46f059bea92bedbd395793702c73946ead235586vboxsync * @param pDbgc Debugger console instance data.
46f059bea92bedbd395793702c73946ead235586vboxsync * @param fNoExecute Indicates that no commands should actually be executed.
46f059bea92bedbd395793702c73946ead235586vboxsyncstatic int dbgcProcessCommands(PDBGC pDbgc, bool fNoExecute)
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync /** @todo Replace this with a sh/ksh/csh/rexx like toplevel language that
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * allows doing function, loops, if, cases, and such. */
46f059bea92bedbd395793702c73946ead235586vboxsync * Empty the log buffer if we're hooking the log.
char ch;
pszTrg++;
return rc;
int rc = pDbgc->pBack->pfnRead(pDbgc->pBack, &pDbgc->achInput[0], sizeof(pDbgc->achInput) - 1, &cbRead);
return rc;
if (psz)
int rc = 0;
if (!cbLeft)
return rc;
while (cbRead-- > 0)
switch (ch)
switch (ch)
return rc;
return rc;
return rc;
switch (enmCtx)
return rc;
bool fPrintPrompt = true;
case DBGFEVENT_HALT_DONE:
case DBGFEVENT_FATAL_ERROR:
case DBGFEVENT_BREAKPOINT:
switch (rc)
case VERR_DBGC_BP_NOT_FOUND:
case VINF_DBGC_BP_NO_COMMAND:
case VINF_BUFFER_OVERFLOW:
rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "\ndbgf event: Breakpoint %u! Command too long to execute! (%s)\n",
case DBGFEVENT_STEPPED:
case DBGFEVENT_STEPPED_HYPER:
rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "\ndbgf event: Single step! (%s)\n", dbgcGetEventCtx(pEvent->enmCtx));
case DBGFEVENT_DEV_STOP:
case DBGFEVENT_TERMINATING:
fPrintPrompt = false;
rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "\ndbgf/dbgc error: Unknown event %d!\n", pEvent->enmType);
return rc;
return rc;
if (!pDbgc)
return VERR_NO_MEMORY;
dbgcEvalInit();
return VINF_SUCCESS;
return rc;
rc = pDbgc->CmdHlp.pfnVBoxError(&pDbgc->CmdHlp, rc, "When trying to attach to VM %p\n", pDbgc->pVM);
if (pVM)