Index: /trunk/src/VBox/Debugger/DBGCCmdHlp.cpp
===================================================================
--- /trunk/src/VBox/Debugger/DBGCCmdHlp.cpp	(revision 84652)
+++ /trunk/src/VBox/Debugger/DBGCCmdHlp.cpp	(revision 84653)
@@ -219,5 +219,5 @@
     if (cbChars)
     {
-        int rc = pDbgc->pBack->pfnWrite(pDbgc->pBack, pachChars, cbChars, NULL);
+        int rc = pDbgc->pfnOutput(pDbgc->pvOutputUser, pachChars, cbChars);
         if (RT_SUCCESS(rc))
             pDbgc->chLastOutput = pachChars[cbChars - 1];
Index: /trunk/src/VBox/Debugger/DBGCGdbRemoteStub.cpp
===================================================================
--- /trunk/src/VBox/Debugger/DBGCGdbRemoteStub.cpp	(revision 84652)
+++ /trunk/src/VBox/Debugger/DBGCGdbRemoteStub.cpp	(revision 84653)
@@ -126,4 +126,6 @@
     /** Flag whether the stub is in extended mode. */
     bool                        fExtendedMode;
+    /** Flag whether was something was output using the 'O' packet since it was reset last. */
+    bool                        fOutput;
 } GDBSTUBCTX;
 /** Pointer to the GDB stub context data. */
@@ -356,5 +358,5 @@
  * @param   cbSrc               Number of bytes to encode.
  */
-DECLINLINE(int) dbgcGdbStubCtxEncodeBinaryAsHex(uint8_t *pbDst, size_t cbDst, void *pvSrc, size_t cbSrc)
+DECLINLINE(int) dbgcGdbStubCtxEncodeBinaryAsHex(uint8_t *pbDst, size_t cbDst, const void *pvSrc, size_t cbSrc)
 {
     return RTStrPrintHexBytes((char *)pbDst, cbDst, pvSrc, cbSrc, RTSTRPRINTHEXBYTES_F_UPPER);
@@ -1089,43 +1091,4 @@
 
 
-#if 0
-/**
- * Calls the given command handler and processes the reply.
- *
- * @returns Status code.
- * @param   pThis               The GDB stub context.
- * @param   pCmd                The command to call - NULL if using the generic monitor command received callback in the
- *                              interface callback table.
- * @param   pszArgs             Argument string to call the command with.
- */
-static int gdbStubCtxCmdProcess(PGDBSTUBCTXINT pThis, PCGDBSTUBCMD pCmd, const char *pszArgs)
-{
-    int rc = gdbStubCtxReplySendBegin(pThis);
-    if (rc == GDBSTUB_INF_SUCCESS)
-    {
-        gdbStubOutCtxReset(&pThis->OutCtx);
-        int rcCmd = GDBSTUB_INF_SUCCESS;
-        if (pCmd)
-            rcCmd = pCmd->pfnCmd(pThis, &pThis->OutCtx.Hlp, pszArgs, pThis->pvUser);
-        else
-            rcCmd = pThis->pIf->pfnMonCmd(pThis, &pThis->OutCtx.Hlp, pszArgs, pThis->pvUser);
-        if (rcCmd == GDBSTUB_INF_SUCCESS)
-        {
-            if (!pThis->OutCtx.offScratch) /* No output, just send OK reply. */
-                rc = gdbStubCtxReplySendOkData(pThis);
-            else
-                rc = gdbStubCtxReplySendData(pThis, &pThis->OutCtx.abScratch[0], pThis->OutCtx.offScratch);
-
-            /* Try to finish the reply in case of an error anyway (but we might be completely screwed at this point anyway). */
-            gdbStubCtxReplySendEnd(pThis);
-        }
-        else
-            rc = gdbStubCtxReplySendErrStsData(pThis, rcCmd);
-    }
-
-    return rc;
-}
-
-
 /**
  * Processes the 'Rcmd' query.
@@ -1136,15 +1099,10 @@
  * @param   cbArgs              Size of arguments in bytes.
  */
-static int gdbStubCtxPktProcessQueryRcmd(PGDBSTUBCTXINT pThis, const uint8_t *pbArgs, size_t cbArgs)
-{
-    int rc = GDBSTUB_INF_SUCCESS;
-
+static int dbgcGdbStubCtxPktProcessQueryRcmd(PGDBSTUBCTX pThis, const uint8_t *pbArgs, size_t cbArgs)
+{
     /* Skip the , following the qRcmd start. */
     if (   cbArgs < 1
         || pbArgs[0] != ',')
-        return GDBSTUB_ERR_PROTOCOL_VIOLATION;
-
-    if (!pThis->pIf->paCmds)
-        return GDBSTUB_ERR_NOT_FOUND;
+        return VERR_NET_PROTOCOL_ERROR;
 
     cbArgs--;
@@ -1153,55 +1111,29 @@
     /* Decode the command. */
     /** @todo Make this dynamic. */
-    char szCmd[4096];
+    char szCmd[_4K];
+    RT_ZERO(szCmd);
+
     if (cbArgs / 2 >= sizeof(szCmd))
-        return GDBSTUB_ERR_BUFFER_OVERFLOW;
+        return VERR_NET_PROTOCOL_ERROR;
 
     size_t cbDecoded = 0;
-    rc = gdbStubCtxParseHexStringAsByteBuf(pbArgs, cbArgs - 1, &szCmd[0], sizeof(szCmd), &cbDecoded);
-    if (rc == GDBSTUB_INF_SUCCESS)
-    {
-        const char *pszArgs = NULL;
-
-        cbDecoded /= 2;
+    int rc = RTStrConvertHexBytesEx((const char *)pbArgs, &szCmd[0], sizeof(szCmd), 0 /*fFlags*/,
+                                    NULL /* ppszNext */, &cbDecoded);
+    if (rc == VWRN_TRAILING_CHARS)
+        rc = VINF_SUCCESS;
+    if (RT_SUCCESS(rc))
+    {
         szCmd[cbDecoded] = '\0'; /* Ensure zero termination. */
 
-        /** @todo Sanitize string. */
-
-        /* Look for the first space and take that as the separator between command identifier. */
-        uint8_t *pbDelim = gdbStubCtxMemchr(&szCmd[0], ' ', cbDecoded);
-        if (pbDelim)
-        {
-            *pbDelim = '\0';
-            pszArgs = pbDelim + 1;
-        }
-
-        /* Search for the command. */
-        PCGDBSTUBCMD pCmd = &pThis->pIf->paCmds[0];
-        rc = GDBSTUB_ERR_NOT_FOUND;
-        while (pCmd->pszCmd)
-        {
-            if (!gdbStubStrcmp(pCmd->pszCmd, &szCmd[0]))
-            {
-                rc = gdbStubCtxCmdProcess(pThis, pCmd, pszArgs);
-                break;
-            }
-            pCmd++;
-        }
-
-        if (   rc == GDBSTUB_ERR_NOT_FOUND
-            && pThis->pIf->pfnMonCmd)
-        {
-            /* Restore delimiter. */
-            if (pbDelim)
-                *pbDelim = ' ';
-            rc = gdbStubCtxCmdProcess(pThis, NULL, &szCmd[0]);
-        }
-        else
-            rc = gdbStubCtxReplySendErrSts(pThis, rc); /** @todo Send string. */
+        pThis->fOutput = false;
+        rc = dbgcEvalCommand(&pThis->Dbgc, &szCmd[0], cbDecoded, false /*fNoExecute*/);
+        dbgcGdbStubCtxReplySendOk(pThis);
+        if (   rc != VERR_DBGC_QUIT
+            && rc != VWRN_DBGC_CMD_PENDING)
+            rc = VINF_SUCCESS; /* ignore other statuses */
     }
 
     return rc;
 }
-#endif
 
 
@@ -1215,5 +1147,5 @@
     GDBSTUBQPKTPROC_INIT("Supported",          dbgcGdbStubCtxPktProcessQuerySupported),
     GDBSTUBQPKTPROC_INIT("Xfer:features:read", dbgcGdbStubCtxPktProcessQueryXferFeatRead),
-    //GDBSTUBQPKTPROC_INIT("Rcmd",               dbgcGdbStubCtxPktProcessQueryRcmd),
+    GDBSTUBQPKTPROC_INIT("Rcmd",               dbgcGdbStubCtxPktProcessQueryRcmd),
 #undef GDBSTUBQPKTPROC_INIT
 };
@@ -1981,4 +1913,5 @@
      * Process the event.
      */
+    PDBGC pDbgc = &pThis->Dbgc;
     pThis->Dbgc.pszScratch = &pThis->Dbgc.achInput[0];
     pThis->Dbgc.iArg       = 0;
@@ -1996,5 +1929,4 @@
 
 
-#if 0
         /*
          * The second part is events which can occur at any time.
@@ -2008,5 +1940,4 @@
             break;
         }
-#endif
 
         case DBGFEVENT_BREAKPOINT:
@@ -2026,5 +1957,4 @@
         }
 
-#if 0
         case DBGFEVENT_ASSERTION_HYPER:
         {
@@ -2069,5 +1999,4 @@
             break;
         }
-#endif
 
         case DBGFEVENT_POWERING_OFF:
@@ -2236,4 +2165,44 @@
 
 /**
+ * @copdoc{DBGC,pfnOutput}
+ */
+static DECLCALLBACK(int) dbgcOutputGdb(void *pvUser, const char *pachChars, size_t cbChars)
+{
+    PGDBSTUBCTX pThis = (PGDBSTUBCTX)pvUser;
+
+    pThis->fOutput = true;
+    int rc = dbgcGdbStubCtxReplySendBegin(pThis);
+    if (RT_SUCCESS(rc))
+    {
+        uint8_t chConOut = 'O';
+        rc = dbgcGdbStubCtxReplySendData(pThis, &chConOut, sizeof(chConOut));
+        if (RT_SUCCESS(rc))
+        {
+            /* Convert the characters to hex. */
+            const char *pachCur = pachChars;
+
+            while (   cbChars
+                   && RT_SUCCESS(rc))
+            {
+                uint8_t achHex[512 + 1];
+                size_t cbThisSend = RT_MIN((sizeof(achHex) - 1) / 2, cbChars); /* Each character needs two bytes. */
+
+                rc = dbgcGdbStubCtxEncodeBinaryAsHex(&achHex[0], cbThisSend * 2 + 1, pachCur, cbThisSend);
+                if (RT_SUCCESS(rc))
+                    rc = dbgcGdbStubCtxReplySendData(pThis, &achHex[0], cbThisSend * 2);
+
+                pachCur += cbThisSend;
+                cbChars -= cbThisSend;
+            }
+        }
+
+        dbgcGdbStubCtxReplySendEnd(pThis);
+    }
+
+    return rc;
+}
+
+
+/**
  * Creates a GDB stub context instance with the given backend.
  *
@@ -2264,4 +2233,6 @@
      */
     pThis->Dbgc.pBack            = pBack;
+    pThis->Dbgc.pfnOutput        = dbgcOutputGdb;
+    pThis->Dbgc.pvOutputUser     = pThis;
     pThis->Dbgc.pVM              = NULL;
     pThis->Dbgc.pUVM             = NULL;
@@ -2317,4 +2288,5 @@
     pThis->cbTgtXmlDesc    = 0;
     pThis->fExtendedMode   = false;
+    pThis->fOutput         = false;
     dbgcGdbStubCtxReset(pThis);
 
@@ -2385,4 +2357,7 @@
             pThis->Dbgc.pUVM  = pUVM;
             pThis->Dbgc.idCpu = 0;
+            rc = pThis->Dbgc.CmdHlp.pfnPrintf(&pThis->Dbgc.CmdHlp, NULL,
+                                              "Current VM is %08x, CPU #%u\n" /** @todo get and print the VM name! */
+                                              , pThis->Dbgc.pVM, pThis->Dbgc.idCpu);
         }
         else
Index: /trunk/src/VBox/Debugger/DBGCInternal.h
===================================================================
--- /trunk/src/VBox/Debugger/DBGCInternal.h	(revision 84652)
+++ /trunk/src/VBox/Debugger/DBGCInternal.h	(revision 84653)
@@ -116,4 +116,16 @@
     /** Pointer to backend callback structure. */
     PDBGCBACK           pBack;
+
+    /**
+     * Output a bunch of characters.
+     *
+     * @returns VBox status code.
+     * @param   pvUser      Opaque user data from DBGC::pvOutputUser.
+     * @param   pachChars   Pointer to an array of utf-8 characters.
+     * @param   cbChars     Number of bytes in the character array pointed to by pachChars.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnOutput, (void *pvUser, const char *pachChars, size_t cbChars));
+    /** Opqaue user data passed to DBGC::pfnOutput. */
+    void                *pvOutputUser;
 
     /** Pointer to the current VM. */
@@ -587,4 +599,5 @@
 void    dbgcDestroy(PDBGC pDbgc);
 
+const char *dbgcGetEventCtx(DBGFEVENTCTX enmCtx);
 
 DECLHIDDEN(int) dbgcGdbStubCreate(PUVM pUVM, PDBGCBACK pBack, unsigned fFlags);
Index: /trunk/src/VBox/Debugger/DBGConsole.cpp
===================================================================
--- /trunk/src/VBox/Debugger/DBGConsole.cpp	(revision 84652)
+++ /trunk/src/VBox/Debugger/DBGConsole.cpp	(revision 84653)
@@ -588,5 +588,5 @@
  * @param   enmCtx          The context.
  */
-static const char *dbgcGetEventCtx(DBGFEVENTCTX enmCtx)
+const char *dbgcGetEventCtx(DBGFEVENTCTX enmCtx)
 {
     switch (enmCtx)
@@ -1089,4 +1089,13 @@
 
 
+/**
+ * @copdoc{DBGC,pfnOutput}
+ */
+static DECLCALLBACK(int) dbgcOutputNative(void *pvUser, const char *pachChars, size_t cbChars)
+{
+    PDBGC pDbgc = (PDBGC)pvUser;
+    return pDbgc->pBack->pfnWrite(pDbgc->pBack, pachChars, cbChars, NULL /*pcbWritten*/);
+}
+
 
 /**
@@ -1115,4 +1124,6 @@
     dbgcInitCmdHlp(pDbgc);
     pDbgc->pBack            = pBack;
+    pDbgc->pfnOutput        = dbgcOutputNative;
+    pDbgc->pvOutputUser     = pDbgc;
     pDbgc->pVM              = NULL;
     pDbgc->pUVM             = NULL;
