summaryrefslogtreecommitdiffstats
path: root/src/VBox/Debugger/testcase
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
commitf8fe689a81f906d1b91bb3220acde2a4ecb14c5b (patch)
tree26484e9d7e2c67806c2d1760196ff01aaa858e8c /src/VBox/Debugger/testcase
parentInitial commit. (diff)
downloadvirtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.tar.xz
virtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.zip
Adding upstream version 6.0.4-dfsg.upstream/6.0.4-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Debugger/testcase')
-rw-r--r--src/VBox/Debugger/testcase/Makefile.kup0
-rw-r--r--src/VBox/Debugger/testcase/tstDBGCParser.cpp1286
-rw-r--r--src/VBox/Debugger/testcase/tstDBGCStubs.cpp728
-rw-r--r--src/VBox/Debugger/testcase/tstVBoxDbg.cpp119
4 files changed, 2133 insertions, 0 deletions
diff --git a/src/VBox/Debugger/testcase/Makefile.kup b/src/VBox/Debugger/testcase/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/Debugger/testcase/Makefile.kup
diff --git a/src/VBox/Debugger/testcase/tstDBGCParser.cpp b/src/VBox/Debugger/testcase/tstDBGCParser.cpp
new file mode 100644
index 00000000..3ea5bf95
--- /dev/null
+++ b/src/VBox/Debugger/testcase/tstDBGCParser.cpp
@@ -0,0 +1,1286 @@
+/* $Id: tstDBGCParser.cpp $ */
+/** @file
+ * DBGC Testcase - Command Parser.
+ */
+
+/*
+ * Copyright (C) 2006-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/dbg.h>
+#include "../DBGCInternal.h"
+
+#include <iprt/string.h>
+#include <iprt/test.h>
+#include <VBox/err.h>
+
+
+/*********************************************************************************************************************************
+* Internal Functions *
+*********************************************************************************************************************************/
+static DECLCALLBACK(bool) tstDBGCBackInput(PDBGCBACK pBack, uint32_t cMillies);
+static DECLCALLBACK(int) tstDBGCBackRead(PDBGCBACK pBack, void *pvBuf, size_t cbBuf, size_t *pcbRead);
+static DECLCALLBACK(int) tstDBGCBackWrite(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten);
+static DECLCALLBACK(void) tstDBGCBackSetReady(PDBGCBACK pBack, bool fReady);
+
+
+/*********************************************************************************************************************************
+* Global Variables *
+*********************************************************************************************************************************/
+/** The test handle. */
+static RTTEST g_hTest = NIL_RTTEST;
+
+/** The DBGC backend structure for use in this testcase. */
+static DBGCBACK g_tstBack =
+{
+ tstDBGCBackInput,
+ tstDBGCBackRead,
+ tstDBGCBackWrite,
+ tstDBGCBackSetReady
+};
+/** For keeping track of output prefixing. */
+static bool g_fPendingPrefix = true;
+/** Pointer to the current input position. */
+const char *g_pszInput = NULL;
+/** The output of the last command. */
+static char g_szOutput[1024];
+/** The current offset into g_szOutput. */
+static size_t g_offOutput = 0;
+
+
+/**
+ * Checks if there is input.
+ *
+ * @returns true if there is input ready.
+ * @returns false if there not input ready.
+ * @param pBack Pointer to the backend structure supplied by
+ * the backend. The backend can use this to find
+ * it's instance data.
+ * @param cMillies Number of milliseconds to wait on input data.
+ */
+static DECLCALLBACK(bool) tstDBGCBackInput(PDBGCBACK pBack, uint32_t cMillies)
+{
+ return g_pszInput != NULL
+ && *g_pszInput != '\0';
+}
+
+
+/**
+ * Read input.
+ *
+ * @returns VBox status code.
+ * @param pBack Pointer to the backend structure supplied by
+ * the backend. The backend can use this to find
+ * it's instance data.
+ * @param pvBuf Where to put the bytes we read.
+ * @param cbBuf Maximum nymber of bytes to read.
+ * @param pcbRead Where to store the number of bytes actually read.
+ * If NULL the entire buffer must be filled for a
+ * successful return.
+ */
+static DECLCALLBACK(int) tstDBGCBackRead(PDBGCBACK pBack, void *pvBuf, size_t cbBuf, size_t *pcbRead)
+{
+ if (g_pszInput && *g_pszInput)
+ {
+ size_t cb = strlen(g_pszInput);
+ if (cb > cbBuf)
+ cb = cbBuf;
+ *pcbRead = cb;
+ memcpy(pvBuf, g_pszInput, cb);
+ g_pszInput += cb;
+ }
+ else
+ *pcbRead = 0;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Write (output).
+ *
+ * @returns VBox status code.
+ * @param pBack Pointer to the backend structure supplied by
+ * the backend. The backend can use this to find
+ * it's instance data.
+ * @param pvBuf What to write.
+ * @param cbBuf Number of bytes to write.
+ * @param pcbWritten Where to store the number of bytes actually written.
+ * If NULL the entire buffer must be successfully written.
+ */
+static DECLCALLBACK(int) tstDBGCBackWrite(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten)
+{
+ const char *pch = (const char *)pvBuf;
+ if (pcbWritten)
+ *pcbWritten = cbBuf;
+ while (cbBuf-- > 0)
+ {
+ /* screen/log output */
+ if (g_fPendingPrefix)
+ {
+ RTTestPrintfNl(g_hTest, RTTESTLVL_ALWAYS, "OUTPUT: ");
+ g_fPendingPrefix = false;
+ }
+ if (*pch == '\n')
+ g_fPendingPrefix = true;
+ RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "%c", *pch);
+
+ /* buffer output */
+ if (g_offOutput < sizeof(g_szOutput) - 1)
+ {
+ g_szOutput[g_offOutput++] = *pch;
+ g_szOutput[g_offOutput] = '\0';
+ }
+
+ /* advance */
+ pch++;
+ }
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Ready / busy notification.
+ *
+ * @param pBack Pointer to the backend structure supplied by
+ * the backend. The backend can use this to find
+ * it's instance data.
+ * @param fReady Whether it's ready (true) or busy (false).
+ */
+static DECLCALLBACK(void) tstDBGCBackSetReady(PDBGCBACK pBack, bool fReady)
+{
+}
+
+
+/**
+ * Completes the output, making sure that we're in
+ * the 1 position of a new line.
+ */
+static void tstCompleteOutput(void)
+{
+ if (!g_fPendingPrefix)
+ RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "\n");
+ g_fPendingPrefix = true;
+}
+
+
+/**
+ * Checks if two DBGC variables are identical
+ *
+ * @returns
+ * @param pVar1 .
+ * @param pVar2 .
+ */
+bool DBGCVarAreIdentical(PCDBGCVAR pVar1, PCDBGCVAR pVar2)
+{
+ if (!pVar1)
+ return false;
+ if (pVar1 == pVar2)
+ return true;
+
+ if (pVar1->enmType != pVar2->enmType)
+ return false;
+ switch (pVar1->enmType)
+ {
+ case DBGCVAR_TYPE_GC_FLAT:
+ if (pVar1->u.GCFlat != pVar2->u.GCFlat)
+ return false;
+ break;
+ case DBGCVAR_TYPE_GC_FAR:
+ if (pVar1->u.GCFar.off != pVar2->u.GCFar.off)
+ return false;
+ if (pVar1->u.GCFar.sel != pVar2->u.GCFar.sel)
+ return false;
+ break;
+ case DBGCVAR_TYPE_GC_PHYS:
+ if (pVar1->u.GCPhys != pVar2->u.GCPhys)
+ return false;
+ break;
+ case DBGCVAR_TYPE_HC_FLAT:
+ if (pVar1->u.pvHCFlat != pVar2->u.pvHCFlat)
+ return false;
+ break;
+ case DBGCVAR_TYPE_HC_PHYS:
+ if (pVar1->u.HCPhys != pVar2->u.HCPhys)
+ return false;
+ break;
+ case DBGCVAR_TYPE_NUMBER:
+ if (pVar1->u.u64Number != pVar2->u.u64Number)
+ return false;
+ break;
+ case DBGCVAR_TYPE_STRING:
+ case DBGCVAR_TYPE_SYMBOL:
+ if (RTStrCmp(pVar1->u.pszString, pVar2->u.pszString) != 0)
+ return false;
+ break;
+ default:
+ AssertFailedReturn(false);
+ }
+
+ if (pVar1->enmRangeType != pVar2->enmRangeType)
+ return false;
+ switch (pVar1->enmRangeType)
+ {
+ case DBGCVAR_RANGE_NONE:
+ break;
+
+ case DBGCVAR_RANGE_ELEMENTS:
+ case DBGCVAR_RANGE_BYTES:
+ if (pVar1->u64Range != pVar2->u64Range)
+ return false;
+ break;
+ default:
+ AssertFailedReturn(false);
+ }
+
+ return true;
+}
+
+/**
+ * Tries one command string.
+ * @param pDbgc Pointer to the debugger instance.
+ * @param pszCmds The command to test.
+ * @param rcCmd The expected result.
+ * @param fNoExecute When set, the command is not executed.
+ * @param pszExpected Expected output. This does not need to include all
+ * of the output, just the start of it. Thus the
+ * prompt can be omitted.
+ * @param cArgs The number of expected arguments. -1 if we don't
+ * want to check the parsed arguments.
+ * @param va Info about expected parsed arguments. For each
+ * argument a DBGCVARTYPE, value (depends on type),
+ * DBGCVARRANGETYPE and optionally range value.
+ */
+static void tstTryExV(PDBGC pDbgc, const char *pszCmds, int rcCmd, bool fNoExecute, const char *pszExpected,
+ int32_t cArgs, va_list va)
+{
+ RT_ZERO(g_szOutput);
+ g_offOutput = 0;
+ g_pszInput = pszCmds;
+ if (strchr(pszCmds, '\0')[-1] == '\n')
+ RTTestPrintfNl(g_hTest, RTTESTLVL_ALWAYS, "RUNNING: %s", pszCmds);
+ else
+ RTTestPrintfNl(g_hTest, RTTESTLVL_ALWAYS, "RUNNING: %s\n", pszCmds);
+
+ pDbgc->rcCmd = VERR_INTERNAL_ERROR;
+ dbgcProcessInput(pDbgc, fNoExecute);
+ tstCompleteOutput();
+
+ if (pDbgc->rcCmd != rcCmd)
+ RTTestFailed(g_hTest, "rcCmd=%Rrc expected =%Rrc\n", pDbgc->rcCmd, rcCmd);
+ else if ( !fNoExecute
+ && pszExpected
+ && strncmp(pszExpected, g_szOutput, strlen(pszExpected)))
+ RTTestFailed(g_hTest, "Wrong output - expected \"%s\"", pszExpected);
+
+ if (cArgs >= 0)
+ {
+ PCDBGCVAR paArgs = pDbgc->aArgs;
+ for (int32_t iArg = 0; iArg < cArgs; iArg++)
+ {
+ DBGCVAR ExpectedArg;
+ ExpectedArg.enmType = (DBGCVARTYPE)va_arg(va, int/*DBGCVARTYPE*/);
+ switch (ExpectedArg.enmType)
+ {
+ case DBGCVAR_TYPE_GC_FLAT: ExpectedArg.u.GCFlat = va_arg(va, RTGCPTR); break;
+ case DBGCVAR_TYPE_GC_FAR: ExpectedArg.u.GCFar.sel = va_arg(va, int /*RTSEL*/);
+ ExpectedArg.u.GCFar.off = va_arg(va, uint32_t); break;
+ case DBGCVAR_TYPE_GC_PHYS: ExpectedArg.u.GCPhys = va_arg(va, RTGCPHYS); break;
+ case DBGCVAR_TYPE_HC_FLAT: ExpectedArg.u.pvHCFlat = va_arg(va, void *); break;
+ case DBGCVAR_TYPE_HC_PHYS: ExpectedArg.u.HCPhys = va_arg(va, RTHCPHYS); break;
+ case DBGCVAR_TYPE_NUMBER: ExpectedArg.u.u64Number = va_arg(va, uint64_t); break;
+ case DBGCVAR_TYPE_STRING: ExpectedArg.u.pszString = va_arg(va, const char *); break;
+ case DBGCVAR_TYPE_SYMBOL: ExpectedArg.u.pszString = va_arg(va, const char *); break;
+ default:
+ RTTestFailed(g_hTest, "enmType=%u iArg=%u\n", ExpectedArg.enmType, iArg);
+ ExpectedArg.u.u64Number = 0;
+ break;
+ }
+ ExpectedArg.enmRangeType = (DBGCVARRANGETYPE)va_arg(va, int /*DBGCVARRANGETYPE*/);
+ switch (ExpectedArg.enmRangeType)
+ {
+ case DBGCVAR_RANGE_NONE: ExpectedArg.u64Range = 0; break;
+ case DBGCVAR_RANGE_ELEMENTS: ExpectedArg.u64Range = va_arg(va, uint64_t); break;
+ case DBGCVAR_RANGE_BYTES: ExpectedArg.u64Range = va_arg(va, uint64_t); break;
+ default:
+ RTTestFailed(g_hTest, "enmRangeType=%u iArg=%u\n", ExpectedArg.enmRangeType, iArg);
+ ExpectedArg.u64Range = 0;
+ break;
+ }
+
+ if (!DBGCVarAreIdentical(&ExpectedArg, &paArgs[iArg]))
+ RTTestFailed(g_hTest,
+ "Arg #%u\n"
+ "actual: enmType=%u u64=%#RX64 enmRangeType=%u u64Range=%#RX64\n"
+ "expected: enmType=%u u64=%#RX64 enmRangeType=%u u64Range=%#RX64\n",
+ iArg,
+ paArgs[iArg].enmType, paArgs[iArg].u.u64Number, paArgs[iArg].enmRangeType, paArgs[iArg].u64Range,
+ ExpectedArg.enmType, ExpectedArg.u.u64Number, ExpectedArg.enmRangeType, ExpectedArg.u64Range);
+ }
+ }
+}
+
+/**
+ * Tries one command string.
+ *
+ * @param pDbgc Pointer to the debugger instance.
+ * @param pszCmds The command to test.
+ * @param rcCmd The expected result.
+ * @param fNoExecute When set, the command is not executed.
+ * @param pszExpected Expected output. This does not need to include all
+ * of the output, just the start of it. Thus the
+ * prompt can be omitted.
+ * @param cArgs The number of expected arguments. -1 if we don't
+ * want to check the parsed arguments.
+ * @param ... Info about expected parsed arguments. For each
+ * argument a DBGCVARTYPE, value (depends on type),
+ * DBGCVARRANGETYPE and optionally range value.
+ */
+static void tstTryEx(PDBGC pDbgc, const char *pszCmds, int rcCmd, bool fNoExecute, const char *pszExpected, int32_t cArgs, ...)
+{
+ va_list va;
+ va_start(va, cArgs);
+ tstTryExV(pDbgc, pszCmds, rcCmd, fNoExecute, pszExpected, cArgs, va);
+ va_end(va);
+}
+
+
+/**
+ * Tries one command string without executing it.
+ *
+ * @param pDbgc Pointer to the debugger instance.
+ * @param pszCmds The command to test.
+ * @param rcCmd The expected result.
+ */
+static void tstTry(PDBGC pDbgc, const char *pszCmds, int rcCmd)
+{
+ return tstTryEx(pDbgc, pszCmds, rcCmd, true /*fNoExecute*/, NULL, -1);
+}
+
+
+#ifdef SOME_UNUSED_FUNCTION
+/**
+ * Tries to execute one command string.
+ * @param pDbgc Pointer to the debugger instance.
+ * @param pszCmds The command to test.
+ * @param rcCmd The expected result.
+ * @param pszExpected Expected output. This does not need to include all
+ * of the output, just the start of it. Thus the
+ * prompt can be omitted.
+ */
+static void tstTryExec(PDBGC pDbgc, const char *pszCmds, int rcCmd, const char *pszExpected)
+{
+ return tstTryEx(pDbgc, pszCmds, rcCmd, false /*fNoExecute*/, pszExpected, -1);
+}
+#endif
+
+
+/**
+ * Test an operator on an expression resulting a plain number.
+ *
+ * @param pDbgc Pointer to the debugger instance.
+ * @param pszExpr The express to test.
+ * @param u64Expect The expected result.
+ */
+static void tstNumOp(PDBGC pDbgc, const char *pszExpr, uint64_t u64Expect)
+{
+ char szCmd[80];
+ RTStrPrintf(szCmd, sizeof(szCmd), "format %s\n", pszExpr);
+
+ char szExpected[80];
+ RTStrPrintf(szExpected, sizeof(szExpected),
+ "Number: hex %llx dec 0i%lld oct 0t%llo", u64Expect, u64Expect, u64Expect);
+
+ return tstTryEx(pDbgc, szCmd, VINF_SUCCESS, false /*fNoExecute*/, szExpected, -1);
+}
+
+
+/*
+ *
+ * CodeView emulation commands.
+ * CodeView emulation commands.
+ * CodeView emulation commands.
+ *
+ */
+
+
+static void testCodeView_ba(PDBGC pDbgc)
+{
+ RTTestISub("codeview - ba");
+ tstTry(pDbgc, "ba x 1 0f000:0000\n", VINF_SUCCESS);
+ tstTry(pDbgc, "ba x 1 0f000:0000 0\n", VINF_SUCCESS);
+ tstTry(pDbgc, "ba x 1 0f000:0000 0 ~0\n", VINF_SUCCESS);
+ tstTry(pDbgc, "ba x 1 0f000:0000 0 ~0 \"command\"\n", VINF_SUCCESS);
+ tstTry(pDbgc, "ba x 1 0f000:0000 0 ~0 \"command\" too_many\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+ tstTry(pDbgc, "ba x 1\n", VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS);
+
+ tstTryEx(pDbgc, "ba x 1 0f000:1234 5 1000 \"command\"\n", VINF_SUCCESS,
+ true /*fNoExecute*/, NULL /*pszExpected*/, 6 /*cArgs*/,
+ DBGCVAR_TYPE_STRING, "x", DBGCVAR_RANGE_BYTES, UINT64_C(1),
+ DBGCVAR_TYPE_NUMBER, UINT64_C(1), DBGCVAR_RANGE_NONE,
+ DBGCVAR_TYPE_GC_FAR, 0xf000, UINT32_C(0x1234), DBGCVAR_RANGE_NONE,
+ DBGCVAR_TYPE_NUMBER, UINT64_C(0x5), DBGCVAR_RANGE_NONE,
+ DBGCVAR_TYPE_NUMBER, UINT64_C(0x1000), DBGCVAR_RANGE_NONE,
+ DBGCVAR_TYPE_STRING, "command", DBGCVAR_RANGE_BYTES, UINT64_C(7));
+
+ tstTryEx(pDbgc, "ba x 1 %0f000:1234 5 1000 \"command\"\n", VINF_SUCCESS,
+ true /*fNoExecute*/, NULL /*pszExpected*/, 6 /*cArgs*/,
+ DBGCVAR_TYPE_STRING, "x", DBGCVAR_RANGE_BYTES, UINT64_C(1),
+ DBGCVAR_TYPE_NUMBER, UINT64_C(1), DBGCVAR_RANGE_NONE,
+ DBGCVAR_TYPE_GC_FLAT, UINT64_C(0xf1234), DBGCVAR_RANGE_NONE,
+ DBGCVAR_TYPE_NUMBER, UINT64_C(0x5), DBGCVAR_RANGE_NONE,
+ DBGCVAR_TYPE_NUMBER, UINT64_C(0x1000), DBGCVAR_RANGE_NONE,
+ DBGCVAR_TYPE_STRING, "command", DBGCVAR_RANGE_BYTES, UINT64_C(7));
+
+ tstTry(pDbgc, "ba x 1 bad:bad 5 1000 \"command\"\n", VINF_SUCCESS);
+ tstTry(pDbgc, "ba x 1 %bad:bad 5 1000 \"command\"\n", VERR_DBGC_PARSE_CONVERSION_FAILED);
+
+ tstTryEx(pDbgc, "ba f 1 0f000:1234 5 1000 \"command\"\n", VINF_SUCCESS,
+ true /*fNoExecute*/, NULL /*pszExpected*/, 6 /*cArgs*/,
+ DBGCVAR_TYPE_STRING, "f", DBGCVAR_RANGE_BYTES, UINT64_C(1),
+ DBGCVAR_TYPE_NUMBER, UINT64_C(1), DBGCVAR_RANGE_NONE,
+ DBGCVAR_TYPE_GC_FAR, 0xf000, UINT32_C(0x1234), DBGCVAR_RANGE_NONE,
+ DBGCVAR_TYPE_NUMBER, UINT64_C(0x5), DBGCVAR_RANGE_NONE,
+ DBGCVAR_TYPE_NUMBER, UINT64_C(0x1000), DBGCVAR_RANGE_NONE,
+ DBGCVAR_TYPE_STRING, "command", DBGCVAR_RANGE_BYTES, UINT64_C(7));
+
+ tstTry(pDbgc, "ba x 1 0f000:1234 qnx 1000 \"command\"\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+ tstTry(pDbgc, "ba x 1 0f000:1234 5 qnx \"command\"\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+ tstTry(pDbgc, "ba x qnx 0f000:1234 5 1000 \"command\"\n", VERR_DBGC_PARSE_INVALID_NUMBER);
+ tstTry(pDbgc, "ba x 1 qnx 5 1000 \"command\"\n", VERR_DBGC_PARSE_INVALID_NUMBER);
+}
+
+
+static void testCodeView_bc(PDBGC pDbgc)
+{
+ RTTestISub("codeview - bc");
+}
+
+
+static void testCodeView_bd(PDBGC pDbgc)
+{
+ RTTestISub("codeview - bc");
+}
+
+
+static void testCodeView_be(PDBGC pDbgc)
+{
+ RTTestISub("codeview - be");
+}
+
+
+static void testCodeView_bl(PDBGC pDbgc)
+{
+ RTTestISub("codeview - bl");
+}
+
+
+static void testCodeView_bp(PDBGC pDbgc)
+{
+ RTTestISub("codeview - bp");
+}
+
+
+static void testCodeView_br(PDBGC pDbgc)
+{
+ RTTestISub("codeview - br");
+}
+
+
+static void testCodeView_d(PDBGC pDbgc)
+{
+ RTTestISub("codeview - d");
+}
+
+
+static void testCodeView_da(PDBGC pDbgc)
+{
+ RTTestISub("codeview - da");
+}
+
+
+static void testCodeView_db(PDBGC pDbgc)
+{
+ RTTestISub("codeview - db");
+}
+
+
+static void testCodeView_dd(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dd");
+}
+
+
+static void testCodeView_dg(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dg");
+}
+
+
+static void testCodeView_dga(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dga");
+}
+
+
+static void testCodeView_di(PDBGC pDbgc)
+{
+ RTTestISub("codeview - di");
+}
+
+
+static void testCodeView_dia(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dia");
+}
+
+
+static void testCodeView_dl(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dl");
+}
+
+
+static void testCodeView_dla(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dla");
+}
+
+
+static void testCodeView_dpd(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dpd");
+}
+
+
+static void testCodeView_dpda(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dpda");
+}
+
+
+static void testCodeView_dpdb(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dpdb");
+}
+
+
+static void testCodeView_dpdg(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dpdg");
+}
+
+
+static void testCodeView_dpdh(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dpdh");
+}
+
+
+static void testCodeView_dph(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dph");
+}
+
+
+static void testCodeView_dphg(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dphg");
+}
+
+
+static void testCodeView_dphh(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dphh");
+}
+
+
+static void testCodeView_dq(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dq");
+}
+
+
+static void testCodeView_dt(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dt");
+}
+
+
+static void testCodeView_dt16(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dt16");
+}
+
+
+static void testCodeView_dt32(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dt32");
+}
+
+
+static void testCodeView_dt64(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dt64");
+}
+
+
+static void testCodeView_dw(PDBGC pDbgc)
+{
+ RTTestISub("codeview - dw");
+}
+
+
+static void testCodeView_eb(PDBGC pDbgc)
+{
+ RTTestISub("codeview - eb");
+}
+
+
+static void testCodeView_ew(PDBGC pDbgc)
+{
+ RTTestISub("codeview - ew");
+}
+
+
+static void testCodeView_ed(PDBGC pDbgc)
+{
+ RTTestISub("codeview - ed");
+}
+
+
+static void testCodeView_eq(PDBGC pDbgc)
+{
+ RTTestISub("codeview - eq");
+}
+
+
+static void testCodeView_g(PDBGC pDbgc)
+{
+ RTTestISub("codeview - g");
+}
+
+
+static void testCodeView_k(PDBGC pDbgc)
+{
+ RTTestISub("codeview - k");
+}
+
+
+static void testCodeView_kg(PDBGC pDbgc)
+{
+ RTTestISub("codeview - kg");
+}
+
+
+static void testCodeView_kh(PDBGC pDbgc)
+{
+ RTTestISub("codeview - kh");
+}
+
+
+static void testCodeView_lm(PDBGC pDbgc)
+{
+ RTTestISub("codeview - lm");
+}
+
+
+static void testCodeView_lmo(PDBGC pDbgc)
+{
+ RTTestISub("codeview - lmo");
+}
+
+
+static void testCodeView_ln(PDBGC pDbgc)
+{
+ RTTestISub("codeview - ln");
+}
+
+
+static void testCodeView_ls(PDBGC pDbgc)
+{
+ RTTestISub("codeview - ls");
+}
+
+
+static void testCodeView_m(PDBGC pDbgc)
+{
+ RTTestISub("codeview - m");
+}
+
+
+static void testCodeView_r(PDBGC pDbgc)
+{
+ RTTestISub("codeview - r");
+}
+
+
+static void testCodeView_rg(PDBGC pDbgc)
+{
+ RTTestISub("codeview - rg");
+}
+
+
+static void testCodeView_rg32(PDBGC pDbgc)
+{
+ RTTestISub("codeview - rg32");
+}
+
+
+static void testCodeView_rg64(PDBGC pDbgc)
+{
+ RTTestISub("codeview - rg64");
+}
+
+
+static void testCodeView_rh(PDBGC pDbgc)
+{
+ RTTestISub("codeview - rh");
+}
+
+
+static void testCodeView_rt(PDBGC pDbgc)
+{
+ RTTestISub("codeview - rt");
+}
+
+
+static void testCodeView_s(PDBGC pDbgc)
+{
+ RTTestISub("codeview - s");
+}
+
+
+static void testCodeView_sa(PDBGC pDbgc)
+{
+ RTTestISub("codeview - sa");
+}
+
+
+static void testCodeView_sb(PDBGC pDbgc)
+{
+ RTTestISub("codeview - sb");
+}
+
+
+static void testCodeView_sd(PDBGC pDbgc)
+{
+ RTTestISub("codeview - sd");
+}
+
+
+static void testCodeView_sq(PDBGC pDbgc)
+{
+ RTTestISub("codeview - sq");
+}
+
+
+static void testCodeView_su(PDBGC pDbgc)
+{
+ RTTestISub("codeview - su");
+}
+
+
+static void testCodeView_sw(PDBGC pDbgc)
+{
+ RTTestISub("codeview - sw");
+}
+
+
+static void testCodeView_t(PDBGC pDbgc)
+{
+ RTTestISub("codeview - t");
+}
+
+
+static void testCodeView_y(PDBGC pDbgc)
+{
+ RTTestISub("codeview - y");
+}
+
+
+static void testCodeView_u64(PDBGC pDbgc)
+{
+ RTTestISub("codeview - u64");
+}
+
+
+static void testCodeView_u32(PDBGC pDbgc)
+{
+ RTTestISub("codeview - u32");
+}
+
+
+static void testCodeView_u16(PDBGC pDbgc)
+{
+ RTTestISub("codeview - u16");
+}
+
+
+static void testCodeView_uv86(PDBGC pDbgc)
+{
+ RTTestISub("codeview - uv86");
+}
+
+
+/*
+ * Common commands.
+ */
+
+static void testCommon_bye_exit_quit(PDBGC pDbgc)
+{
+ RTTestISub("common - bye/exit/quit");
+ /* These have the same parameter descriptor and handler, the command really
+ just has a couple of aliases.*/
+ tstTry(pDbgc, "bye\n", VINF_SUCCESS);
+ tstTry(pDbgc, "bye x\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+ tstTry(pDbgc, "bye 1\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+ tstTry(pDbgc, "bye %bad:bad\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+ tstTry(pDbgc, "exit\n", VINF_SUCCESS);
+ tstTry(pDbgc, "quit\n", VINF_SUCCESS);
+}
+
+
+static void testCommon_cpu(PDBGC pDbgc)
+{
+ RTTestISub("common - cpu");
+ tstTry(pDbgc, "cpu\n", VINF_SUCCESS);
+ tstTry(pDbgc, "cpu 1\n", VINF_SUCCESS);
+ tstTry(pDbgc, "cpu 1 1\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+ tstTry(pDbgc, "cpu emt\n", VERR_DBGC_PARSE_INVALID_NUMBER);
+ tstTry(pDbgc, "cpu @eax\n", VINF_SUCCESS);
+ tstTry(pDbgc, "cpu %bad:bad\n", VERR_DBGC_PARSE_CONVERSION_FAILED);
+ tstTry(pDbgc, "cpu '1'\n", VERR_DBGC_PARSE_INVALID_NUMBER);
+}
+
+
+static void testCommon_echo(PDBGC pDbgc)
+{
+ RTTestISub("common - echo");
+ tstTry(pDbgc, "echo\n", VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS);
+ tstTry(pDbgc, "echo 1\n", VINF_SUCCESS);
+ tstTryEx(pDbgc, "echo 1 2 3 4 5 6\n", VINF_SUCCESS, false, "1 2 3 4 5 6", -1);
+
+ /* The idea here is that since the prefered input is a string, we
+ definitely won't be confused by the number like beginning. */
+ tstTryEx(pDbgc, "echo 1234567890abcdefghijklmn\n", VINF_SUCCESS, false, "1234567890abcdefghijklmn", -1);
+
+ /* The idea here is that we'll perform the + operation and then convert the
+ result to a string (hex). */
+ tstTryEx(pDbgc, "echo 1 + 1\n", VINF_SUCCESS, false, "2", -1);
+ tstTryEx(pDbgc, "echo \"1 + 1\"\n", VINF_SUCCESS, false, "1 + 1", -1);
+
+ tstTryEx(pDbgc, "echo 0i10 + 6\n", VINF_SUCCESS, false, "10", -1);
+ tstTryEx(pDbgc, "echo \"0i10 + 6\"\n", VINF_SUCCESS, false, "0i10 + 6", -1);
+
+ tstTryEx(pDbgc, "echo %f000:0010\n", VINF_SUCCESS, false, "%00000000000f0010", -1);
+ tstTryEx(pDbgc, "echo \"%f000:0010\"\n", VINF_SUCCESS, false, "%f000:0010", -1);
+
+ tstTry(pDbgc, "echo %bad:bad\n", VERR_DBGC_PARSE_CONVERSION_FAILED);
+}
+
+
+static void testCommon_format(PDBGC pDbgc)
+{
+ RTTestISub("common - format");
+}
+
+
+static void testCommon_detect(PDBGC pDbgc)
+{
+ RTTestISub("common - detect");
+}
+
+
+static void testCommon_harakiri(PDBGC pDbgc)
+{
+ RTTestISub("common - harakiri");
+}
+
+
+static void testCommon_help(PDBGC pDbgc)
+{
+ RTTestISub("common - help");
+}
+
+
+static void testCommon_info(PDBGC pDbgc)
+{
+ RTTestISub("common - info");
+ tstTry(pDbgc, "info 12fg\n", VINF_SUCCESS);
+ tstTry(pDbgc, "info fflags argument\n", VINF_SUCCESS);
+}
+
+
+static void testCommon_loadimage(PDBGC pDbgc)
+{
+ RTTestISub("common - loadimage");
+}
+
+
+static void testCommon_loadmap(PDBGC pDbgc)
+{
+ RTTestISub("common - loadmap");
+}
+
+
+static void testCommon_loadplugin(PDBGC pDbgc)
+{
+ RTTestISub("common - loadplugin");
+}
+
+
+static void testCommon_loadseg(PDBGC pDbgc)
+{
+ RTTestISub("common - loadseg");
+}
+
+
+static void testCommon_loadsyms(PDBGC pDbgc)
+{
+ RTTestISub("common - loadsyms");
+}
+
+
+static void testCommon_loadvars(PDBGC pDbgc)
+{
+ RTTestISub("common - loadvars");
+}
+
+
+static void testCommon_log(PDBGC pDbgc)
+{
+ RTTestISub("common - log");
+}
+
+
+static void testCommon_logdest(PDBGC pDbgc)
+{
+ RTTestISub("common - logdest");
+}
+
+
+static void testCommon_logflags(PDBGC pDbgc)
+{
+ RTTestISub("common - logflags");
+}
+
+
+static void testCommon_runscript(PDBGC pDbgc)
+{
+ RTTestISub("common - runscript");
+}
+
+
+static void testCommon_set(PDBGC pDbgc)
+{
+ RTTestISub("common - set");
+}
+
+
+static void testCommon_showplugins(PDBGC pDbgc)
+{
+ RTTestISub("common - showplugins");
+}
+
+
+static void testCommon_showvars(PDBGC pDbgc)
+{
+ RTTestISub("common - showvars");
+}
+
+
+static void testCommon_stop(PDBGC pDbgc)
+{
+ RTTestISub("common - stop");
+}
+
+
+static void testCommon_unloadplugin(PDBGC pDbgc)
+{
+ RTTestISub("common - unloadplugin");
+}
+
+
+static void testCommon_unset(PDBGC pDbgc)
+{
+ RTTestISub("common - unset");
+}
+
+
+static void testCommon_writecore(PDBGC pDbgc)
+{
+ RTTestISub("common - writecore");
+}
+
+
+
+/*
+ * Basic tests.
+ */
+
+static void testBasicsOddCases(PDBGC pDbgc)
+{
+ RTTestISub("Odd cases");
+ tstTry(pDbgc, "r @rax\n", VINF_SUCCESS);
+ tstTry(pDbgc, "r @eax\n", VINF_SUCCESS);
+ tstTry(pDbgc, "r @ah\n", VINF_SUCCESS);
+ tstTry(pDbgc, "r @notavalidregister\n", VERR_DBGF_REGISTER_NOT_FOUND);
+}
+
+
+static void testBasicsOperators(PDBGC pDbgc)
+{
+ RTTestISub("Operators");
+ tstNumOp(pDbgc, "1", 1);
+ tstNumOp(pDbgc, "1", 1);
+ tstNumOp(pDbgc, "1", 1);
+
+ tstNumOp(pDbgc, "+1", 1);
+ tstNumOp(pDbgc, "++++++1", 1);
+
+ tstNumOp(pDbgc, "-1", UINT64_MAX);
+ tstNumOp(pDbgc, "--1", 1);
+ tstNumOp(pDbgc, "---1", UINT64_MAX);
+ tstNumOp(pDbgc, "----1", 1);
+
+ tstNumOp(pDbgc, "~0", UINT64_MAX);
+ tstNumOp(pDbgc, "~1", UINT64_MAX-1);
+ tstNumOp(pDbgc, "~~0", 0);
+ tstNumOp(pDbgc, "~~1", 1);
+
+ tstNumOp(pDbgc, "!1", 0);
+ tstNumOp(pDbgc, "!0", 1);
+ tstNumOp(pDbgc, "!42", 0);
+ tstNumOp(pDbgc, "!!42", 1);
+ tstNumOp(pDbgc, "!!!42", 0);
+ tstNumOp(pDbgc, "!!!!42", 1);
+
+ tstNumOp(pDbgc, "1 +1", 2);
+ tstNumOp(pDbgc, "1 + 1", 2);
+ tstNumOp(pDbgc, "1+1", 2);
+ tstNumOp(pDbgc, "1+ 1", 2);
+
+ tstNumOp(pDbgc, "1 - 1", 0);
+ tstNumOp(pDbgc, "99 - 90", 9);
+
+ tstNumOp(pDbgc, "2 * 2", 4);
+
+ tstNumOp(pDbgc, "2 / 2", 1);
+ tstNumOp(pDbgc, "2 / 0", UINT64_MAX);
+ tstNumOp(pDbgc, "0i1024 / 0i4", 256);
+
+ tstNumOp(pDbgc, "8 mod 7", 1);
+
+ tstNumOp(pDbgc, "1<<1", 2);
+ tstNumOp(pDbgc, "1<<0i32", UINT64_C(0x0000000100000000));
+ tstNumOp(pDbgc, "1<<0i48", UINT64_C(0x0001000000000000));
+ tstNumOp(pDbgc, "1<<0i63", UINT64_C(0x8000000000000000));
+
+ tstNumOp(pDbgc, "fedcba0987654321>>0i04", UINT64_C(0x0fedcba098765432));
+ tstNumOp(pDbgc, "fedcba0987654321>>0i32", UINT64_C(0xfedcba09));
+ tstNumOp(pDbgc, "fedcba0987654321>>0i48", UINT64_C(0x0000fedc));
+
+ tstNumOp(pDbgc, "0ef & 4", 4);
+ tstNumOp(pDbgc, "01234567891 & fff", UINT64_C(0x00000000891));
+ tstNumOp(pDbgc, "01234567891 & ~fff", UINT64_C(0x01234567000));
+
+ tstNumOp(pDbgc, "1 | 1", 1);
+ tstNumOp(pDbgc, "0 | 4", 4);
+ tstNumOp(pDbgc, "4 | 0", 4);
+ tstNumOp(pDbgc, "4 | 4", 4);
+ tstNumOp(pDbgc, "1 | 4 | 2", 7);
+
+ tstNumOp(pDbgc, "1 ^ 1", 0);
+ tstNumOp(pDbgc, "1 ^ 0", 1);
+ tstNumOp(pDbgc, "0 ^ 1", 1);
+ tstNumOp(pDbgc, "3 ^ 1", 2);
+ tstNumOp(pDbgc, "7 ^ 3", 4);
+
+ tstNumOp(pDbgc, "7 || 3", 1);
+ tstNumOp(pDbgc, "1 || 0", 1);
+ tstNumOp(pDbgc, "0 || 1", 1);
+ tstNumOp(pDbgc, "0 || 0", 0);
+
+ tstNumOp(pDbgc, "0 && 0", 0);
+ tstNumOp(pDbgc, "1 && 0", 0);
+ tstNumOp(pDbgc, "0 && 1", 0);
+ tstNumOp(pDbgc, "1 && 1", 1);
+ tstNumOp(pDbgc, "4 && 1", 1);
+}
+
+
+static void testBasicsFundametalParsing(PDBGC pDbgc)
+{
+ RTTestISub("Fundamental parsing");
+ tstTry(pDbgc, "stop\n", VINF_SUCCESS);
+ tstTry(pDbgc, "format 1\n", VINF_SUCCESS);
+ tstTry(pDbgc, "format \n", VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS);
+ tstTry(pDbgc, "format 0 1 23 4\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+ tstTry(pDbgc, "format 'x'\n", VINF_SUCCESS);
+ tstTry(pDbgc, "format 'x' 'x'\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+ tstTry(pDbgc, "format 'x''x'\n", VINF_SUCCESS);
+ tstTry(pDbgc, "format 'x'\"x\"\n", VERR_DBGC_PARSE_EXPECTED_BINARY_OP);
+ tstTry(pDbgc, "format 'x'1\n", VERR_DBGC_PARSE_EXPECTED_BINARY_OP);
+ tstTry(pDbgc, "format (1)1\n", VERR_DBGC_PARSE_EXPECTED_BINARY_OP);
+ tstTry(pDbgc, "format (1)(1)\n", VERR_DBGC_PARSE_EXPECTED_BINARY_OP);
+ tstTry(pDbgc, "format (1)''\n", VERR_DBGC_PARSE_EXPECTED_BINARY_OP);
+ tstTry(pDbgc, "format nosuchfunction(1)\n", VERR_DBGC_PARSE_FUNCTION_NOT_FOUND);
+ tstTry(pDbgc, "format nosuchfunction(1,2,3)\n", VERR_DBGC_PARSE_FUNCTION_NOT_FOUND);
+ tstTry(pDbgc, "format nosuchfunction()\n", VERR_DBGC_PARSE_FUNCTION_NOT_FOUND);
+ tstTry(pDbgc, "format randu32()\n", VINF_SUCCESS);
+ tstTryEx(pDbgc, "format %0\n", VINF_SUCCESS, false, "Guest flat address: %00000000", -1);
+ tstTryEx(pDbgc, "format %eax\n", VINF_SUCCESS, false, "Guest flat address: %cafebabe", -1);
+ tstTry(pDbgc, "sa 3 23 4 'q' \"21123123\" 'b' \n", VINF_SUCCESS);
+ tstTry(pDbgc, "sa 3,23, 4,'q' ,\"21123123\" , 'b' \n", VINF_SUCCESS);
+}
+
+
+int main()
+{
+ /*
+ * Init.
+ */
+ int rc = RTTestInitAndCreate("tstDBGCParser", &g_hTest);
+ if (rc)
+ return rc;
+ RTTestBanner(g_hTest);
+
+ /*
+ * Create a DBGC instance.
+ */
+ RTTestSub(g_hTest, "dbgcCreate");
+ PDBGC pDbgc;
+ rc = dbgcCreate(&pDbgc, &g_tstBack, 0);
+ if (RT_SUCCESS(rc))
+ {
+ pDbgc->pVM = (PVM)pDbgc;
+ rc = dbgcProcessInput(pDbgc, true /* fNoExecute */);
+ tstCompleteOutput();
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Perform basic tests first.
+ */
+ testBasicsFundametalParsing(pDbgc);
+ if (RTTestErrorCount(g_hTest) == 0)
+ testBasicsOperators(pDbgc);
+ if (RTTestErrorCount(g_hTest) == 0)
+ testBasicsOddCases(pDbgc);
+
+ /*
+ * Test commands.
+ */
+ if (RTTestErrorCount(g_hTest) == 0)
+ {
+ testCodeView_ba(pDbgc);
+ testCodeView_bc(pDbgc);
+ testCodeView_bd(pDbgc);
+ testCodeView_be(pDbgc);
+ testCodeView_bl(pDbgc);
+ testCodeView_bp(pDbgc);
+ testCodeView_br(pDbgc);
+ testCodeView_d(pDbgc);
+ testCodeView_da(pDbgc);
+ testCodeView_db(pDbgc);
+ testCodeView_dd(pDbgc);
+ testCodeView_dg(pDbgc);
+ testCodeView_dga(pDbgc);
+ testCodeView_di(pDbgc);
+ testCodeView_dia(pDbgc);
+ testCodeView_dl(pDbgc);
+ testCodeView_dla(pDbgc);
+ testCodeView_dpd(pDbgc);
+ testCodeView_dpda(pDbgc);
+ testCodeView_dpdb(pDbgc);
+ testCodeView_dpdg(pDbgc);
+ testCodeView_dpdh(pDbgc);
+ testCodeView_dph(pDbgc);
+ testCodeView_dphg(pDbgc);
+ testCodeView_dphh(pDbgc);
+ testCodeView_dq(pDbgc);
+ testCodeView_dt(pDbgc);
+ testCodeView_dt16(pDbgc);
+ testCodeView_dt32(pDbgc);
+ testCodeView_dt64(pDbgc);
+ testCodeView_dw(pDbgc);
+ testCodeView_eb(pDbgc);
+ testCodeView_ew(pDbgc);
+ testCodeView_ed(pDbgc);
+ testCodeView_eq(pDbgc);
+ testCodeView_g(pDbgc);
+ testCodeView_k(pDbgc);
+ testCodeView_kg(pDbgc);
+ testCodeView_kh(pDbgc);
+ testCodeView_lm(pDbgc);
+ testCodeView_lmo(pDbgc);
+ testCodeView_ln(pDbgc);
+ testCodeView_ls(pDbgc);
+ testCodeView_m(pDbgc);
+ testCodeView_r(pDbgc);
+ testCodeView_rg(pDbgc);
+ testCodeView_rg32(pDbgc);
+ testCodeView_rg64(pDbgc);
+ testCodeView_rh(pDbgc);
+ testCodeView_rt(pDbgc);
+ testCodeView_s(pDbgc);
+ testCodeView_sa(pDbgc);
+ testCodeView_sb(pDbgc);
+ testCodeView_sd(pDbgc);
+ testCodeView_sq(pDbgc);
+ testCodeView_su(pDbgc);
+ testCodeView_sw(pDbgc);
+ testCodeView_t(pDbgc);
+ testCodeView_y(pDbgc);
+ testCodeView_u64(pDbgc);
+ testCodeView_u32(pDbgc);
+ testCodeView_u16(pDbgc);
+ testCodeView_uv86(pDbgc);
+
+ testCommon_bye_exit_quit(pDbgc);
+ testCommon_cpu(pDbgc);
+ testCommon_echo(pDbgc);
+ testCommon_format(pDbgc);
+ testCommon_detect(pDbgc);
+ testCommon_harakiri(pDbgc);
+ testCommon_help(pDbgc);
+ testCommon_info(pDbgc);
+ testCommon_loadimage(pDbgc);
+ testCommon_loadmap(pDbgc);
+ testCommon_loadplugin(pDbgc);
+ testCommon_loadseg(pDbgc);
+ testCommon_loadsyms(pDbgc);
+ testCommon_loadvars(pDbgc);
+ testCommon_log(pDbgc);
+ testCommon_logdest(pDbgc);
+ testCommon_logflags(pDbgc);
+ testCommon_runscript(pDbgc);
+ testCommon_set(pDbgc);
+ testCommon_showplugins(pDbgc);
+ testCommon_showvars(pDbgc);
+ testCommon_stop(pDbgc);
+ testCommon_unloadplugin(pDbgc);
+ testCommon_unset(pDbgc);
+ testCommon_writecore(pDbgc);
+ }
+ }
+
+ dbgcDestroy(pDbgc);
+ }
+
+ /*
+ * Summary
+ */
+ return RTTestSummaryAndDestroy(g_hTest);
+}
diff --git a/src/VBox/Debugger/testcase/tstDBGCStubs.cpp b/src/VBox/Debugger/testcase/tstDBGCStubs.cpp
new file mode 100644
index 00000000..0e75733a
--- /dev/null
+++ b/src/VBox/Debugger/testcase/tstDBGCStubs.cpp
@@ -0,0 +1,728 @@
+/* $Id: tstDBGCStubs.cpp $ */
+/** @file
+ * DBGC Testcase - Command Parser, VMM Stub Functions.
+ */
+
+/*
+ * Copyright (C) 2006-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <VBox/err.h>
+#include <VBox/vmm/vm.h>
+#include <iprt/string.h>
+
+
+
+#include <VBox/vmm/dbgf.h>
+VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromFlat(PUVM pUVM, PDBGFADDRESS pAddress, RTGCUINTPTR FlatPtr)
+{
+ return NULL;
+}
+
+VMMR3DECL(int) DBGFR3AddrFromSelOff(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, RTSEL Sel, RTUINTPTR off)
+{
+ /* bad:bad -> provke error during parsing. */
+ if (Sel == 0xbad && off == 0xbad)
+ return VERR_OUT_OF_SELECTOR_BOUNDS;
+
+ /* real mode conversion. */
+ pAddress->FlatPtr = (uint32_t)(Sel << 4) | off;
+ pAddress->fFlags |= DBGFADDRESS_FLAGS_FLAT;
+ pAddress->Sel = DBGF_SEL_FLAT;
+ pAddress->off = pAddress->FlatPtr;
+ return VINF_SUCCESS;
+}
+
+VMMR3DECL(int) DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, PRTGCPHYS pGCPhys)
+{
+ return VERR_INTERNAL_ERROR;
+}
+
+VMMR3DECL(int) DBGFR3Attach(PUVM pUVM)
+{
+ return VERR_INTERNAL_ERROR;
+}
+
+VMMR3DECL(int) DBGFR3BpClear(PUVM pUVM, RTUINT iBp)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3BpDisable(PUVM pUVM, RTUINT iBp)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3BpEnable(PUVM pUVM, RTUINT iBp)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3BpEnum(PUVM pUVM, PFNDBGFBPENUM pfnCallback, void *pvUser)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3BpSetInt3(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, PRTUINT piBp)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3BpSetReg(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable,
+ uint8_t fType, uint8_t cb, PRTUINT piBp)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3BpSetREM(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, PRTUINT piBp)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3QueryWaitable(PUVM pUVM)
+{
+ return VINF_SUCCESS;
+}
+VMMR3DECL(int) DBGFR3Detach(PUVM pUVM)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3DisasInstrEx(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, RTGCPTR GCPtr, uint32_t fFlags,
+ char *pszOutput, uint32_t cchOutput, uint32_t *pcbInstr)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3EventWait(PUVM pUVM, RTMSINTERVAL cMillies, PCDBGFEVENT *ppEvent)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3EventConfigEx(PUVM pUVM, PCDBGFEVENTCONFIG paConfigs, size_t cConfigs)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3InterruptConfigEx(PUVM pUVM, PCDBGFINTERRUPTCONFIG paConfigs, size_t cConfigs)
+{
+ return VERR_INTERNAL_ERROR;
+}
+
+VMMR3DECL(int) DBGFR3Halt(PUVM pUVM)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3Info(PUVM pUVM, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3InfoEx(PUVM pUVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(bool) DBGFR3IsHalted(PUVM pUVM)
+{
+ return true;
+}
+VMMR3DECL(int) DBGFR3LogModifyDestinations(PUVM pUVM, const char *pszDestSettings)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3LogModifyFlags(PUVM pUVM, const char *pszFlagSettings)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3LogModifyGroups(PUVM pUVM, const char *pszGroupSettings)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(RTDBGCFG) DBGFR3AsGetConfig(PUVM pUVM)
+{
+ return NIL_RTDBGCFG;
+}
+VMMR3DECL(int) DBGFR3AsLoadImage(PUVM pUVM, RTDBGAS hAS, const char *pszFilename, const char *pszModName, RTLDRARCH enmArch,
+ PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3AsLoadMap(PUVM pUVM, RTDBGAS hAS, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, RTGCUINTPTR uSubtrahend, uint32_t fFlags)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3AsUnlinkModuleByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszModName)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PUVM pUVM, RTDBGAS hAlias)
+{
+ return NIL_RTDBGAS;
+}
+VMMR3DECL(int) DBGFR3AsLineByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress,
+ PRTGCINTPTR poffDisp, PRTDBGLINE pLine, PRTDBGMOD phMod)
+{
+ return VERR_DBG_LINE_NOT_FOUND;
+}
+VMMR3DECL(int) DBGFR3Resume(PUVM pUVM)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3StackWalkBegin(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFSTACKFRAME *ppFirstFrame)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(PCDBGFSTACKFRAME) DBGFR3StackWalkNext(PCDBGFSTACKFRAME pCurrent)
+{
+ return NULL;
+}
+VMMR3DECL(void) DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame)
+{
+}
+VMMR3DECL(int) DBGFR3StepEx(PUVM pUVM, VMCPUID idCpu, uint32_t fFlags, PCDBGFADDRESS pStopPcAddr,
+ PCDBGFADDRESS pStopPopAddr, RTGCUINTPTR cbStopPop, uint32_t cMaxSteps)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3AsSymbolByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t fFlags, PRTGCINTPTR poffDisplacement, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t fFlags,
+ PRTGCINTPTR poffDisp, PRTDBGMOD phMod)
+{
+ return NULL;
+}
+VMMR3DECL(int) DBGFR3AsSymbolByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3AsLinkModule(PUVM pUVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3ModInMem(PUVM pUVM, PCDBGFADDRESS pImageAddr, uint32_t fFlags, const char *pszName, const char *pszFilename,
+ RTLDRARCH enmArch, uint32_t cbImage, PRTDBGMOD phDbgMod, PRTERRINFO pErrInfo)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3MemScan(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, RTGCUINTPTR uAlign, const void *pabNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3MemRead(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3MemReadString(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, char *pszBuf, size_t cchBuf)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3MemWrite(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, const void *pvBuf, size_t cbRead)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMDECL(int) DBGFR3PagingDumpEx(PUVM pUVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr,
+ uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3RegNmValidate(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg)
+{
+ if ( !strcmp(pszReg, "ah")
+ || !strcmp(pszReg, "ax")
+ || !strcmp(pszReg, "eax")
+ || !strcmp(pszReg, "rax"))
+ return VINF_SUCCESS;
+ return VERR_DBGF_REGISTER_NOT_FOUND;
+}
+VMMR3DECL(const char *) DBGFR3RegCpuName(PUVM pUVM, DBGFREG enmReg, DBGFREGVALTYPE enmType)
+{
+ return NULL;
+}
+VMMR3DECL(int) DBGFR3RegCpuQueryU8( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t *pu8)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3RegCpuQueryU16( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t *pu16)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3RegCpuQueryU32( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t *pu32)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3RegCpuQueryU64( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3RegCpuQueryXdtr(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64Base, uint16_t *pu16Limit)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3RegNmQuery(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType)
+{
+ if (idDefCpu == 0 || idDefCpu == DBGFREG_HYPER_VMCPUID)
+ {
+ if (!strcmp(pszReg, "ah"))
+ {
+ pValue->u16 = 0xf0;
+ *penmType = DBGFREGVALTYPE_U8;
+ return VINF_SUCCESS;
+ }
+ if (!strcmp(pszReg, "ax"))
+ {
+ pValue->u16 = 0xbabe;
+ *penmType = DBGFREGVALTYPE_U16;
+ return VINF_SUCCESS;
+ }
+ if (!strcmp(pszReg, "eax"))
+ {
+ pValue->u32 = 0xcafebabe;
+ *penmType = DBGFREGVALTYPE_U32;
+ return VINF_SUCCESS;
+ }
+ if (!strcmp(pszReg, "rax"))
+ {
+ pValue->u64 = UINT64_C(0x00beef00feedface);
+ *penmType = DBGFREGVALTYPE_U32;
+ return VINF_SUCCESS;
+ }
+ }
+ return VERR_DBGF_REGISTER_NOT_FOUND;
+}
+VMMR3DECL(int) DBGFR3RegPrintf(PUVM pUVM, VMCPUID idCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, ...)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMDECL(ssize_t) DBGFR3RegFormatValue(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, bool fSpecial)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3RegNmSet(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType)
+{
+ return VERR_INTERNAL_ERROR;
+}
+
+VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromPhys(PUVM pUVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr)
+{
+ return NULL;
+}
+VMMR3DECL(int) DBGFR3AddrToHostPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3AddrToVolatileR3Ptr(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr)
+{
+ return VERR_INTERNAL_ERROR;
+}
+
+VMMR3DECL(int) DBGFR3OSRegister(PUVM pUVM, PCDBGFOSREG pReg)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3OSDetect(PUVM pUVM, char *pszName, size_t cchName)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3OSQueryNameAndVersion(PUVM pUVM, char *pszName, size_t cchName, char *pszVersion, size_t cchVersion)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(void *) DBGFR3OSQueryInterface(PUVM pUVM, DBGFOSINTERFACE enmIf)
+{
+ return NULL;
+}
+
+VMMR3DECL(int) DBGFR3SelQueryInfo(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, uint32_t fFlags, PDBGFSELINFO pSelInfo)
+{
+ return VERR_INTERNAL_ERROR;
+}
+
+VMMR3DECL(CPUMMODE) DBGFR3CpuGetMode(PUVM pUVM, VMCPUID idCpu)
+{
+ return CPUMMODE_INVALID;
+}
+VMMR3DECL(VMCPUID) DBGFR3CpuGetCount(PUVM pUVM)
+{
+ return 1;
+}
+VMMR3DECL(bool) DBGFR3CpuIsIn64BitCode(PUVM pUVM, VMCPUID idCpu)
+{
+ return false;
+}
+VMMR3DECL(bool) DBGFR3CpuIsInV86Code(PUVM pUVM, VMCPUID idCpu)
+{
+ return false;
+}
+
+VMMR3DECL(int) DBGFR3CoreWrite(PUVM pUVM, const char *pszFilename, bool fReplaceFile)
+{
+ return VERR_INTERNAL_ERROR;
+}
+
+VMMR3DECL(int) DBGFR3PlugInLoad(PUVM pUVM, const char *pszPlugIn, char *pszActual, size_t cbActual, PRTERRINFO pErrInfo)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3PlugInUnload(PUVM pUVM, const char *pszName)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(void) DBGFR3PlugInLoadAll(PUVM pUVM)
+{
+}
+VMMR3DECL(int) DBGFR3TypeRegister( PUVM pUVM, uint32_t cTypes, PCDBGFTYPEREG paTypes)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3TypeDeregister(PUVM pUVM, const char *pszType)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3TypeQueryReg( PUVM pUVM, const char *pszType, PCDBGFTYPEREG *ppTypeReg)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3TypeQuerySize( PUVM pUVM, const char *pszType, size_t *pcbType)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3TypeSetSize( PUVM pUVM, const char *pszType, size_t cbType)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3TypeDumpEx( PUVM pUVM, const char *pszType, uint32_t fFlags,
+ uint32_t cLvlMax, PFNDBGFR3TYPEDUMP pfnDump, void *pvUser)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3TypeQueryValByType(PUVM pUVM, PCDBGFADDRESS pAddress, const char *pszType,
+ PDBGFTYPEVAL *ppVal)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(void) DBGFR3TypeValFree(PDBGFTYPEVAL pVal)
+{
+}
+VMMR3DECL(int) DBGFR3TypeValDumpEx(PUVM pUVM, PCDBGFADDRESS pAddress, const char *pszType, uint32_t fFlags,
+ uint32_t cLvlMax, FNDBGFR3TYPEVALDUMP pfnDump, void *pvUser)
+{
+ return VERR_INTERNAL_ERROR;
+}
+
+VMMR3DECL(int) DBGFR3FlowCreate(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddressStart, uint32_t cbDisasmMax,
+ uint32_t fFlagsFlow, uint32_t fFlagsDisasm, PDBGFFLOW phFlow)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(uint32_t) DBGFR3FlowRetain(DBGFFLOW hFlow)
+{
+ return 0;
+}
+VMMR3DECL(uint32_t) DBGFR3FlowRelease(DBGFFLOW hFlow)
+{
+ return 0;
+}
+VMMR3DECL(int) DBGFR3FlowQueryStartBb(DBGFFLOW hFlow, PDBGFFLOWBB phFlowBb)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3FlowQueryBbByAddress(DBGFFLOW hFlow, PDBGFADDRESS pAddr, PDBGFFLOWBB phFlowBb)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3FlowQueryBranchTblByAddress(DBGFFLOW hFlow, PDBGFADDRESS pAddr, PDBGFFLOWBRANCHTBL phFlowBranchTbl)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(uint32_t) DBGFR3FlowGetBbCount(DBGFFLOW hFlow)
+{
+ return 0;
+}
+VMMR3DECL(uint32_t) DBGFR3FlowGetBranchTblCount(DBGFFLOW hFlow)
+{
+ return 0;
+}
+VMMR3DECL(uint32_t) DBGFR3FlowBbRetain(DBGFFLOWBB hFlowBb)
+{
+ return 0;
+}
+VMMR3DECL(uint32_t) DBGFR3FlowBbRelease(DBGFFLOWBB hFlowBb)
+{
+ return 0;
+}
+VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetStartAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrStart)
+{
+ return NULL;
+}
+VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetEndAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrEnd)
+{
+ return NULL;
+}
+VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetBranchAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrTarget)
+{
+ return NULL;
+}
+VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetFollowingAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrFollow)
+{
+ return NULL;
+}
+VMMR3DECL(DBGFFLOWBBENDTYPE) DBGFR3FlowBbGetType(DBGFFLOWBB hFlowBb)
+{
+ return DBGFFLOWBBENDTYPE_INVALID;
+}
+VMMR3DECL(uint32_t) DBGFR3FlowBbGetInstrCount(DBGFFLOWBB hFlowBb)
+{
+ return 0;
+}
+VMMR3DECL(uint32_t) DBGFR3FlowBbGetFlags(DBGFFLOWBB hFlowBb)
+{
+ return 0;
+}
+VMMR3DECL(int) DBGFR3FlowBbQueryBranchTbl(DBGFFLOWBB hFlowBb, PDBGFFLOWBRANCHTBL phBranchTbl)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3FlowBbQueryError(DBGFFLOWBB hFlowBb, const char **ppszErr)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3FlowBbQueryInstr(DBGFFLOWBB hFlowBb, uint32_t idxInstr, PDBGFADDRESS pAddrInstr,
+ uint32_t *pcbInstr, const char **ppszInstr)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3FlowBbQuerySuccessors(DBGFFLOWBB hFlowBb, PDBGFFLOWBB phFlowBbFollow,
+ PDBGFFLOWBB phFlowBbTarget)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(uint32_t) DBGFR3FlowBbGetRefBbCount(DBGFFLOWBB hFlowBb)
+{
+ return 0;
+}
+VMMR3DECL(int) DBGFR3FlowBbGetRefBb(DBGFFLOWBB hFlowBb, PDBGFFLOWBB pahFlowBbRef, uint32_t cRef)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(uint32_t) DBGFR3FlowBranchTblRetain(DBGFFLOWBRANCHTBL hFlowBranchTbl)
+{
+ return 0;
+}
+VMMR3DECL(uint32_t) DBGFR3FlowBranchTblRelease(DBGFFLOWBRANCHTBL hFlowBranchTbl)
+{
+ return 0;
+}
+VMMR3DECL(uint32_t) DBGFR3FlowBranchTblGetSlots(DBGFFLOWBRANCHTBL hFlowBranchTbl)
+{
+ return 0;
+}
+VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBranchTblGetStartAddress(DBGFFLOWBRANCHTBL hFlowBranchTbl, PDBGFADDRESS pAddrStart)
+{
+ return NULL;
+}
+VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBranchTblGetAddrAtSlot(DBGFFLOWBRANCHTBL hFlowBranchTbl, uint32_t idxSlot, PDBGFADDRESS pAddrSlot)
+{
+ return NULL;
+}
+VMMR3DECL(int) DBGFR3FlowBranchTblQueryAddresses(DBGFFLOWBRANCHTBL hFlowBranchTbl, PDBGFADDRESS paAddrs, uint32_t cAddrs)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3FlowItCreate(DBGFFLOW hFlow, DBGFFLOWITORDER enmOrder, PDBGFFLOWIT phFlowIt)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(void) DBGFR3FlowItDestroy(DBGFFLOWIT hFlowIt)
+{
+}
+VMMR3DECL(DBGFFLOWBB) DBGFR3FlowItNext(DBGFFLOWIT hFlowIt)
+{
+ return NULL;
+}
+VMMR3DECL(int) DBGFR3FlowItReset(DBGFFLOWIT hFlowIt)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) DBGFR3FlowBranchTblItCreate(DBGFFLOW hFlow, DBGFFLOWITORDER enmOrder, PDBGFFLOWBRANCHTBLIT phFlowBranchTblIt)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(void) DBGFR3FlowBranchTblItDestroy(DBGFFLOWBRANCHTBLIT hFlowBranchTblIt)
+{
+}
+VMMR3DECL(DBGFFLOWBRANCHTBL) DBGFR3FlowBranchTblItNext(DBGFFLOWBRANCHTBLIT hFlowBranchTblIt)
+{
+ return NULL;
+}
+VMMR3DECL(int) DBGFR3FlowBranchTblItReset(DBGFFLOWBRANCHTBLIT hFlowBranchTblIt)
+{
+ return VERR_INTERNAL_ERROR;
+}
+
+VMMR3DECL(int) DBGFR3FormatBugCheck(PUVM pUVM, char *pszDetails, size_t cbDetails,
+ uint64_t uP0, uint64_t uP1, uint64_t uP2, uint64_t uP3, uint64_t uP4)
+{
+ pszDetails[0] = '\0';
+ return VERR_INTERNAL_ERROR;
+}
+
+#include <VBox/vmm/cfgm.h>
+VMMR3DECL(int) CFGMR3ValidateConfig(PCFGMNODE pNode, const char *pszNode,
+ const char *pszValidValues, const char *pszValidNodes,
+ const char *pszWho, uint32_t uInstance)
+{
+ return VINF_SUCCESS;
+}
+
+VMMR3DECL(PCFGMNODE) CFGMR3GetRootU(PUVM pUVM)
+{
+ return NULL;
+}
+
+VMMR3DECL(PCFGMNODE) CFGMR3GetChild(PCFGMNODE pNode, const char *pszPath)
+{
+ return NULL;
+}
+
+VMMR3DECL(int) CFGMR3QueryString(PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString)
+{
+ *pszString = '\0';
+ return VINF_SUCCESS;
+}
+
+VMMR3DECL(int) CFGMR3QueryStringDef(PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString, const char *pszDef)
+{
+ *pszString = '\0';
+ return VINF_SUCCESS;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+// The rest should eventually be replaced by DBGF calls and eliminated. //
+/////////////////////////////////////////////////////////////////////////
+
+
+#include <VBox/vmm/cpum.h>
+
+VMMDECL(uint64_t) CPUMGetGuestCR3(PVMCPU pVCpu)
+{
+ return 0;
+}
+
+VMMDECL(uint64_t) CPUMGetGuestCR4(PVMCPU pVCpu)
+{
+ return 0;
+}
+
+VMMDECL(RTSEL) CPUMGetGuestCS(PVMCPU pVCpu)
+{
+ return 0;
+}
+
+VMMDECL(PCCPUMCTXCORE) CPUMGetGuestCtxCore(PVMCPU pVCpu)
+{
+ return NULL;
+}
+
+VMMDECL(uint32_t) CPUMGetGuestEIP(PVMCPU pVCpu)
+{
+ return 0;
+}
+
+VMMDECL(uint64_t) CPUMGetGuestRIP(PVMCPU pVCpu)
+{
+ return 0;
+}
+
+VMMDECL(RTGCPTR) CPUMGetGuestIDTR(PVMCPU pVCpu, uint16_t *pcbLimit)
+{
+ return 0;
+}
+
+VMMDECL(CPUMMODE) CPUMGetGuestMode(PVMCPU pVCpu)
+{
+ return CPUMMODE_INVALID;
+}
+
+VMMDECL(RTSEL) CPUMGetHyperCS(PVMCPU pVCpu)
+{
+ return 0xfff8;
+}
+
+VMMDECL(uint32_t) CPUMGetHyperEIP(PVMCPU pVCpu)
+{
+ return 0;
+}
+
+VMMDECL(PCPUMCTX) CPUMQueryGuestCtxPtr(PVMCPU pVCpu)
+{
+ return NULL;
+}
+
+VMMDECL(bool) CPUMIsGuestIn64BitCode(PVMCPU pVCpu)
+{
+ return false;
+}
+
+VMMDECL(uint32_t) CPUMGetGuestEFlags(PVMCPU pVCpu)
+{
+ return 2;
+}
+
+#include <VBox/vmm/hm.h>
+VMMR3DECL(bool) HMR3IsEnabled(PUVM pUVM)
+{
+ return true;
+}
+
+
+#include <VBox/vmm/nem.h>
+VMMR3DECL(bool) NEMR3IsEnabled(PUVM pUVM)
+{
+ return true;
+}
+
+
+#include <VBox/vmm/pgm.h>
+
+VMMDECL(RTHCPHYS) PGMGetHyperCR3(PVMCPU pVCpu)
+{
+ return 0;
+}
+
+VMMDECL(PGMMODE) PGMGetShadowMode(PVMCPU pVCpu)
+{
+ return PGMMODE_INVALID;
+}
+
+VMMR3DECL(int) PGMR3DbgR3Ptr2GCPhys(PUVM pUVM, RTR3PTR R3Ptr, PRTGCPHYS pGCPhys)
+{
+ return VERR_INTERNAL_ERROR;
+}
+
+VMMR3DECL(int) PGMR3DbgR3Ptr2HCPhys(PUVM pUVM, RTR3PTR R3Ptr, PRTHCPHYS pHCPhys)
+{
+ return VERR_INTERNAL_ERROR;
+}
+VMMR3DECL(int) PGMR3DbgHCPhys2GCPhys(PUVM pUVM, RTHCPHYS HCPhys, PRTGCPHYS pGCPhys)
+{
+ return VERR_INTERNAL_ERROR;
+}
+
+
+#include <VBox/vmm/vmm.h>
+
+VMMR3DECL(PVMCPU) VMMR3GetCpuByIdU(PUVM pUVM, RTCPUID idCpu)
+{
+ return NULL;
+}
+
+
+VMMR3DECL(PVM) VMR3GetVM(PUVM pUVM)
+{
+ return NULL;
+}
+
+VMMR3DECL(VMSTATE) VMR3GetStateU(PUVM pUVM)
+{
+ return VMSTATE_DESTROYING;
+}
diff --git a/src/VBox/Debugger/testcase/tstVBoxDbg.cpp b/src/VBox/Debugger/testcase/tstVBoxDbg.cpp
new file mode 100644
index 00000000..ecf90e97
--- /dev/null
+++ b/src/VBox/Debugger/testcase/tstVBoxDbg.cpp
@@ -0,0 +1,119 @@
+/* $Id: tstVBoxDbg.cpp $ */
+/** @file
+ * VBox Debugger GUI, dummy testcase.
+ */
+
+/*
+ * Copyright (C) 2006-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <qapplication.h>
+#include <VBox/dbggui.h>
+#include <VBox/vmm/vm.h>
+#include <iprt/errcore.h>
+#include <iprt/initterm.h>
+#include <VBox/log.h>
+#include <iprt/assert.h>
+#include <iprt/initterm.h>
+#include <iprt/semaphore.h>
+#include <iprt/stream.h>
+
+
+#define TESTCASE "tstVBoxDbg"
+
+
+int main(int argc, char **argv)
+{
+ int cErrors = 0; /* error count. */
+
+ RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB);
+ RTPrintf(TESTCASE ": TESTING...\n");
+
+ /*
+ * Create empty VM.
+ */
+ PVM pVM;
+ PUVM pUVM;
+ int rc = VMR3Create(1, NULL, NULL, NULL, NULL, NULL, &pVM, &pUVM);
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Instantiate the debugger GUI bits and run them.
+ */
+ QApplication App(argc, argv);
+ PDBGGUI pGui;
+ PCDBGGUIVT pGuiVT;
+ rc = DBGGuiCreateForVM(pUVM, &pGui, &pGuiVT);
+ if (RT_SUCCESS(rc))
+ {
+ if (argc <= 1 || argc == 2)
+ {
+ RTPrintf(TESTCASE ": calling pfnShowCommandLine...\n");
+ rc = pGuiVT->pfnShowCommandLine(pGui);
+ if (RT_FAILURE(rc))
+ {
+ RTPrintf(TESTCASE ": error: pfnShowCommandLine failed! rc=%Rrc\n", rc);
+ cErrors++;
+ }
+ }
+
+ if (argc <= 1 || argc == 3)
+ {
+ RTPrintf(TESTCASE ": calling pfnShowStatistics...\n");
+ pGuiVT->pfnShowStatistics(pGui);
+ if (RT_FAILURE(rc))
+ {
+ RTPrintf(TESTCASE ": error: pfnShowStatistics failed! rc=%Rrc\n", rc);
+ cErrors++;
+ }
+ }
+
+ pGuiVT->pfnAdjustRelativePos(pGui, 0, 0, 640, 480);
+ RTPrintf(TESTCASE ": calling App.exec()...\n");
+ App.exec();
+ }
+ else
+ {
+ RTPrintf(TESTCASE ": error: DBGGuiCreateForVM failed! rc=%Rrc\n", rc);
+ cErrors++;
+ }
+
+ /*
+ * Cleanup.
+ */
+ rc = VMR3Destroy(pUVM);
+ if (!RT_SUCCESS(rc))
+ {
+ RTPrintf(TESTCASE ": error: failed to destroy vm! rc=%Rrc\n", rc);
+ cErrors++;
+ }
+ VMR3ReleaseUVM(pUVM);
+ }
+ else
+ {
+ RTPrintf(TESTCASE ": fatal error: failed to create vm! rc=%Rrc\n", rc);
+ cErrors++;
+ }
+
+ /*
+ * Summary and exit.
+ */
+ if (!cErrors)
+ RTPrintf(TESTCASE ": SUCCESS\n");
+ else
+ RTPrintf(TESTCASE ": FAILURE - %d errors\n", cErrors);
+ return !!cErrors;
+}
+