Index: trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp
===================================================================
--- trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp	(revision 73457)
+++ trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp	(revision 73460)
@@ -2853,19 +2853,23 @@
              * Display verbose frame info.
              */
-            const char *pszRetType;
+            const char *pszRetType = "invalid";
             switch (pFrame->enmReturnType)
             {
-                case DBGFRETURNTYPE_NEAR16:         pszRetType = "retn/16"; break;
-                case DBGFRETURNTYPE_NEAR32:         pszRetType = "retn/32"; break;
-                case DBGFRETURNTYPE_NEAR64:         pszRetType = "retn/64"; break;
-                case DBGFRETURNTYPE_FAR16:          pszRetType = "retf/16"; break;
-                case DBGFRETURNTYPE_FAR32:          pszRetType = "retf/32"; break;
-                case DBGFRETURNTYPE_FAR64:          pszRetType = "retf/64"; break;
-                case DBGFRETURNTYPE_IRET16:         pszRetType = "iret-16"; break;
-                case DBGFRETURNTYPE_IRET32:         pszRetType = "iret/32s"; break;
-                case DBGFRETURNTYPE_IRET32_PRIV:    pszRetType = "iret/32p"; break;
-                case DBGFRETURNTYPE_IRET32_V86:     pszRetType = "iret/v86"; break;
-                case DBGFRETURNTYPE_IRET64:         pszRetType = "iret/64"; break;
-                default:                            pszRetType = "invalid"; break;
+                case RTDBGRETURNTYPE_NEAR16:        pszRetType = "retn/16"; break;
+                case RTDBGRETURNTYPE_NEAR32:        pszRetType = "retn/32"; break;
+                case RTDBGRETURNTYPE_NEAR64:        pszRetType = "retn/64"; break;
+                case RTDBGRETURNTYPE_FAR16:         pszRetType = "retf/16"; break;
+                case RTDBGRETURNTYPE_FAR32:         pszRetType = "retf/32"; break;
+                case RTDBGRETURNTYPE_FAR64:         pszRetType = "retf/64"; break;
+                case RTDBGRETURNTYPE_IRET16:        pszRetType = "iret-16"; break;
+                case RTDBGRETURNTYPE_IRET32:        pszRetType = "iret/32s"; break;
+                case RTDBGRETURNTYPE_IRET32_PRIV:   pszRetType = "iret/32p"; break;
+                case RTDBGRETURNTYPE_IRET32_V86:    pszRetType = "iret/v86"; break;
+                case RTDBGRETURNTYPE_IRET64:        pszRetType = "iret/64"; break;
+
+                case RTDBGRETURNTYPE_END:
+                case RTDBGRETURNTYPE_INVALID:
+                case RTDBGRETURNTYPE_32BIT_HACK:
+                    break;
             }
             size_t cchLine = DBGCCmdHlpPrintfLen(pCmdHlp, "   %s", pszRetType);
@@ -2878,4 +2882,6 @@
             if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_MAX_DEPTH)
                 cchLine += DBGCCmdHlpPrintfLen(pCmdHlp, " max-depth");
+            if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_TRAP_FRAME)
+                cchLine += DBGCCmdHlpPrintfLen(pCmdHlp, " trap-frame");
 
             if (pFrame->cSureRegs > 0)
Index: trunk/src/VBox/Debugger/DBGPlugInDarwin.cpp
===================================================================
--- trunk/src/VBox/Debugger/DBGPlugInDarwin.cpp	(revision 73457)
+++ trunk/src/VBox/Debugger/DBGPlugInDarwin.cpp	(revision 73460)
@@ -129,4 +129,5 @@
 *********************************************************************************************************************************/
 static DECLCALLBACK(int)  dbgDiggerDarwinInit(PUVM pUVM, void *pvData);
+
 
 
@@ -304,4 +305,16 @@
 
 /**
+ * @copydoc DBGFOSREG::pfnStackUnwindAssist
+ */
+static DECLCALLBACK(int) dbgDiggerDarwinStackUnwindAssist(PUVM pUVM, void *pvData, VMCPUID idCpu, PDBGFSTACKFRAME pFrame,
+                                                          PRTDBGUNWINDSTATE pState, PCCPUMCTX pInitialCtx, RTDBGAS hAs,
+                                                          uint64_t *puScratch)
+{
+    RT_NOREF(pUVM, pvData, idCpu, pFrame, pState, pInitialCtx, hAs, puScratch);
+    return VINF_SUCCESS;
+}
+
+
+/**
  * @copydoc DBGFOSREG::pfnQueryInterface
  */
@@ -972,17 +985,18 @@
 const DBGFOSREG g_DBGDiggerDarwin =
 {
-    /* .u32Magic = */           DBGFOSREG_MAGIC,
-    /* .fFlags = */             0,
-    /* .cbData = */             sizeof(DBGDIGGERDARWIN),
-    /* .szName = */             "Darwin",
-    /* .pfnConstruct = */       dbgDiggerDarwinConstruct,
-    /* .pfnDestruct = */        dbgDiggerDarwinDestruct,
-    /* .pfnProbe = */           dbgDiggerDarwinProbe,
-    /* .pfnInit = */            dbgDiggerDarwinInit,
-    /* .pfnRefresh = */         dbgDiggerDarwinRefresh,
-    /* .pfnTerm = */            dbgDiggerDarwinTerm,
-    /* .pfnQueryVersion = */    dbgDiggerDarwinQueryVersion,
-    /* .pfnQueryInterface = */  dbgDiggerDarwinQueryInterface,
-    /* .u32EndMagic = */        DBGFOSREG_MAGIC
+    /* .u32Magic = */               DBGFOSREG_MAGIC,
+    /* .fFlags = */                 0,
+    /* .cbData = */                 sizeof(DBGDIGGERDARWIN),
+    /* .szName = */                 "Darwin",
+    /* .pfnConstruct = */           dbgDiggerDarwinConstruct,
+    /* .pfnDestruct = */            dbgDiggerDarwinDestruct,
+    /* .pfnProbe = */               dbgDiggerDarwinProbe,
+    /* .pfnInit = */                dbgDiggerDarwinInit,
+    /* .pfnRefresh = */             dbgDiggerDarwinRefresh,
+    /* .pfnTerm = */                dbgDiggerDarwinTerm,
+    /* .pfnQueryVersion = */        dbgDiggerDarwinQueryVersion,
+    /* .pfnQueryInterface = */      dbgDiggerDarwinQueryInterface,
+    /* .pfnStackUnwindAssist = */   dbgDiggerDarwinStackUnwindAssist,
+    /* .u32EndMagic = */            DBGFOSREG_MAGIC
 };
 
Index: trunk/src/VBox/Debugger/DBGPlugInFreeBsd.cpp
===================================================================
--- trunk/src/VBox/Debugger/DBGPlugInFreeBsd.cpp	(revision 73457)
+++ trunk/src/VBox/Debugger/DBGPlugInFreeBsd.cpp	(revision 73460)
@@ -585,4 +585,16 @@
 
 /**
+ * @copydoc DBGFOSREG::pfnStackUnwindAssist
+ */
+static DECLCALLBACK(int) dbgDiggerFreeBsdStackUnwindAssist(PUVM pUVM, void *pvData, VMCPUID idCpu, PDBGFSTACKFRAME pFrame,
+                                                           PRTDBGUNWINDSTATE pState, PCCPUMCTX pInitialCtx, RTDBGAS hAs,
+                                                           uint64_t *puScratch)
+{
+    RT_NOREF(pUVM, pvData, idCpu, pFrame, pState, pInitialCtx, hAs, puScratch);
+    return VINF_SUCCESS;
+}
+
+
+/**
  * @copydoc DBGFOSREG::pfnQueryInterface
  */
@@ -799,17 +811,18 @@
 const DBGFOSREG g_DBGDiggerFreeBsd =
 {
-    /* .u32Magic = */           DBGFOSREG_MAGIC,
-    /* .fFlags = */             0,
-    /* .cbData = */             sizeof(DBGDIGGERFBSD),
-    /* .szName = */             "FreeBSD",
-    /* .pfnConstruct = */       dbgDiggerFreeBsdConstruct,
-    /* .pfnDestruct = */        dbgDiggerFreeBsdDestruct,
-    /* .pfnProbe = */           dbgDiggerFreeBsdProbe,
-    /* .pfnInit = */            dbgDiggerFreeBsdInit,
-    /* .pfnRefresh = */         dbgDiggerFreeBsdRefresh,
-    /* .pfnTerm = */            dbgDiggerFreeBsdTerm,
-    /* .pfnQueryVersion = */    dbgDiggerFreeBsdQueryVersion,
-    /* .pfnQueryInterface = */  dbgDiggerFreeBsdQueryInterface,
-    /* .u32EndMagic = */        DBGFOSREG_MAGIC
+    /* .u32Magic = */               DBGFOSREG_MAGIC,
+    /* .fFlags = */                 0,
+    /* .cbData = */                 sizeof(DBGDIGGERFBSD),
+    /* .szName = */                 "FreeBSD",
+    /* .pfnConstruct = */           dbgDiggerFreeBsdConstruct,
+    /* .pfnDestruct = */            dbgDiggerFreeBsdDestruct,
+    /* .pfnProbe = */               dbgDiggerFreeBsdProbe,
+    /* .pfnInit = */                dbgDiggerFreeBsdInit,
+    /* .pfnRefresh = */             dbgDiggerFreeBsdRefresh,
+    /* .pfnTerm = */                dbgDiggerFreeBsdTerm,
+    /* .pfnQueryVersion = */        dbgDiggerFreeBsdQueryVersion,
+    /* .pfnQueryInterface = */      dbgDiggerFreeBsdQueryInterface,
+    /* .pfnStackUnwindAssist = */   dbgDiggerFreeBsdStackUnwindAssist,
+    /* .u32EndMagic = */            DBGFOSREG_MAGIC
 };
 
Index: trunk/src/VBox/Debugger/DBGPlugInLinux.cpp
===================================================================
--- trunk/src/VBox/Debugger/DBGPlugInLinux.cpp	(revision 73457)
+++ trunk/src/VBox/Debugger/DBGPlugInLinux.cpp	(revision 73460)
@@ -1082,4 +1082,16 @@
 {
     RTStrSpaceDestroy(&pThis->hCfgDb, dbgDiggerLinuxCfgDbDestroyWorker, NULL);
+}
+
+
+/**
+ * @copydoc DBGFOSREG::pfnStackUnwindAssist
+ */
+static DECLCALLBACK(int) dbgDiggerLinuxStackUnwindAssist(PUVM pUVM, void *pvData, VMCPUID idCpu, PDBGFSTACKFRAME pFrame,
+                                                         PRTDBGUNWINDSTATE pState, PCCPUMCTX pInitialCtx, RTDBGAS hAs,
+                                                         uint64_t *puScratch)
+{
+    RT_NOREF(pUVM, pvData, idCpu, pFrame, pState, pInitialCtx, hAs, puScratch);
+    return VINF_SUCCESS;
 }
 
@@ -2598,17 +2610,18 @@
 const DBGFOSREG g_DBGDiggerLinux =
 {
-    /* .u32Magic = */           DBGFOSREG_MAGIC,
-    /* .fFlags = */             0,
-    /* .cbData = */             sizeof(DBGDIGGERLINUX),
-    /* .szName = */             "Linux",
-    /* .pfnConstruct = */       dbgDiggerLinuxConstruct,
-    /* .pfnDestruct = */        dbgDiggerLinuxDestruct,
-    /* .pfnProbe = */           dbgDiggerLinuxProbe,
-    /* .pfnInit = */            dbgDiggerLinuxInit,
-    /* .pfnRefresh = */         dbgDiggerLinuxRefresh,
-    /* .pfnTerm = */            dbgDiggerLinuxTerm,
-    /* .pfnQueryVersion = */    dbgDiggerLinuxQueryVersion,
-    /* .pfnQueryInterface = */  dbgDiggerLinuxQueryInterface,
-    /* .u32EndMagic = */        DBGFOSREG_MAGIC
+    /* .u32Magic = */               DBGFOSREG_MAGIC,
+    /* .fFlags = */                 0,
+    /* .cbData = */                 sizeof(DBGDIGGERLINUX),
+    /* .szName = */                 "Linux",
+    /* .pfnConstruct = */           dbgDiggerLinuxConstruct,
+    /* .pfnDestruct = */            dbgDiggerLinuxDestruct,
+    /* .pfnProbe = */               dbgDiggerLinuxProbe,
+    /* .pfnInit = */                dbgDiggerLinuxInit,
+    /* .pfnRefresh = */             dbgDiggerLinuxRefresh,
+    /* .pfnTerm = */                dbgDiggerLinuxTerm,
+    /* .pfnQueryVersion = */        dbgDiggerLinuxQueryVersion,
+    /* .pfnQueryInterface = */      dbgDiggerLinuxQueryInterface,
+    /* .pfnStackUnwindAssist = */   dbgDiggerLinuxStackUnwindAssist,
+    /* .u32EndMagic = */            DBGFOSREG_MAGIC
 };
 
Index: trunk/src/VBox/Debugger/DBGPlugInOS2.cpp
===================================================================
--- trunk/src/VBox/Debugger/DBGPlugInOS2.cpp	(revision 73457)
+++ trunk/src/VBox/Debugger/DBGPlugInOS2.cpp	(revision 73460)
@@ -116,4 +116,16 @@
 
 /**
+ * @copydoc DBGFOSREG::pfnStackUnwindAssist
+ */
+static DECLCALLBACK(int) dbgDiggerOS2StackUnwindAssist(PUVM pUVM, void *pvData, VMCPUID idCpu, PDBGFSTACKFRAME pFrame,
+                                                       PRTDBGUNWINDSTATE pState, PCCPUMCTX pInitialCtx, RTDBGAS hAs,
+                                                       uint64_t *puScratch)
+{
+    RT_NOREF(pUVM, pvData, idCpu, pFrame, pState, pInitialCtx, hAs, puScratch);
+    return VINF_SUCCESS;
+}
+
+
+/**
  * @copydoc DBGFOSREG::pfnQueryInterface
  */
@@ -343,16 +355,17 @@
 const DBGFOSREG g_DBGDiggerOS2 =
 {
-    /* .u32Magic = */           DBGFOSREG_MAGIC,
-    /* .fFlags = */             0,
-    /* .cbData = */             sizeof(DBGDIGGEROS2),
-    /* .szName = */             "OS/2",
-    /* .pfnConstruct = */       dbgDiggerOS2Construct,
-    /* .pfnDestruct = */        dbgDiggerOS2Destruct,
-    /* .pfnProbe = */           dbgDiggerOS2Probe,
-    /* .pfnInit = */            dbgDiggerOS2Init,
-    /* .pfnRefresh = */         dbgDiggerOS2Refresh,
-    /* .pfnTerm = */            dbgDiggerOS2Term,
-    /* .pfnQueryVersion = */    dbgDiggerOS2QueryVersion,
-    /* .pfnQueryInterface = */  dbgDiggerOS2QueryInterface,
-    /* .u32EndMagic = */        DBGFOSREG_MAGIC
+    /* .u32Magic = */               DBGFOSREG_MAGIC,
+    /* .fFlags = */                 0,
+    /* .cbData = */                 sizeof(DBGDIGGEROS2),
+    /* .szName = */                 "OS/2",
+    /* .pfnConstruct = */           dbgDiggerOS2Construct,
+    /* .pfnDestruct = */            dbgDiggerOS2Destruct,
+    /* .pfnProbe = */               dbgDiggerOS2Probe,
+    /* .pfnInit = */                dbgDiggerOS2Init,
+    /* .pfnRefresh = */             dbgDiggerOS2Refresh,
+    /* .pfnTerm = */                dbgDiggerOS2Term,
+    /* .pfnQueryVersion = */        dbgDiggerOS2QueryVersion,
+    /* .pfnQueryInterface = */      dbgDiggerOS2QueryInterface,
+    /* .pfnStackUnwindAssist = */   dbgDiggerOS2StackUnwindAssist,
+    /* .u32EndMagic = */            DBGFOSREG_MAGIC
 };
Index: trunk/src/VBox/Debugger/DBGPlugInSolaris.cpp
===================================================================
--- trunk/src/VBox/Debugger/DBGPlugInSolaris.cpp	(revision 73457)
+++ trunk/src/VBox/Debugger/DBGPlugInSolaris.cpp	(revision 73460)
@@ -352,4 +352,16 @@
 static DECLCALLBACK(int)  dbgDiggerSolarisInit(PUVM pUVM, void *pvData);
 
+
+
+/**
+ * @copydoc DBGFOSREG::pfnStackUnwindAssist
+ */
+static DECLCALLBACK(int) dbgDiggerSolarisStackUnwindAssist(PUVM pUVM, void *pvData, VMCPUID idCpu, PDBGFSTACKFRAME pFrame,
+                                                           PRTDBGUNWINDSTATE pState, PCCPUMCTX pInitialCtx, RTDBGAS hAs,
+                                                           uint64_t *puScratch)
+{
+    RT_NOREF(pUVM, pvData, idCpu, pFrame, pState, pInitialCtx, hAs, puScratch);
+    return VINF_SUCCESS;
+}
 
 
@@ -1111,17 +1123,18 @@
 const DBGFOSREG g_DBGDiggerSolaris =
 {
-    /* .u32Magic = */           DBGFOSREG_MAGIC,
-    /* .fFlags = */             0,
-    /* .cbData = */             sizeof(DBGDIGGERSOLARIS),
-    /* .szName = */             "Solaris",
-    /* .pfnConstruct = */       dbgDiggerSolarisConstruct,
-    /* .pfnDestruct = */        dbgDiggerSolarisDestruct,
-    /* .pfnProbe = */           dbgDiggerSolarisProbe,
-    /* .pfnInit = */            dbgDiggerSolarisInit,
-    /* .pfnRefresh = */         dbgDiggerSolarisRefresh,
-    /* .pfnTerm = */            dbgDiggerSolarisTerm,
-    /* .pfnQueryVersion = */    dbgDiggerSolarisQueryVersion,
-    /* .pfnQueryInterface = */  dbgDiggerSolarisQueryInterface,
-    /* .u32EndMagic = */        DBGFOSREG_MAGIC
+    /* .u32Magic = */               DBGFOSREG_MAGIC,
+    /* .fFlags = */                 0,
+    /* .cbData = */                 sizeof(DBGDIGGERSOLARIS),
+    /* .szName = */                 "Solaris",
+    /* .pfnConstruct = */           dbgDiggerSolarisConstruct,
+    /* .pfnDestruct = */            dbgDiggerSolarisDestruct,
+    /* .pfnProbe = */               dbgDiggerSolarisProbe,
+    /* .pfnInit = */                dbgDiggerSolarisInit,
+    /* .pfnRefresh = */             dbgDiggerSolarisRefresh,
+    /* .pfnTerm = */                dbgDiggerSolarisTerm,
+    /* .pfnQueryVersion = */        dbgDiggerSolarisQueryVersion,
+    /* .pfnQueryInterface = */      dbgDiggerSolarisQueryInterface,
+    /* .pfnStackUnwindAssist = */   dbgDiggerSolarisStackUnwindAssist,
+    /* .u32EndMagic = */            DBGFOSREG_MAGIC
 };
 
Index: trunk/src/VBox/Debugger/DBGPlugInWinNt.cpp
===================================================================
--- trunk/src/VBox/Debugger/DBGPlugInWinNt.cpp	(revision 73457)
+++ trunk/src/VBox/Debugger/DBGPlugInWinNt.cpp	(revision 73460)
@@ -23,4 +23,6 @@
 #include "DBGPlugIns.h"
 #include <VBox/vmm/dbgf.h>
+#include <VBox/vmm/cpumctx.h>
+#include <VBox/vmm/mm.h>
 #include <VBox/err.h>
 #include <VBox/param.h>
@@ -31,4 +33,5 @@
 #include <iprt/formats/pecoff.h>
 #include <iprt/formats/mz.h>
+#include <iprt/nt/nt-structures.h>
 
 
@@ -262,5 +265,5 @@
 #define WINNT32_VALID_ADDRESS(Addr)         ((Addr) >         UINT32_C(0x80000000) && (Addr) <         UINT32_C(0xfffff000))
 /** Validates a 64-bit Windows NT kernel address */
- #define WINNT64_VALID_ADDRESS(Addr)         ((Addr) > UINT64_C(0xffff800000000000) && (Addr) < UINT64_C(0xfffffffffffff000))
+#define WINNT64_VALID_ADDRESS(Addr)         ((Addr) > UINT64_C(0xffff800000000000) && (Addr) < UINT64_C(0xfffffffffffff000))
 /** Validates a kernel address. */
 #define WINNT_VALID_ADDRESS(pThis, Addr)    ((pThis)->f32Bit ? WINNT32_VALID_ADDRESS(Addr) : WINNT64_VALID_ADDRESS(Addr))
@@ -347,4 +350,143 @@
     else
         Log(("DigWinNt: %s: DBGFR3ModInMem failed: %Rrc\n", pszName, rc));
+}
+
+
+/**
+ * @copydoc DBGFOSREG::pfnStackUnwindAssist
+ */
+static DECLCALLBACK(int) dbgDiggerWinNtStackUnwindAssist(PUVM pUVM, void *pvData, VMCPUID idCpu, PDBGFSTACKFRAME pFrame,
+                                                         PRTDBGUNWINDSTATE pState, PCCPUMCTX pInitialCtx, RTDBGAS hAs,
+                                                         uint64_t *puScratch)
+{
+    Assert(pInitialCtx);
+
+    /*
+     * We want to locate trap frames here.  The trap frame structure contains
+     * the 64-bit IRET frame, so given unwind information it's easy to identify
+     * using the return type and frame address.
+     */
+    if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_64BIT)
+    {
+        /*
+         * Is this a trap frame?  If so, try read the trap frame.
+         */
+        if (   pFrame->enmReturnType == RTDBGRETURNTYPE_IRET64
+            && !(pFrame->AddrFrame.FlatPtr & 0x7)
+            && WINNT64_VALID_ADDRESS(pFrame->AddrFrame.FlatPtr) )
+        {
+            KTRAP_FRAME_AMD64 TrapFrame;
+            RT_ZERO(TrapFrame);
+            uint64_t const uTrapFrameAddr = pFrame->AddrFrame.FlatPtr
+                                          - RT_UOFFSETOF(KTRAP_FRAME_AMD64, ErrCdOrXcptFrameOrS);
+            int rc = pState->pfnReadStack(pState, uTrapFrameAddr, sizeof(TrapFrame), &TrapFrame);
+            if (RT_SUCCESS(rc))
+            {
+                /* Valid?  Not too much else we can check here (EFlags isn't
+                   reliable in manually construct frames). */
+                if (TrapFrame.ExceptionActive <= 2)
+                {
+                    pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_TRAP_FRAME;
+
+                    /*
+                     * Add sure 'register' information from the frame to the frame.
+                     *
+                     * To avoid code duplication, we do this in two steps in a loop.
+                     * The first iteration only figures out how many registers we're
+                     * going to save and allocates room for them.  The second iteration
+                     * does the actual adding.
+                     */
+                    uint32_t      cRegs      = pFrame->cSureRegs;
+                    PDBGFREGVALEX paSureRegs = NULL;
+#define ADD_REG_NAMED(a_Type, a_ValMemb, a_Value, a_pszName) do { \
+                            if (paSureRegs) \
+                            { \
+                                paSureRegs[iReg].pszName         = a_pszName;\
+                                paSureRegs[iReg].enmReg          = DBGFREG_END; \
+                                paSureRegs[iReg].enmType         = a_Type; \
+                                paSureRegs[iReg].Value.a_ValMemb = (a_Value); \
+                            } \
+                            iReg++; \
+                        } while (0)
+#define MAYBE_ADD_GREG(a_Value, a_enmReg, a_idxReg) do { \
+                            if (!(pState->u.x86.Loaded.s.fRegs & RT_BIT(a_idxReg))) \
+                            { \
+                                if (paSureRegs) \
+                                { \
+                                    pState->u.x86.Loaded.s.fRegs    |= RT_BIT(a_idxReg); \
+                                    pState->u.x86.auRegs[a_idxReg]   = (a_Value); \
+                                    paSureRegs[iReg].Value.u64       = (a_Value); \
+                                    paSureRegs[iReg].enmReg          = a_enmReg; \
+                                    paSureRegs[iReg].enmType         = DBGFREGVALTYPE_U64; \
+                                    paSureRegs[iReg].pszName         = NULL; \
+                                } \
+                                iReg++; \
+                            } \
+                        } while (0)
+                    for (unsigned iLoop = 0; iLoop < 2; iLoop++)
+                    {
+                        uint32_t iReg = pFrame->cSureRegs;
+                        ADD_REG_NAMED(DBGFREGVALTYPE_U64, u64, uTrapFrameAddr, "TrapFrame");
+                        ADD_REG_NAMED(DBGFREGVALTYPE_U8,   u8, TrapFrame.ExceptionActive, "ExceptionActive");
+                        if (TrapFrame.ExceptionActive == 0)
+                        {
+                            ADD_REG_NAMED(DBGFREGVALTYPE_U8,   u8, TrapFrame.PreviousIrql, "PrevIrql");
+                            ADD_REG_NAMED(DBGFREGVALTYPE_U8,   u8, (uint8_t)TrapFrame.ErrCdOrXcptFrameOrS, "IntNo");
+                        }
+                        else if (   TrapFrame.ExceptionActive == 1
+                                 && TrapFrame.FaultIndicator == ((TrapFrame.ErrCdOrXcptFrameOrS >> 1) & 0x9))
+                            ADD_REG_NAMED(DBGFREGVALTYPE_U64, u64, TrapFrame.FaultAddrOrCtxRecOrTS, "cr2-probably");
+                        if (TrapFrame.SegCs & X86_SEL_RPL)
+                            ADD_REG_NAMED(DBGFREGVALTYPE_U8,   u8, 1, "UserMode");
+                        else
+                            ADD_REG_NAMED(DBGFREGVALTYPE_U8,   u8, 1, "KernelMode");
+                        if (TrapFrame.ExceptionActive <= 1)
+                        {
+                            MAYBE_ADD_GREG(TrapFrame.Rax, DBGFREG_RAX, X86_GREG_xAX);
+                            MAYBE_ADD_GREG(TrapFrame.Rcx, DBGFREG_RCX, X86_GREG_xCX);
+                            MAYBE_ADD_GREG(TrapFrame.Rdx, DBGFREG_RDX, X86_GREG_xDX);
+                            MAYBE_ADD_GREG(TrapFrame.R8,  DBGFREG_R8,  X86_GREG_x8);
+                            MAYBE_ADD_GREG(TrapFrame.R9,  DBGFREG_R9,  X86_GREG_x9);
+                            MAYBE_ADD_GREG(TrapFrame.R10, DBGFREG_R10, X86_GREG_x10);
+                            MAYBE_ADD_GREG(TrapFrame.R11, DBGFREG_R11, X86_GREG_x11);
+                        }
+                        else if (TrapFrame.ExceptionActive == 2)
+                        {
+                            MAYBE_ADD_GREG(TrapFrame.Rbx, DBGFREG_RBX, X86_GREG_xBX);
+                            MAYBE_ADD_GREG(TrapFrame.Rsi, DBGFREG_RSI, X86_GREG_xSI);
+                            MAYBE_ADD_GREG(TrapFrame.Rdi, DBGFREG_RDI, X86_GREG_xDI);
+                        }
+                        MAYBE_ADD_GREG(TrapFrame.Rbp, DBGFREG_RBP, X86_GREG_xBP);
+
+                        /* Done? */
+                        if (iLoop > 0)
+                        {
+                            Assert(cRegs == iReg);
+                            break;
+                        }
+
+                        /* Resize the array, zeroing the extension. */
+                        if (pFrame->cSureRegs)
+                            paSureRegs = (PDBGFREGVALEX)MMR3HeapRealloc(pFrame->paSureRegs, iReg * sizeof(paSureRegs[0]));
+                        else
+                            paSureRegs = (PDBGFREGVALEX)MMR3HeapAllocU(pUVM, MM_TAG_DBGF_STACK, iReg * sizeof(paSureRegs[0]));
+                        AssertReturn(paSureRegs, VERR_NO_MEMORY);
+
+                        pFrame->paSureRegs = paSureRegs;
+                        RT_BZERO(&paSureRegs[pFrame->cSureRegs], (iReg - pFrame->cSureRegs) * sizeof(paSureRegs[0]));
+                        cRegs = iReg;
+                    }
+#undef ADD_REG_NAMED
+#undef MAYBE_ADD_GREG
+
+                    /* Commit the register update. */
+                    pFrame->cSureRegs = cRegs;
+                }
+            }
+        }
+    }
+
+    RT_NOREF(pUVM, pvData, idCpu, hAs, puScratch);
+    return VINF_SUCCESS;
 }
 
@@ -882,17 +1024,18 @@
 const DBGFOSREG g_DBGDiggerWinNt =
 {
-    /* .u32Magic = */           DBGFOSREG_MAGIC,
-    /* .fFlags = */             0,
-    /* .cbData = */             sizeof(DBGDIGGERWINNT),
-    /* .szName = */             "WinNT",
-    /* .pfnConstruct = */       dbgDiggerWinNtConstruct,
-    /* .pfnDestruct = */        dbgDiggerWinNtDestruct,
-    /* .pfnProbe = */           dbgDiggerWinNtProbe,
-    /* .pfnInit = */            dbgDiggerWinNtInit,
-    /* .pfnRefresh = */         dbgDiggerWinNtRefresh,
-    /* .pfnTerm = */            dbgDiggerWinNtTerm,
-    /* .pfnQueryVersion = */    dbgDiggerWinNtQueryVersion,
-    /* .pfnQueryInterface = */  dbgDiggerWinNtQueryInterface,
-    /* .u32EndMagic = */        DBGFOSREG_MAGIC
+    /* .u32Magic = */               DBGFOSREG_MAGIC,
+    /* .fFlags = */                 0,
+    /* .cbData = */                 sizeof(DBGDIGGERWINNT),
+    /* .szName = */                 "WinNT",
+    /* .pfnConstruct = */           dbgDiggerWinNtConstruct,
+    /* .pfnDestruct = */            dbgDiggerWinNtDestruct,
+    /* .pfnProbe = */               dbgDiggerWinNtProbe,
+    /* .pfnInit = */                dbgDiggerWinNtInit,
+    /* .pfnRefresh = */             dbgDiggerWinNtRefresh,
+    /* .pfnTerm = */                dbgDiggerWinNtTerm,
+    /* .pfnQueryVersion = */        dbgDiggerWinNtQueryVersion,
+    /* .pfnQueryInterface = */      dbgDiggerWinNtQueryInterface,
+    /* .pfnStackUnwindAssist = */   dbgDiggerWinNtStackUnwindAssist,
+    /* .u32EndMagic = */            DBGFOSREG_MAGIC
 };
 
Index: trunk/src/VBox/VMM/VMMR3/DBGFOS.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/DBGFOS.cpp	(revision 73457)
+++ trunk/src/VBox/VMM/VMMR3/DBGFOS.cpp	(revision 73460)
@@ -638,2 +638,24 @@
 }
 
+
+
+/**
+ * Internal wrapper for calling DBGFOSREG::pfnStackUnwindAssist.
+ */
+int dbgfR3OSStackUnwindAssist(PUVM pUVM, VMCPUID idCpu, PDBGFSTACKFRAME pFrame, PRTDBGUNWINDSTATE pState,
+                              PCCPUMCTX pInitialCtx, RTDBGAS hAs, uint64_t *puScratch)
+{
+    int rc = VINF_SUCCESS;
+    if (pUVM->dbgf.s.pCurOS)
+    {
+        ASMCompilerBarrier();
+        DBGF_OS_READ_LOCK(pUVM);
+        PDBGFOS pOS = pUVM->dbgf.s.pCurOS;
+        if (pOS)
+            rc = pOS->pReg->pfnStackUnwindAssist(pUVM, pUVM->dbgf.s.pCurOS->abData, idCpu, pFrame,
+                                                 pState, pInitialCtx, hAs, puScratch);
+        DBGF_OS_READ_UNLOCK(pUVM);
+    }
+    return rc;
+}
+
Index: trunk/src/VBox/VMM/VMMR3/DBGFStack.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/DBGFStack.cpp	(revision 73457)
+++ trunk/src/VBox/VMM/VMMR3/DBGFStack.cpp	(revision 73460)
@@ -40,94 +40,5 @@
 *   Structures and Typedefs                                                                                                      *
 *********************************************************************************************************************************/
-/** Magic value for DBGFUNWINDSTATE::u32Magic (James Moody). */
-#define DBGFUNWINDSTATE_MAGIC           UINT32_C(0x19250326)
-/** Magic value for DBGFUNWINDSTATE::u32Magic after use. */
-#define DBGFUNWINDSTATE_MAGIC_DEAD      UINT32_C(0x20101209)
-
-/**
- * Register state.
- */
-typedef struct DBGFUNWINDSTATE
-{
-    /** Structure magic (DBGFUNWINDSTATE_MAGIC) */
-    uint32_t            u32Magic;
-    /** The state architecture. */
-    RTLDRARCH           enmArch;
-
-    /** The program counter register.
-     * amd64/x86: RIP/EIP/IP
-     * sparc: PC
-     * arm32: PC / R15
-     */
-    uint64_t            uPc;
-
-    /** Return type. */
-    DBGFRETRUNTYPE      enmRetType;
-
-    /** Register state (see enmArch). */
-    union
-    {
-        /** RTLDRARCH_AMD64, RTLDRARCH_X86_32 and RTLDRARCH_X86_16. */
-        struct
-        {
-            /** General purpose registers indexed by X86_GREG_XXX. */
-            uint64_t    auRegs[16];
-            /** The frame address. */
-            RTFAR64     FrameAddr;
-            /** Set if we're in real or virtual 8086 mode. */
-            bool        fRealOrV86;
-            /** The flags register. */
-            uint64_t    uRFlags;
-            /** Trap error code. */
-            uint64_t    uErrCd;
-            /** Segment registers (indexed by X86_SREG_XXX). */
-            uint16_t    auSegs[6];
-
-            /** Bitmap tracking register we've loaded and which content can possibly be trusted. */
-            union
-            {
-                /** For effective clearing of the bits. */
-                uint32_t    fAll;
-                /** Detailed view. */
-                struct
-                {
-                    /** Bitmap indicating whether a GPR was loaded (parallel to auRegs). */
-                    uint16_t    fRegs;
-                    /** Bitmap indicating whether a segment register was loaded (parallel to auSegs). */
-                    uint8_t     fSegs;
-                    /** Set if uPc was loaded. */
-                    uint8_t     fPc : 1;
-                    /** Set if FrameAddr was loaded. */
-                    uint8_t     fFrameAddr : 1;
-                    /** Set if uRFlags was loaded. */
-                    uint8_t     fRFlags : 1;
-                    /** Set if uErrCd was loaded. */
-                    uint8_t     fErrCd : 1;
-                } s;
-            } Loaded;
-        } x86;
-
-        /** @todo add ARM and others as needed. */
-    } u;
-
-    /**
-     * Stack read callback.
-     *
-     * @returns IPRT status code.
-     * @param   pThis       Pointer to this structure.
-     * @param   uSp         The stack pointer address.
-     * @param   cbToRead    The number of bytes to read.
-     * @param   pvDst       Where to put the bytes we read.
-     */
-    DECLCALLBACKMEMBER(int, pfnReadStack)(struct DBGFUNWINDSTATE *pThis, RTUINTPTR uSp, size_t cbToRead, void *pvDst);
-    /** User argument (usefule for pfnReadStack). */
-    void               *pvUser;
-
-} DBGFUNWINDSTATE;
-typedef struct DBGFUNWINDSTATE *PDBGFUNWINDSTATE;
-typedef struct DBGFUNWINDSTATE const *PCDBGFUNWINDSTATE;
-
-static DECLCALLBACK(int) dbgfR3StackReadCallback(PDBGFUNWINDSTATE pThis, RTUINTPTR uSp, size_t cbToRead, void *pvDst);
-
+static DECLCALLBACK(int) dbgfR3StackReadCallback(PRTDBGUNWINDSTATE pThis, RTUINTPTR uSp, size_t cbToRead, void *pvDst);
 
 /**
@@ -143,6 +54,8 @@
     VMCPUID     m_idCpu;
     RTDBGAS     m_hAs;
-
-    DBGFUNWINDSTATE m_State;
+    PCCPUMCTX   m_pInitialCtx;
+    uint64_t    m_uOsScratch; /**< For passing to DBGFOSREG::pfnStackUnwindAssist. */
+
+    RTDBGUNWINDSTATE m_State;
 
     RTDBGMOD    m_hCached;
@@ -159,5 +72,5 @@
     DBGFUNWINDCTX(PUVM pUVM, VMCPUID idCpu, PCCPUMCTX pInitialCtx, RTDBGAS hAs)
     {
-        m_State.u32Magic     = DBGFUNWINDSTATE_MAGIC;
+        m_State.u32Magic     = RTDBGUNWINDSTATE_MAGIC;
         m_State.enmArch      = RTLDRARCH_AMD64;
         m_State.pfnReadStack = dbgfR3StackReadCallback;
@@ -196,4 +109,6 @@
         m_idCpu           = idCpu;
         m_hAs             = DBGFR3AsResolveAndRetain(pUVM, hAs);
+        m_pInitialCtx     = pInitialCtx;
+        m_uOsScratch      = 0;
 
         m_hCached         = NIL_RTDBGMOD;
@@ -243,7 +158,7 @@
 
 /**
- * @interface_method_impl{DBGFUNWINDSTATE,pfnReadStack}
- */
-static DECLCALLBACK(int) dbgfR3StackReadCallback(PDBGFUNWINDSTATE pThis, RTUINTPTR uSp, size_t cbToRead, void *pvDst)
+ * @interface_method_impl{RTDBGUNWINDSTATE,pfnReadStack}
+ */
+static DECLCALLBACK(int) dbgfR3StackReadCallback(PRTDBGUNWINDSTATE pThis, RTUINTPTR uSp, size_t cbToRead, void *pvDst)
 {
     Assert(   pThis->enmArch == RTLDRARCH_AMD64
@@ -308,5 +223,5 @@
  * @param   puDst           The read destination.
  */
-DECLINLINE(int) dbgUnwindLoadStackU16(PDBGFUNWINDSTATE pThis, uint64_t uSrcAddr, uint16_t *puDst)
+DECLINLINE(int) dbgUnwindLoadStackU16(PRTDBGUNWINDSTATE pThis, uint64_t uSrcAddr, uint16_t *puDst)
 {
     return pThis->pfnReadStack(pThis, uSrcAddr, sizeof(*puDst), puDst);
@@ -322,5 +237,5 @@
  * @param   puDst           The read destination.
  */
-DECLINLINE(int) dbgUnwindLoadStackU64(PDBGFUNWINDSTATE pThis, uint64_t uSrcAddr, uint64_t *puDst)
+DECLINLINE(int) dbgUnwindLoadStackU64(PRTDBGUNWINDSTATE pThis, uint64_t uSrcAddr, uint64_t *puDst)
 {
     return pThis->pfnReadStack(pThis, uSrcAddr, sizeof(*puDst), puDst);
@@ -362,5 +277,5 @@
  * @param   fErrCd          Non-zero if there is an error code on the stack.
  */
-static bool dbgUnwindPeAmd64DoOneIRet(PDBGFUNWINDSTATE pThis, uint8_t fErrCd)
+static bool dbgUnwindPeAmd64DoOneIRet(PRTDBGUNWINDSTATE pThis, uint8_t fErrCd)
 {
     Assert(fErrCd <= 1);
@@ -375,5 +290,5 @@
     }
 
-    pThis->enmRetType = DBGFRETURNTYPE_IRET64;
+    pThis->enmRetType = RTDBGRETURNTYPE_IRET64;
     pThis->u.x86.FrameAddr.off = pThis->u.x86.auRegs[X86_GREG_xSP] - /* pretend rbp is pushed on the stack */ 8;
     pThis->u.x86.FrameAddr.sel = pThis->u.x86.auSegs[X86_SREG_SS];
@@ -419,5 +334,5 @@
  */
 static bool dbgUnwindPeAmd64DoOne(RTDBGMOD hMod, PCIMAGE_RUNTIME_FUNCTION_ENTRY paFunctions, size_t cFunctions,
-                                  PDBGFUNWINDSTATE pThis, uint32_t uRvaRip)
+                                  PRTDBGUNWINDSTATE pThis, uint32_t uRvaRip)
 {
     /*
@@ -681,5 +596,5 @@
          * RSP should now give us the return address, so perform a RET.
          */
-        pThis->enmRetType = DBGFRETURNTYPE_NEAR64;
+        pThis->enmRetType = RTDBGRETURNTYPE_NEAR64;
 
         pThis->u.x86.FrameAddr.off = pThis->u.x86.auRegs[X86_GREG_xSP] - /* pretend rbp is pushed on the stack */ 8;
@@ -794,5 +709,13 @@
 }
 
-static int dbgfR3StackWalkCollectRegisterChanges(PUVM pUVM, PDBGFSTACKFRAME pFrame, PDBGFUNWINDSTATE pState)
+/**
+ * Collects sure registers on frame exit.
+ *
+ * @returns VINF_SUCCESS or VERR_NO_MEMORY.
+ * @param   pUVM        The user mode VM handle for the allocation.
+ * @param   pFrame      The frame in question.
+ * @param   pState      The unwind state.
+ */
+static int dbgfR3StackWalkCollectRegisterChanges(PUVM pUVM, PDBGFSTACKFRAME pFrame, PRTDBGUNWINDSTATE pState)
 {
     pFrame->cSureRegs  = 0;
@@ -931,24 +854,11 @@
             pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO;
             pFrame->fFlags &= ~DBGFSTACKFRAME_FLAGS_UNWIND_INFO_RET;
-            if (pFrame->enmReturnFrameReturnType != DBGFRETURNTYPE_INVALID)
+            if (pFrame->enmReturnFrameReturnType != RTDBGRETURNTYPE_INVALID)
             {
                 pFrame->enmReturnType = pFrame->enmReturnFrameReturnType;
-                pFrame->enmReturnFrameReturnType = DBGFRETURNTYPE_INVALID;
+                pFrame->enmReturnFrameReturnType = RTDBGRETURNTYPE_INVALID;
             }
         }
-    }
-
-    /*
-     * Enagage the OS layer and collect register changes.
-     */
-    if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO)
-    {
-        /** @todo engage the OS buggers to identify trap frames and update unwindctx accordingly. */
-        if (!fFirst)
-        {
-            int rc = dbgfR3StackWalkCollectRegisterChanges(pUnwindCtx->m_pUVM, pFrame, &pUnwindCtx->m_State);
-            if (RT_FAILURE(rc))
-                return rc;
-        }
+        pFrame->fFlags &= ~DBGFSTACKFRAME_FLAGS_TRAP_FRAME;
     }
 
@@ -957,5 +867,5 @@
      */
     /** @todo this is bogus... */
-    unsigned cbRetAddr = DBGFReturnTypeSize(pFrame->enmReturnType);
+    unsigned cbRetAddr = RTDbgReturnTypeSize(pFrame->enmReturnType);
     unsigned cbStackItem;
     switch (pFrame->AddrPC.fFlags & DBGFADDRESS_FLAGS_TYPE_MASK)
@@ -968,17 +878,17 @@
             switch (pFrame->enmReturnType)
             {
-                case DBGFRETURNTYPE_FAR16:
-                case DBGFRETURNTYPE_IRET16:
-                case DBGFRETURNTYPE_IRET32_V86:
-                case DBGFRETURNTYPE_NEAR16: cbStackItem = 2; break;
-
-                case DBGFRETURNTYPE_FAR32:
-                case DBGFRETURNTYPE_IRET32:
-                case DBGFRETURNTYPE_IRET32_PRIV:
-                case DBGFRETURNTYPE_NEAR32: cbStackItem = 4; break;
-
-                case DBGFRETURNTYPE_FAR64:
-                case DBGFRETURNTYPE_IRET64:
-                case DBGFRETURNTYPE_NEAR64: cbStackItem = 8; break;
+                case RTDBGRETURNTYPE_FAR16:
+                case RTDBGRETURNTYPE_IRET16:
+                case RTDBGRETURNTYPE_IRET32_V86:
+                case RTDBGRETURNTYPE_NEAR16: cbStackItem = 2; break;
+
+                case RTDBGRETURNTYPE_FAR32:
+                case RTDBGRETURNTYPE_IRET32:
+                case RTDBGRETURNTYPE_IRET32_PRIV:
+                case RTDBGRETURNTYPE_NEAR32: cbStackItem = 4; break;
+
+                case RTDBGRETURNTYPE_FAR64:
+                case RTDBGRETURNTYPE_IRET64:
+                case RTDBGRETURNTYPE_NEAR64: cbStackItem = 8; break;
 
                 default:
@@ -1024,9 +934,9 @@
     if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO)
     {
-        if (   pFrame->enmReturnType == DBGFRETURNTYPE_IRET32_PRIV
-            || pFrame->enmReturnType == DBGFRETURNTYPE_IRET64)
+        if (   pFrame->enmReturnType == RTDBGRETURNTYPE_IRET32_PRIV
+            || pFrame->enmReturnType == RTDBGRETURNTYPE_IRET64)
             DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnFrame,
                                  pUnwindCtx->m_State.u.x86.auSegs[X86_SREG_SS], pUnwindCtx->m_State.u.x86.auRegs[X86_GREG_xBP]);
-        else if (pFrame->enmReturnType == DBGFRETURNTYPE_IRET32_V86)
+        else if (pFrame->enmReturnType == RTDBGRETURNTYPE_IRET32_V86)
             DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &pFrame->AddrReturnFrame,
                                  ((uint32_t)pUnwindCtx->m_State.u.x86.auSegs[X86_SREG_SS] << 4)
@@ -1055,14 +965,14 @@
             {
                 pFrame->AddrReturnFrame.off &= ~(RTGCUINTPTR)1;
-                if (pFrame->enmReturnType == DBGFRETURNTYPE_NEAR16)
+                if (pFrame->enmReturnType == RTDBGRETURNTYPE_NEAR16)
                 {
                     pFrame->fFlags       |= DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN;
-                    pFrame->enmReturnType = DBGFRETURNTYPE_FAR16;
+                    pFrame->enmReturnType = RTDBGRETURNTYPE_FAR16;
                     cbRetAddr = 4;
                 }
-                else if (pFrame->enmReturnType == DBGFRETURNTYPE_NEAR32)
+                else if (pFrame->enmReturnType == RTDBGRETURNTYPE_NEAR32)
                 {
                     pFrame->fFlags       |= DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN;
-                    pFrame->enmReturnType = DBGFRETURNTYPE_FAR32;
+                    pFrame->enmReturnType = RTDBGRETURNTYPE_FAR32;
                     cbRetAddr = 8;
                 }
@@ -1070,12 +980,12 @@
             else if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN)
             {
-                if (pFrame->enmReturnType == DBGFRETURNTYPE_FAR16)
+                if (pFrame->enmReturnType == RTDBGRETURNTYPE_FAR16)
                 {
-                    pFrame->enmReturnType = DBGFRETURNTYPE_NEAR16;
+                    pFrame->enmReturnType = RTDBGRETURNTYPE_NEAR16;
                     cbRetAddr = 2;
                 }
-                else if (pFrame->enmReturnType == DBGFRETURNTYPE_NEAR32)
+                else if (pFrame->enmReturnType == RTDBGRETURNTYPE_NEAR32)
                 {
-                    pFrame->enmReturnType = DBGFRETURNTYPE_FAR32;
+                    pFrame->enmReturnType = RTDBGRETURNTYPE_FAR32;
                     cbRetAddr = 4;
                 }
@@ -1094,9 +1004,9 @@
     if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO)
     {
-        if (   pFrame->enmReturnType == DBGFRETURNTYPE_IRET32_PRIV
-            || pFrame->enmReturnType == DBGFRETURNTYPE_IRET64)
+        if (   pFrame->enmReturnType == RTDBGRETURNTYPE_IRET32_PRIV
+            || pFrame->enmReturnType == RTDBGRETURNTYPE_IRET64)
             DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnStack,
                                  pUnwindCtx->m_State.u.x86.auSegs[X86_SREG_SS], pUnwindCtx->m_State.u.x86.auRegs[X86_GREG_xSP]);
-        else if (pFrame->enmReturnType == DBGFRETURNTYPE_IRET32_V86)
+        else if (pFrame->enmReturnType == RTDBGRETURNTYPE_IRET32_V86)
             DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &pFrame->AddrReturnStack,
                                  ((uint32_t)pUnwindCtx->m_State.u.x86.auSegs[X86_SREG_SS] << 4)
@@ -1120,5 +1030,5 @@
     if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO)
     {
-        if (DBGFReturnTypeIsNear(pFrame->enmReturnType))
+        if (RTDbgReturnTypeIsNear(pFrame->enmReturnType))
         {
             pFrame->AddrReturnPC.off      = pUnwindCtx->m_State.uPc;
@@ -1132,5 +1042,5 @@
         switch (pFrame->enmReturnType)
         {
-            case DBGFRETURNTYPE_NEAR16:
+            case RTDBGRETURNTYPE_NEAR16:
                 if (DBGFADDRESS_IS_VALID(&pFrame->AddrReturnPC))
                 {
@@ -1141,5 +1051,5 @@
                     DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &pFrame->AddrReturnPC, *uRet.pu16);
                 break;
-            case DBGFRETURNTYPE_NEAR32:
+            case RTDBGRETURNTYPE_NEAR32:
                 if (DBGFADDRESS_IS_VALID(&pFrame->AddrReturnPC))
                 {
@@ -1150,5 +1060,5 @@
                     DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &pFrame->AddrReturnPC, *uRet.pu32);
                 break;
-            case DBGFRETURNTYPE_NEAR64:
+            case RTDBGRETURNTYPE_NEAR64:
                 if (DBGFADDRESS_IS_VALID(&pFrame->AddrReturnPC))
                 {
@@ -1159,26 +1069,26 @@
                     DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &pFrame->AddrReturnPC, *uRet.pu64);
                 break;
-            case DBGFRETURNTYPE_FAR16:
+            case RTDBGRETURNTYPE_FAR16:
                 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[1], uRet.pu16[0]);
                 break;
-            case DBGFRETURNTYPE_FAR32:
+            case RTDBGRETURNTYPE_FAR32:
                 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]);
                 break;
-            case DBGFRETURNTYPE_FAR64:
+            case RTDBGRETURNTYPE_FAR64:
                 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[4], uRet.pu64[0]);
                 break;
-            case DBGFRETURNTYPE_IRET16:
+            case RTDBGRETURNTYPE_IRET16:
                 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[1], uRet.pu16[0]);
                 break;
-            case DBGFRETURNTYPE_IRET32:
+            case RTDBGRETURNTYPE_IRET32:
                 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]);
                 break;
-            case DBGFRETURNTYPE_IRET32_PRIV:
+            case RTDBGRETURNTYPE_IRET32_PRIV:
                 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]);
                 break;
-            case DBGFRETURNTYPE_IRET32_V86:
+            case RTDBGRETURNTYPE_IRET32_V86:
                 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]);
                 break;
-            case DBGFRETURNTYPE_IRET64:
+            case RTDBGRETURNTYPE_IRET64:
                 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[4], uRet.pu64[0]);
                 break;
@@ -1214,9 +1124,32 @@
 
     /*
+     * Collect register changes.
+     * Then call the OS layer to assist us (e.g. NT trap frames).
+     */
+    if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO)
+    {
+        if (!fFirst)
+        {
+            int rc = dbgfR3StackWalkCollectRegisterChanges(pUnwindCtx->m_pUVM, pFrame, &pUnwindCtx->m_State);
+            if (RT_FAILURE(rc))
+                return rc;
+        }
+
+        if (   pUnwindCtx->m_pInitialCtx
+            && pUnwindCtx->m_hAs != NIL_RTDBGAS)
+        {
+            int rc = dbgfR3OSStackUnwindAssist(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, pFrame, &pUnwindCtx->m_State,
+                                               pUnwindCtx->m_pInitialCtx, pUnwindCtx->m_hAs, &pUnwindCtx->m_uOsScratch);
+            if (RT_FAILURE(rc))
+                return rc;
+        }
+    }
+
+    /*
      * Try use unwind information to locate the return frame pointer (for the
      * next loop iteration).
      */
     Assert(!(pFrame->fFlags & DBGFSTACKFRAME_FLAGS_UNWIND_INFO_RET));
-    pFrame->enmReturnFrameReturnType = DBGFRETURNTYPE_INVALID;
+    pFrame->enmReturnFrameReturnType = RTDBGRETURNTYPE_INVALID;
     if (!(pFrame->fFlags & DBGFSTACKFRAME_FLAGS_LAST))
     {
@@ -1258,5 +1191,5 @@
                                                 PCDBGFADDRESS pAddrStack,
                                                 PCDBGFADDRESS pAddrPC,
-                                                DBGFRETURNTYPE enmReturnType,
+                                                RTDBGRETURNTYPE enmReturnType,
                                                 PCDBGFSTACKFRAME *ppFirstFrame)
 {
@@ -1301,6 +1234,6 @@
             {
                 fAddrMask = UINT16_MAX;
-                if (enmReturnType == DBGFRETURNTYPE_INVALID)
-                    pCur->enmReturnType = DBGFRETURNTYPE_NEAR16;
+                if (enmReturnType == RTDBGRETURNTYPE_INVALID)
+                    pCur->enmReturnType = RTDBGRETURNTYPE_NEAR16;
             }
             else if (   enmCpuMode == CPUMMODE_PROTECTED
@@ -1308,26 +1241,26 @@
             {
                 fAddrMask = UINT32_MAX;
-                if (enmReturnType == DBGFRETURNTYPE_INVALID)
-                    pCur->enmReturnType = DBGFRETURNTYPE_NEAR32;
+                if (enmReturnType == RTDBGRETURNTYPE_INVALID)
+                    pCur->enmReturnType = RTDBGRETURNTYPE_NEAR32;
             }
             else
             {
                 fAddrMask = UINT64_MAX;
-                if (enmReturnType == DBGFRETURNTYPE_INVALID)
-                    pCur->enmReturnType = DBGFRETURNTYPE_NEAR64;
+                if (enmReturnType == RTDBGRETURNTYPE_INVALID)
+                    pCur->enmReturnType = RTDBGRETURNTYPE_NEAR64;
             }
         }
 
-        if (enmReturnType == DBGFRETURNTYPE_INVALID)
+        if (enmReturnType == RTDBGRETURNTYPE_INVALID)
             switch (pCur->AddrPC.fFlags & DBGFADDRESS_FLAGS_TYPE_MASK)
             {
-                case DBGFADDRESS_FLAGS_FAR16: pCur->enmReturnType = DBGFRETURNTYPE_NEAR16; break;
-                case DBGFADDRESS_FLAGS_FAR32: pCur->enmReturnType = DBGFRETURNTYPE_NEAR32; break;
-                case DBGFADDRESS_FLAGS_FAR64: pCur->enmReturnType = DBGFRETURNTYPE_NEAR64; break;
+                case DBGFADDRESS_FLAGS_FAR16: pCur->enmReturnType = RTDBGRETURNTYPE_NEAR16; break;
+                case DBGFADDRESS_FLAGS_FAR32: pCur->enmReturnType = RTDBGRETURNTYPE_NEAR32; break;
+                case DBGFADDRESS_FLAGS_FAR64: pCur->enmReturnType = RTDBGRETURNTYPE_NEAR64; break;
                 case DBGFADDRESS_FLAGS_RING0:
-                    pCur->enmReturnType = HC_ARCH_BITS == 64 ? DBGFRETURNTYPE_NEAR64 : DBGFRETURNTYPE_NEAR32;
+                    pCur->enmReturnType = HC_ARCH_BITS == 64 ? RTDBGRETURNTYPE_NEAR64 : RTDBGRETURNTYPE_NEAR32;
                     break;
                 default:
-                    pCur->enmReturnType = DBGFRETURNTYPE_NEAR32;
+                    pCur->enmReturnType = RTDBGRETURNTYPE_NEAR32;
                     break;
             }
@@ -1438,5 +1371,5 @@
                                       PCDBGFADDRESS pAddrStack,
                                       PCDBGFADDRESS pAddrPC,
-                                      DBGFRETURNTYPE enmReturnType,
+                                      RTDBGRETURNTYPE enmReturnType,
                                       PCDBGFSTACKFRAME *ppFirstFrame)
 {
@@ -1455,5 +1388,5 @@
     if (pAddrPC)
         AssertReturn(DBGFR3AddrIsValid(pUVM, pAddrPC), VERR_INVALID_PARAMETER);
-    AssertReturn(enmReturnType >= DBGFRETURNTYPE_INVALID && enmReturnType < DBGFRETURNTYPE_END, VERR_INVALID_PARAMETER);
+    AssertReturn(enmReturnType >= RTDBGRETURNTYPE_INVALID && enmReturnType < RTDBGRETURNTYPE_END, VERR_INVALID_PARAMETER);
 
     /*
@@ -1510,5 +1443,5 @@
                                       PCDBGFADDRESS pAddrStack,
                                       PCDBGFADDRESS pAddrPC,
-                                      DBGFRETURNTYPE enmReturnType,
+                                      RTDBGRETURNTYPE enmReturnType,
                                       PCDBGFSTACKFRAME *ppFirstFrame)
 {
@@ -1534,5 +1467,5 @@
 VMMR3DECL(int) DBGFR3StackWalkBegin(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFSTACKFRAME *ppFirstFrame)
 {
-    return dbgfR3StackWalkBeginCommon(pUVM, idCpu, enmCodeType, NULL, NULL, NULL, DBGFRETURNTYPE_INVALID, ppFirstFrame);
+    return dbgfR3StackWalkBeginCommon(pUVM, idCpu, enmCodeType, NULL, NULL, NULL, RTDBGRETURNTYPE_INVALID, ppFirstFrame);
 }
 
Index: trunk/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp	(revision 73457)
+++ trunk/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp	(revision 73460)
@@ -473,5 +473,5 @@
                     PCDBGFSTACKFRAME pFirstFrame;
                     rc2 = DBGFR3StackWalkBeginEx(pVM->pUVM, pVCpu->idCpu, DBGFCODETYPE_RING0, &ebp, &esp, &pc,
-                                                 DBGFRETURNTYPE_INVALID, &pFirstFrame);
+                                                 RTDBGRETURNTYPE_INVALID, &pFirstFrame);
                     if (RT_SUCCESS(rc2))
                     {
Index: trunk/src/VBox/VMM/VMMR3/VMMR3.def
===================================================================
--- trunk/src/VBox/VMM/VMMR3/VMMR3.def	(revision 73457)
+++ trunk/src/VBox/VMM/VMMR3/VMMR3.def	(revision 73460)
@@ -207,4 +207,5 @@
     MMR3HeapFree
     MMR3HeapRealloc
+    MMR3HeapAllocU
 
     MMR3HyperAllocOnceNoRel
Index: trunk/src/VBox/VMM/include/DBGFInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/DBGFInternal.h	(revision 73457)
+++ trunk/src/VBox/VMM/include/DBGFInternal.h	(revision 73460)
@@ -153,4 +153,5 @@
 
 
+#ifdef IN_RING3
 /**
  * Guest OS digger instance.
@@ -167,8 +168,9 @@
     uint8_t                     abData[16];
 } DBGFOS;
+#endif
 /** Pointer to guest OS digger instance. */
-typedef DBGFOS *PDBGFOS;
+typedef struct DBGFOS *PDBGFOS;
 /** Pointer to const guest OS digger instance. */
-typedef DBGFOS const *PCDBGFOS;
+typedef struct DBGFOS const *PCDBGFOS;
 
 
@@ -497,4 +499,5 @@
 
 
+#ifdef IN_RING3
 int  dbgfR3AsInit(PUVM pUVM);
 void dbgfR3AsTerm(PUVM pUVM);
@@ -506,4 +509,6 @@
 void dbgfR3OSTermPart1(PUVM pUVM);
 void dbgfR3OSTermPart2(PUVM pUVM);
+int  dbgfR3OSStackUnwindAssist(PUVM pUVM, VMCPUID idCpu, PDBGFSTACKFRAME pFrame, PRTDBGUNWINDSTATE pState,
+                               PCCPUMCTX pInitialCtx, RTDBGAS hAs, uint64_t *puScratch);
 int  dbgfR3RegInit(PUVM pUVM);
 void dbgfR3RegTerm(PUVM pUVM);
@@ -517,7 +522,4 @@
 int  dbgfR3BugCheckInit(PVM pVM);
 
-
-
-#ifdef IN_RING3
 /**
  * DBGF disassembler state (substate of DISSTATE).
@@ -541,7 +543,7 @@
                                         char *pszOutput, uint32_t cbOutput, PDBGFDISSTATE pDisState);
 
+#endif /* IN_RING3 */
+
+/** @} */
+
 #endif
-
-/** @} */
-
-#endif
