DBGConsole.cpp revision 4d8891c509dc8abc8a8040f347e33afa9c390f8d
1N/A * DBGC - Debugger Console. 1N/A * Copyright (C) 2006-2013 Oracle Corporation 1N/A * This file is part of VirtualBox Open Source Edition (OSE), as 1N/A * you can redistribute it and/or modify it under the terms of the GNU 1N/A * General Public License (GPL) as published by the Free Software 1N/A * Foundation, in version 2 as it comes in the "COPYING" file of the 1N/A * VirtualBox OSE distribution. VirtualBox OSE is distributed in the 1N/A * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. 1N/A/** @page pg_dbgc DBGC - The Debug Console 1N/A * The debugger console is an early attempt to make some interactive 1N/A * debugging facilities for the VirtualBox VMM. It was initially only 1N/A * accessible thru a telnet session in debug builds. Later it was hastily built 1N/A * into the VBoxDbg module with a very simple Qt wrapper around it. 1N/A * The current state is that it's by default shipped with all standard 1N/A * VirtualBox builds. The GUI component is by default accessible in all 1N/A * non-release builds, while release builds require extra data, environment or 1N/A * command line options to make it visible. 1N/A * Now, even if we ship it with all standard builds we would like it to remain 1N/A * an optional feature that can be omitted when building VirtualBox. Therefore, 1N/A * all external code interfacing DBGC need to be enclosed in 1N/A * \#ifdef VBOX_WITH_DEBUGGER blocks. This is mandatory for components that 1N/A * register external commands. 1N/A * @section sec_dbgc_op Operation 1N/A * The console will process commands in a manner similar to the OS/2 and Windows 1N/A * kernel debuggers. This means ';' is a command separator and that when 1N/A * possible we'll use the same command names as these two uses. As an 1N/A * alternative we intent to provide a set of gdb-like commands as well and let 1N/A * the user decide which should take precedence. 1N/A * @subsection sec_dbg_op_numbers Numbers 1N/A * Numbers are hexadecimal unless specified with a prefix indicating 1N/A * elsewise. Prefixes: 1N/A * - '0x' - hexadecimal. 1N/A * Some of the prefixes are a bit uncommon, the reason for this that the 1N/A * typical binary prefix '0b' can also be a hexadecimal value since no prefix or 1N/A * suffix is required for such values. Ditto for '0n' and '0' for decimal and 1N/A * The '`' can be used in the numeric value to separate parts as the user 1N/A * wishes. Generally, though the debugger may use it in output as thousand 1N/A * separator in decimal numbers and 32-bit separator in hex numbers. 1N/A * For historical reasons, a 'h' suffix is suffered on hex numbers. Unlike most 1N/A * assemblers, a leading 0 before a-f is not required with the 'h' suffix. 1N/A * The prefix '0i' can be used instead of '0n', as it was the early decimal 1N/A * prefix employed by DBGC. It's being deprecated and may be removed later. 1N/A * @subsection sec_dbg_op_strings Strings and Symbols 1N/A * The debugger will try to guess, convert or promote what the type of an 1N/A * argument to a command, function or operator based on the input description of 1N/A * the receiver. If the user wants to make it clear to the debugger that 1N/A * something is a string, put it inside double quotes. Symbols should use 1N/A * single quotes, though we're current still a bit flexible on this point. 1N/A * If you need to put a quote character inside the quoted text, you escape it by 1N/A * repating it once: echo "printf(""hello world"");" 1N/A * @subsection sec_dbg_op_address Addressing modes 1N/A * - Default is flat. For compatibility '%' also means flat. 1N/A * - Segmented addresses are specified selector:offset. 1N/A * - Physical addresses are specified using '%%'. 1N/A * - The default target for the addressing is the guest context, the '#' 1N/A * will override this and set it to the host. 1N/A * Note that several operations won't work on host addresses. 1N/A * The '%', '%%' and '#' prefixes is implemented as unary operators, while ':' 1N/A * is a binary operator. Operator precedence takes care of evaluation order. 1N/A * @subsection sec_dbg_op_c_operators C/C++ Operators 1N/A * Most unary and binary arithmetic, comparison, logical and bitwise C/C++ 1N/A * operators are supported by the debugger, with the same precedence rules of 1N/A * course. There is one notable change made due to the unary '%' and '%%' 1N/A * operators, and that is that the modulo (remainder) operator is called 'mod' 1N/A * instead of '%'. This saves a lot of trouble separating argument. 1N/A * There are no assignment operators. Instead some simple global variable space 1N/A * is provided thru the 'set' and 'unset' commands and the unary '$' operator. 1N/A * @subsection sec_dbg_op_registers Registers 1N/A * All registers and their sub-fields exposed by the DBGF API are accessible via 1N/A * the '\@' operator. A few CPU register are accessible directly (as symbols) * without using the '\@' operator. Hypervisor registers are accessible by * prefixing the register name with a dot ('.'). * @subsection sec_dbg_op_commands Commands * Commands names are case sensitive. By convention they are lower cased, starts * with a letter but may contain digits and underscores afterwards. Operators * are not allowed in the name (not even part of it), as we would risk * misunderstanding it otherwise. * Commands returns a status code. * The '.' prefix indicates the set of external commands. External commands are * command registered by VMM components. * @subsection sec_dbg_op_functions Functions * Functions are similar to commands, but return a variable and can only be used * as part of an expression making up the argument of a command, function, * operator or language statement (if we get around to implement that). * @section sec_dbgc_logging Logging * The idea is to be able to pass thru debug and release logs to the console * if the user so wishes. This feature requires some kind of hook into the * logger instance and while this was sketched it hasn't yet been implemented * (dbgcProcessLog and DBGC::fLog). * This feature has not materialized and probably never will. * @section sec_dbgc_linking Linking and API * The DBGC code is linked into the VBoxVMM module. * IMachineDebugger may one day be extended with a DBGC interface so we can work * with DBGC remotely without requiring TCP. Some questions about callbacks * (for output) and security (you may wish to restrict users from debugging a * VM) needs to be answered first though. /******************************************************************************* *******************************************************************************/ /******************************************************************************* *******************************************************************************/ * Resolves a symbol (or tries to do so at least). * @returns VBox status on failure. * @param pDbgc The debug console instance. * @param pszSymbol The symbol name. * @param enmType The result type. Specifying DBGCVAR_TYPE_GC_FAR may * cause failure, avoid it. * @param pResult Where to store the result. * A typical register? (Guest only) "eax;rax;" "r10;" "r8d;r8w;r8b;" "cr0;" "dr0;" "ebx;rbx;" "r11;" "r9d;r9w;r8b;" "dr1;" "ecx;rcx;" "r12;" "cr2;" "dr2;" "edx;rdx;" "r13;" "cr3;" "dr3;" "edi;rdi;dil;" "r14;" "cr4;" "dr4;" "esi;rsi;sil;" "r15;" "cr8;" /** @todo resolve symbols using PDM. */ * Ask the debug info manager. * Default return is a flat gc address. /* impossible at the moment. */ /* simply make it numeric. */ * Process all commands currently in the buffer. * @returns VBox status code. Any error indicates the termination of the console session. * @param pDbgc Debugger console instance data. * @param fNoExecute Indicates that no commands should actually be executed. /** @todo Replace this with a sh/ksh/csh/rexx like toplevel language that * allows doing function, loops, if, cases, and such. */ * Empty the log buffer if we're hooking the log. * Copy the command to the parse buffer. * Parse and execute this command. * Handle input buffer overflow. * Will read any available input looking for a '\n' to reset the buffer on. * @param pDbgc Debugger console instance data. * Assert overflow status and reset the input buffer. * Eat input till no more or there is a '\n'. * When finding a '\n' we'll continue normal processing. * Read input and do some preprocessing. * In addition to the iWrite and achInput, cInputLines is maintained. * In case of an input overflow the fInputOverflow flag will be set. * @param pDbgc Debugger console instance data. * Read it till we don't have any or we have a full input buffer. * More available buffer space? * Read one char and interpret it. Log2((
"DBGC: backspace\n"));
case '\t':
ch =
' ';
break;
Log2((
"DBGC: ch=%02x\n", (
unsigned char)
ch));
/* Terminate it to make it easier to read in the debugger. */ * Reads input, parses it and executes commands on '\n'. * @param pDbgc Debugger console instance data. * @param fNoExecute Indicates that no commands should actually be executed. * We know there's input ready, so let's read it first. * Now execute any ready commands. /* Received nonsense; just skip it. */ * Gets the event context identifier string. * @returns Read only string. * @param enmCtx The context. return "!Unknown Event Ctx!";
* Processes debugger events. * @param pDbgc DBGC Instance data. * @param pEvent Pointer to event data. * The first part is events we have initiated with commands. * The second part is events which can occur at any time. "\ndbgf event: Hypervisor Assertion! (%s)\n" "dbgf event: DBGFSTOP (%s)\n" * Prints any log lines from the log buffer. * The caller must not call function this unless pDbgc->fLog is set. * @returns VBox status. (output related) * @param pDbgc Debugger console instance data. /** @callback_method_impl{FNRTDBGCFGLOG} */ /** @todo Add symbol noise setting. */ * Run the debugger console. * @param pDbgc Pointer to the debugger console instance data. * We're ready for commands now. * This loop will either block on waiting for input or on waiting on * debug events. If we're forwarding the log we cannot wait for long * before we must flush the log. * Wait for a debug event. * Wait for input. If Logging is enabled we'll only wait very briefly. * Creates a a new instance. * @returns VBox status code. * @param ppDbgc Where to store the pointer to the instance data. * @param pBack Pointer to the backend. * @param fFlags The flags. * Allocate and initialize. //pDbgc->cPagingHierarchyDumps = 0; //pDbgc->DisasmPos = {0}; //pDbgc->SourcePos = {0}; //pDbgc->cbDumpElement = 0; //pDbgc->pPlugInHead = NULL; //pDbgc->pFirstBp = NULL; //pDbgc->SearchAddr = {0}; //pDbgc->cbSearchRange = 0; //pDbgc->cInputLines = 0; //pDbgc->fInputOverflow = false; * Destroys a DBGC instance created by dbgcCreate. * @param pDbgc Pointer to the debugger console instance data. /* Unload all plug-ins. */ /* Detach from the VM. */ /* finally, free the instance memory. */ * Make a console instance. * This will not return until either an 'exit' command is issued or a error code * indicating connection loss is encountered. * @returns VINF_SUCCESS if console termination caused by the 'exit' command. * @returns The VBox status code causing the console termination. * @param pUVM The user mode VM handle. * @param pBack Pointer to the backend structure. This must contain * a full set of function pointers to service the console. * @param fFlags Reserved, must be zero. * @remark A forced termination of the console is easiest done by forcing the * callbacks to return fatal failures. * Allocate and initialize instance data "Welcome to the VirtualBox Debugger!\n");
* Attach to the specified VM. "Current VM is %08x, CPU #%u\n" /** @todo get and print the VM name! */ * Set debug config log callback. * Run the debugger main loop. * Remove debug config log callback. * Cleanup console debugger session.