Index: /trunk/include/VBox/dbg.h
===================================================================
--- /trunk/include/VBox/dbg.h	(revision 64720)
+++ /trunk/include/VBox/dbg.h	(revision 64721)
@@ -686,5 +686,5 @@
 
 
-#ifdef IN_RING3
+#if defined(IN_RING3) || defined(IN_SLICKEDIT)
 
 /**
Index: /trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp
===================================================================
--- /trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp	(revision 64720)
+++ /trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp	(revision 64721)
@@ -65,4 +65,5 @@
 static FNDBGCCMD dbgcCmdEditMem;
 static FNDBGCCMD dbgcCmdGo;
+static FNDBGCCMD dbgcCmdGoUp;
 static FNDBGCCMD dbgcCmdListModules;
 static FNDBGCCMD dbgcCmdListNear;
@@ -75,9 +76,11 @@
 static FNDBGCCMD dbgcCmdSearchMem;
 static FNDBGCCMD dbgcCmdSearchMemType;
+static FNDBGCCMD dbgcCmdStepTrace;
+static FNDBGCCMD dbgcCmdStepTraceTo;
+static FNDBGCCMD dbgcCmdStepTraceToggle;
 static FNDBGCCMD dbgcCmdEventCtrl;
 static FNDBGCCMD dbgcCmdEventCtrlList;
 static FNDBGCCMD dbgcCmdEventCtrlReset;
 static FNDBGCCMD dbgcCmdStack;
-static FNDBGCCMD dbgcCmdTrace;
 static FNDBGCCMD dbgcCmdUnassemble;
 static FNDBGCCMD dbgcCmdUnassembleCfg;
@@ -266,4 +269,22 @@
     /* cTimesMin,   cTimesMax,  enmCategory,            fFlags,                         pszName,        pszDescription */
     {  1,           1,          DBGCVAR_CAT_POINTER,    0,                              "address",      "Pointer to obtain info about." },
+};
+
+
+/** 'p', 'pc', 'pt', 't', 'tc' and 'tt' arguments. */
+static const DBGCVARDESC    g_aArgStepTrace[] =
+{
+    /* cTimesMin,   cTimesMax,  enmCategory,            fFlags,                         pszName,        pszDescription */
+    {  0,           1,          DBGCVAR_CAT_NUMBER,     0,                              "count",        "Number of instructions or source lines to step." },
+    {  0,           1,          DBGCVAR_CAT_STRING,     0,                              "cmds",         "String of commands to be executed afterwards. Quote it!" },
+};
+
+
+/** 'pa' and 'ta' arguments. */
+static const DBGCVARDESC    g_aArgStepTraceTo[] =
+{
+    /* cTimesMin,   cTimesMax,  enmCategory,            fFlags,                         pszName,        pszDescription */
+    {  1,           1,          DBGCVAR_CAT_POINTER,    0,                              "address",      "Where to stop" },
+    {  0,           1,          DBGCVAR_CAT_STRING,     0,                              "cmds",         "String of commands to be executed afterwards. Quote it!" },
 };
 
@@ -390,4 +411,5 @@
     { "eq",         2,        2,        &g_aArgEditMem[0],  RT_ELEMENTS(g_aArgEditMem),     0,       dbgcCmdEditMem,     "<addr> <value>",       "Write a 8-byte value to memory." },
     { "g",          0,        0,        NULL,               0,                              0,       dbgcCmdGo,          "",                     "Continue execution." },
+    { "gu",         0,        0,        NULL,               0,                              0,       dbgcCmdGoUp,        "",                     "Go up - continue execution till after return." },
     { "k",          0,        0,        NULL,               0,                              0,       dbgcCmdStack,       "",                     "Callstack." },
     { "kg",         0,        0,        NULL,               0,                              0,       dbgcCmdStack,       "",                     "Callstack - guest." },
@@ -400,4 +422,9 @@
     { "ls",         0,        1,        &g_aArgListSource[0],RT_ELEMENTS(g_aArgListSource), 0,       dbgcCmdListSource,  "[addr]",               "Source." },
     { "m",          1,        1,        &g_aArgMemoryInfo[0],RT_ELEMENTS(g_aArgMemoryInfo), 0,       dbgcCmdMemoryInfo,  "<addr>",               "Display information about that piece of memory." },
+    { "p",          0,        2,        &g_aArgStepTrace[0], RT_ELEMENTS(g_aArgStepTrace),  0,       dbgcCmdStepTrace,   "[count] [cmds]",       "Step over." },
+    { "pr",         0,        0,        NULL,               0,                              0,       dbgcCmdStepTraceToggle, "",                 "Toggle displaying registers for tracing & stepping (no code executed)." },
+    { "pa",         1,        1,        &g_aArgStepTraceTo[0], RT_ELEMENTS(g_aArgStepTraceTo), 0,    dbgcCmdStepTraceTo, "<addr> [count] [cmds]","Step to the given address." },
+    { "pc",         0,        0,        &g_aArgStepTrace[0], RT_ELEMENTS(g_aArgStepTrace),  0,       dbgcCmdStepTrace,   "[count] [cmds]",       "Step to the next call instruction." },
+    { "pt",         0,        0,        &g_aArgStepTrace[0], RT_ELEMENTS(g_aArgStepTrace),  0,       dbgcCmdStepTrace,   "[count] [cmds]",       "Step to the next return instruction." },
     { "r",          0,        3,        &g_aArgReg[0],      RT_ELEMENTS(g_aArgReg),         0,       dbgcCmdReg,         "[reg [[=] newval]]",   "Show or set register(s) - active reg set." },
     { "rg",         0,        3,        &g_aArgReg[0],      RT_ELEMENTS(g_aArgReg),         0,       dbgcCmdRegGuest,    "[reg [[=] newval]]",   "Show or set register(s) - guest reg set." },
@@ -419,5 +446,9 @@
     { "sxi",        1,       ~0U,       &g_aArgEventCtrl[0], RT_ELEMENTS(g_aArgEventCtrl),  0,       dbgcCmdEventCtrl,      "[-c <cmd>] <event> [..]", "Ignore: Ignore the specified exceptions, exits and other events ('all' = all of them).  Without the -c option, the guest runs like normal." },
     { "sxr",        0,        0,        &g_aArgEventCtrlOpt[0], RT_ELEMENTS(g_aArgEventCtrlOpt), 0,  dbgcCmdEventCtrlReset, "",                    "Reset the settings to default for exceptions, exits and other events. All if no filter is specified." },
-    { "t",          0,        0,        NULL,               0,                              0,       dbgcCmdTrace,       "",                     "Instruction trace (step into)." },
+    { "t",          0,        2,        &g_aArgStepTrace[0], RT_ELEMENTS(g_aArgStepTrace),  0,       dbgcCmdStepTrace,   "[count] [cmds]",       "Trace ." },
+    { "tr",         0,        0,        NULL,               0,                              0,       dbgcCmdStepTraceToggle, "",                 "Toggle displaying registers for tracing & stepping (no code executed)." },
+    { "ta",         1,        1,        &g_aArgStepTraceTo[0], RT_ELEMENTS(g_aArgStepTraceTo), 0,    dbgcCmdStepTraceTo, "<addr> [count] [cmds]","Trace to the given address." },
+    { "tc",         0,        0,        &g_aArgStepTrace[0], RT_ELEMENTS(g_aArgStepTrace),  0,       dbgcCmdStepTrace,   "[count] [cmds]",       "Trace to the next call instruction." },
+    { "tt",         0,        0,        &g_aArgStepTrace[0], RT_ELEMENTS(g_aArgStepTrace),  0,       dbgcCmdStepTrace,   "[count] [cmds]",       "Trace to the next return instruction." },
     { "u",          0,        1,        &g_aArgUnassemble[0],RT_ELEMENTS(g_aArgUnassemble), 0,       dbgcCmdUnassemble,  "[addr]",               "Unassemble." },
     { "u64",        0,        1,        &g_aArgUnassemble[0],RT_ELEMENTS(g_aArgUnassemble), 0,       dbgcCmdUnassemble,  "[addr]",               "Unassemble 64-bit code." },
@@ -595,5 +626,5 @@
 
 /**
- * @callback_method_impl{FNDBGCCMD, The 'go' command.}
+ * @callback_method_impl{FNDBGCCMD, The 'g' command.}
  */
 static DECLCALLBACK(int) dbgcCmdGo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR paArgs, unsigned cArgs)
@@ -613,4 +644,24 @@
     NOREF(paArgs); NOREF(cArgs);
     return VINF_SUCCESS;
+}
+
+
+/**
+ * @callback_method_impl{FNDBGCCMD, The 'gu' command.}
+ */
+static DECLCALLBACK(int) dbgcCmdGoUp(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR paArgs, unsigned cArgs)
+{
+    PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
+    RT_NOREF(pCmd, paArgs, cArgs);
+
+    /* The simple way out. */
+    PDBGFADDRESS pStackPop  = NULL; /** @todo try set up some stack limitations */
+    RTGCPTR      cbStackPop = 0;
+    int rc = DBGFR3StepEx(pUVM, pDbgc->idCpu, DBGF_STEP_F_OVER | DBGF_STEP_F_STOP_AFTER_RET, NULL, pStackPop, cbStackPop, _512K);
+    if (RT_SUCCESS(rc))
+        pDbgc->fReady = false;
+    else
+        return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGFR3StepEx(,,DBGF_STEP_F_OVER | DBGF_STEP_F_STOP_AFTER_RET,) failed");
+    return rc;
 }
 
@@ -2483,5 +2534,5 @@
          * Disassemble one instruction at cs:[r|e]ip.
          */
-        if (!f64BitMode && strstr(pszRegs, " vm ")) /* a big ugly... */
+        if (!f64BitMode && strstr(pszRegs, " vm ")) /* a bit ugly... */
             return pCmdHlp->pfnExec(pCmdHlp, "uv86 %s", szDisAndRegs + 2);
         return pCmdHlp->pfnExec(pCmdHlp, "%s", szDisAndRegs);
@@ -2555,17 +2606,84 @@
 
 /**
- * @callback_method_impl{FNDBGCCMD, The 't' command.}
- */
-static DECLCALLBACK(int) dbgcCmdTrace(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR paArgs, unsigned cArgs)
+ * @callback_method_impl{FNDBGCCMD, The 'pr' and 'tr' commands.}
+ */
+static DECLCALLBACK(int) dbgcCmdStepTraceToggle(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR paArgs, unsigned cArgs)
+{
+    PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
+    Assert(cArgs == 0); NOREF(pCmd); NOREF(pUVM); NOREF(paArgs); NOREF(cArgs);
+
+    /* Note! windbg accepts 'r' as a flag to 'p', 'pa', 'pc', 'pt', 't',
+             'ta', 'tc' and 'tt'.  We've simplified it.  */
+    pDbgc->fStepTraceRegs = !pDbgc->fStepTraceRegs;
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * @callback_method_impl{FNDBGCCMD,
+ *      The 'p', 'pc', 'pt', 't', 'tc', and 'tt' commands.}
+ */
+static DECLCALLBACK(int) dbgcCmdStepTrace(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR paArgs, unsigned cArgs)
 {
     PDBGC   pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
-
-    int rc = DBGFR3Step(pUVM, pDbgc->idCpu);
+    if (cArgs != 0)
+        return DBGCCmdHlpFail(pCmdHlp, pCmd,
+                              "Sorry, but the '%s' command does not currently implement any arguments.\n", pCmd->pszCmd);
+
+    /* The 'count' has to be implemented by DBGC, whereas the
+       filtering is taken care of by DBGF. */
+
+    /*
+     * Convert the command to DBGF_STEP_F_XXX and other API input.
+     */
+    //DBGFADDRESS StackPop;
+    PDBGFADDRESS pStackPop  = NULL;
+    RTGCPTR      cbStackPop = 0;
+    uint32_t     cMaxSteps  = pCmd->pszCmd[0] == 'p' ? _512K : _64K;
+    uint32_t     fFlags     = pCmd->pszCmd[0] == 'p' ? DBGF_STEP_F_OVER : DBGF_STEP_F_INTO;
+    if (pCmd->pszCmd[1] == 'c')
+        fFlags |= DBGF_STEP_F_STOP_ON_CALL;
+    else if (pCmd->pszCmd[1] == 't')
+        fFlags |= DBGF_STEP_F_STOP_ON_RET;
+    else if (pCmd->pszCmd[0] != 'p')
+        cMaxSteps = 1;
+    else
+    {
+        /** @todo consider passing RSP + 1 in for 'p' and something else sensible for
+         *        the 'pt' command. */
+    }
+
+    int rc = DBGFR3StepEx(pUVM, pDbgc->idCpu, fFlags, NULL, pStackPop, cbStackPop, cMaxSteps);
     if (RT_SUCCESS(rc))
         pDbgc->fReady = false;
     else
-        rc = pDbgc->CmdHlp.pfnVBoxError(&pDbgc->CmdHlp, rc, "When trying to single step VM %p\n", pDbgc->pVM);
+        return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGFR3StepEx(,,%#x,) failed", fFlags);
 
     NOREF(pCmd); NOREF(paArgs); NOREF(cArgs);
+    return rc;
+}
+
+
+/**
+ * @callback_method_impl{FNDBGCCMD, The 'pa' and 'ta' commands.}
+ */
+static DECLCALLBACK(int) dbgcCmdStepTraceTo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR paArgs, unsigned cArgs)
+{
+    PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
+    if (cArgs != 1)
+        return DBGCCmdHlpFail(pCmdHlp, pCmd,
+                              "Sorry, but the '%s' command only implements a single argument at present.\n", pCmd->pszCmd);
+    DBGFADDRESS Address;
+    int rc = pCmdHlp->pfnVarToDbgfAddr(pCmdHlp, &paArgs[0], &Address);
+    if (RT_FAILURE(rc))
+        return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "VarToDbgfAddr(,%Dv,)\n", &paArgs[0]);
+
+    uint32_t cMaxSteps = pCmd->pszCmd[0] == 'p' ? _512K : 1;
+    uint32_t fFlags    = pCmd->pszCmd[0] == 'p' ? DBGF_STEP_F_OVER : DBGF_STEP_F_INTO;
+    rc = DBGFR3StepEx(pUVM, pDbgc->idCpu, fFlags, &Address, NULL, 0, cMaxSteps);
+    if (RT_SUCCESS(rc))
+        pDbgc->fReady = false;
+    else
+        return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGFR3StepEx(,,%#x,) failed", fFlags);
     return rc;
 }
Index: /trunk/src/VBox/Debugger/DBGCInternal.h
===================================================================
--- /trunk/src/VBox/Debugger/DBGCInternal.h	(revision 64720)
+++ /trunk/src/VBox/Debugger/DBGCInternal.h	(revision 64721)
@@ -140,4 +140,6 @@
     /** Indicates whether the register are terse or sparse. */
     bool                fRegTerse;
+    /** Whether to display registers when tracing. */
+    bool                fStepTraceRegs;
     /** Counter use to suppress the printing of the headers. */
     uint8_t             cPagingHierarchyDumps;
Index: /trunk/src/VBox/Debugger/DBGConsole.cpp
===================================================================
--- /trunk/src/VBox/Debugger/DBGConsole.cpp	(revision 64720)
+++ /trunk/src/VBox/Debugger/DBGConsole.cpp	(revision 64721)
@@ -718,5 +718,23 @@
             rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "\ndbgf event: Single step! (%s)\n", dbgcGetEventCtx(pEvent->enmCtx));
             if (RT_SUCCESS(rc))
-                rc = pDbgc->CmdHlp.pfnExec(&pDbgc->CmdHlp, "r");
+            {
+                if (pDbgc->fStepTraceRegs)
+                    rc = pDbgc->CmdHlp.pfnExec(&pDbgc->CmdHlp, "r");
+                else
+                {
+                    char szCmd[80];
+                    if (!pDbgc->fRegCtxGuest)
+                        rc = DBGFR3RegPrintf(pDbgc->pUVM, pDbgc->idCpu | DBGFREG_HYPER_VMCPUID, szCmd, sizeof(szCmd),
+                                             "u %VR{cs}:%VR{eip} L 0");
+                    else if (DBGFR3CpuIsIn64BitCode(pDbgc->pUVM, pDbgc->idCpu))
+                        rc = DBGFR3RegPrintf(pDbgc->pUVM, pDbgc->idCpu, szCmd, sizeof(szCmd), "u %016VR{rip} L 0");
+                    else if (DBGFR3CpuIsInV86Code(pDbgc->pUVM, pDbgc->idCpu))
+                        rc = DBGFR3RegPrintf(pDbgc->pUVM, pDbgc->idCpu, szCmd, sizeof(szCmd), "uv86 %04VR{cs}:%08VR{eip} L 0");
+                    else
+                        rc = DBGFR3RegPrintf(pDbgc->pUVM, pDbgc->idCpu, szCmd, sizeof(szCmd), "u %04VR{cs}:%08VR{eip} L 0");
+                    if (RT_SUCCESS(rc))
+                        rc = pDbgc->CmdHlp.pfnExec(&pDbgc->CmdHlp, "%s", szCmd);
+                }
+            }
             break;
         }
@@ -1078,4 +1096,5 @@
     pDbgc->fRegCtxGuest     = true;
     pDbgc->fRegTerse        = true;
+    pDbgc->fStepTraceRegs   = true;
     //pDbgc->cPagingHierarchyDumps = 0;
     //pDbgc->DisasmPos        = {0};
Index: /trunk/src/VBox/Debugger/VBoxDbgConsole.cpp
===================================================================
--- /trunk/src/VBox/Debugger/VBoxDbgConsole.cpp	(revision 64720)
+++ /trunk/src/VBox/Debugger/VBoxDbgConsole.cpp	(revision 64721)
@@ -833,7 +833,19 @@
             break;
 
+        case Qt::Key_F8:
+            if (pEvent->modifiers() == 0)
+                commandSubmitted("t");
+            break;
+
+        case Qt::Key_F10:
+            if (pEvent->modifiers() == 0)
+                commandSubmitted("p");
+            break;
+
         case Qt::Key_F11:
             if (pEvent->modifiers() == 0)
                 commandSubmitted("t");
+            else if (pEvent->modifiers() == Qt::ShiftModifier)
+                commandSubmitted("gu");
             break;
 
Index: /trunk/src/VBox/Debugger/testcase/tstDBGCStubs.cpp
===================================================================
--- /trunk/src/VBox/Debugger/testcase/tstDBGCStubs.cpp	(revision 64720)
+++ /trunk/src/VBox/Debugger/testcase/tstDBGCStubs.cpp	(revision 64721)
@@ -176,5 +176,6 @@
 {
 }
-VMMR3DECL(int) DBGFR3Step(PUVM pUVM, VMCPUID idCpu)
+VMMR3DECL(int) DBGFR3StepEx(PUVM pUVM, VMCPUID idCpu, uint32_t fFlags, PCDBGFADDRESS pStopPcAddr,
+                            PCDBGFADDRESS pStopPopAddr, RTGCUINTPTR cbStopPop, uint32_t cMaxSteps)
 {
     return VERR_INTERNAL_ERROR;
@@ -325,4 +326,8 @@
     return false;
 }
+VMMR3DECL(bool) DBGFR3CpuIsInV86Code(PUVM pUVM, VMCPUID idCpu)
+{
+    return false;
+}
 
 VMMR3DECL(int) DBGFR3CoreWrite(PUVM pUVM, const char *pszFilename, bool fReplaceFile)
