VirtualBox

Changeset 73444 in vbox for trunk/src


Ignore:
Timestamp:
Aug 2, 2018 10:53:28 AM (6 years ago)
Author:
vboxsync
Message:

DBGFStack.cpp: Refactored the code in prep for IPRT move. Added a set of 'sure' registers to the frames so we can display non-volatile register changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/DBGFStack.cpp

    r73399 r73444  
    4040*   Structures and Typedefs                                                                                                      *
    4141*********************************************************************************************************************************/
     42/** Magic value for DBGFUNWINDSTATE::u32Magic (James Moody). */
     43#define DBGFUNWINDSTATE_MAGIC           UINT32_C(0x19250326)
     44/** Magic value for DBGFUNWINDSTATE::u32Magic after use. */
     45#define DBGFUNWINDSTATE_MAGIC_DEAD      UINT32_C(0x20101209)
     46
     47/**
     48 * Register state.
     49 */
     50typedef struct DBGFUNWINDSTATE
     51{
     52    /** Structure magic (DBGFUNWINDSTATE_MAGIC) */
     53    uint32_t            u32Magic;
     54    /** The state architecture. */
     55    RTLDRARCH           enmArch;
     56
     57    /** The program counter register.
     58     * amd64/x86: RIP/EIP/IP
     59     * sparc: PC
     60     * arm32: PC / R15
     61     */
     62    uint64_t            uPc;
     63
     64    /** Return type. */
     65    DBGFRETRUNTYPE      enmRetType;
     66
     67    /** Register state (see enmArch). */
     68    union
     69    {
     70        /** RTLDRARCH_AMD64, RTLDRARCH_X86_32 and RTLDRARCH_X86_16. */
     71        struct
     72        {
     73            /** General purpose registers indexed by X86_GREG_XXX. */
     74            uint64_t    auRegs[16];
     75            /** The frame address. */
     76            RTFAR64     FrameAddr;
     77            /** Set if we're in real or virtual 8086 mode. */
     78            bool        fRealOrV86;
     79            /** The flags register. */
     80            uint64_t    uRFlags;
     81            /** Trap error code. */
     82            uint64_t    uErrCd;
     83            /** Segment registers (indexed by X86_SREG_XXX). */
     84            uint16_t    auSegs[6];
     85
     86            /** Bitmap tracking register we've loaded and which content can possibly be trusted. */
     87            union
     88            {
     89                /** For effective clearing of the bits. */
     90                uint32_t    fAll;
     91                /** Detailed view. */
     92                struct
     93                {
     94                    /** Bitmap indicating whether a GPR was loaded (parallel to auRegs). */
     95                    uint16_t    fRegs;
     96                    /** Bitmap indicating whether a segment register was loaded (parallel to auSegs). */
     97                    uint8_t     fSegs;
     98                    /** Set if uPc was loaded. */
     99                    uint8_t     fPc : 1;
     100                    /** Set if FrameAddr was loaded. */
     101                    uint8_t     fFrameAddr : 1;
     102                    /** Set if uRFlags was loaded. */
     103                    uint8_t     fRFlags : 1;
     104                    /** Set if uErrCd was loaded. */
     105                    uint8_t     fErrCd : 1;
     106                } s;
     107            } Loaded;
     108        } x86;
     109
     110        /** @todo add ARM and others as needed. */
     111    } u;
     112
     113    /**
     114     * Stack read callback.
     115     *
     116     * @returns IPRT status code.
     117     * @param   pThis       Pointer to this structure.
     118     * @param   uSp         The stack pointer address.
     119     * @param   cbToRead    The number of bytes to read.
     120     * @param   pvDst       Where to put the bytes we read.
     121     */
     122    DECLCALLBACKMEMBER(int, pfnReadStack)(struct DBGFUNWINDSTATE *pThis, RTUINTPTR uSp, size_t cbToRead, void *pvDst);
     123    /** User argument (usefule for pfnReadStack). */
     124    void               *pvUser;
     125
     126} DBGFUNWINDSTATE;
     127typedef struct DBGFUNWINDSTATE *PDBGFUNWINDSTATE;
     128typedef struct DBGFUNWINDSTATE const *PCDBGFUNWINDSTATE;
     129
     130static DECLCALLBACK(int) dbgfR3StackReadCallback(PDBGFUNWINDSTATE pThis, RTUINTPTR uSp, size_t cbToRead, void *pvDst);
     131
     132
    42133/**
    43134 * Unwind context.
     
    53144    RTDBGAS     m_hAs;
    54145
    55     uint64_t    m_auRegs[16];
    56     uint64_t    m_uPc;
    57     uint64_t    m_uRFlags;
    58     uint16_t    m_uCs;
    59     uint16_t    m_uSs;
     146    DBGFUNWINDSTATE m_State;
    60147
    61148    RTDBGMOD    m_hCached;
     
    72159    DBGFUNWINDCTX(PUVM pUVM, VMCPUID idCpu, PCCPUMCTX pInitialCtx, RTDBGAS hAs)
    73160    {
     161        m_State.u32Magic     = DBGFUNWINDSTATE_MAGIC;
     162        m_State.enmArch      = RTLDRARCH_AMD64;
     163        m_State.pfnReadStack = dbgfR3StackReadCallback;
     164        m_State.pvUser       = this;
     165        RT_ZERO(m_State.u);
    74166        if (pInitialCtx)
    75167        {
    76             m_auRegs[X86_GREG_xAX] = pInitialCtx->rax;
    77             m_auRegs[X86_GREG_xCX] = pInitialCtx->rcx;
    78             m_auRegs[X86_GREG_xDX] = pInitialCtx->rdx;
    79             m_auRegs[X86_GREG_xBX] = pInitialCtx->rbx;
    80             m_auRegs[X86_GREG_xSP] = pInitialCtx->rsp;
    81             m_auRegs[X86_GREG_xBP] = pInitialCtx->rbp;
    82             m_auRegs[X86_GREG_xSI] = pInitialCtx->rsi;
    83             m_auRegs[X86_GREG_xDI] = pInitialCtx->rdi;
    84             m_auRegs[X86_GREG_x8 ] = pInitialCtx->r8;
    85             m_auRegs[X86_GREG_x9 ] = pInitialCtx->r9;
    86             m_auRegs[X86_GREG_x10] = pInitialCtx->r10;
    87             m_auRegs[X86_GREG_x11] = pInitialCtx->r11;
    88             m_auRegs[X86_GREG_x12] = pInitialCtx->r12;
    89             m_auRegs[X86_GREG_x13] = pInitialCtx->r13;
    90             m_auRegs[X86_GREG_x14] = pInitialCtx->r14;
    91             m_auRegs[X86_GREG_x15] = pInitialCtx->r15;
    92             m_uPc                  = pInitialCtx->rip;
    93             m_uCs                  = pInitialCtx->cs.Sel;
    94             m_uSs                  = pInitialCtx->ss.Sel;
    95             m_uRFlags              = pInitialCtx->rflags.u;
    96         }
    97         else
    98         {
    99             RT_BZERO(m_auRegs, sizeof(m_auRegs));
    100             m_uPc                  = 0;
    101             m_uCs                  = 0;
    102             m_uSs                  = 0;
    103             m_uRFlags              = 0;
     168            m_State.u.x86.auRegs[X86_GREG_xAX] = pInitialCtx->rax;
     169            m_State.u.x86.auRegs[X86_GREG_xCX] = pInitialCtx->rcx;
     170            m_State.u.x86.auRegs[X86_GREG_xDX] = pInitialCtx->rdx;
     171            m_State.u.x86.auRegs[X86_GREG_xBX] = pInitialCtx->rbx;
     172            m_State.u.x86.auRegs[X86_GREG_xSP] = pInitialCtx->rsp;
     173            m_State.u.x86.auRegs[X86_GREG_xBP] = pInitialCtx->rbp;
     174            m_State.u.x86.auRegs[X86_GREG_xSI] = pInitialCtx->rsi;
     175            m_State.u.x86.auRegs[X86_GREG_xDI] = pInitialCtx->rdi;
     176            m_State.u.x86.auRegs[X86_GREG_x8 ] = pInitialCtx->r8;
     177            m_State.u.x86.auRegs[X86_GREG_x9 ] = pInitialCtx->r9;
     178            m_State.u.x86.auRegs[X86_GREG_x10] = pInitialCtx->r10;
     179            m_State.u.x86.auRegs[X86_GREG_x11] = pInitialCtx->r11;
     180            m_State.u.x86.auRegs[X86_GREG_x12] = pInitialCtx->r12;
     181            m_State.u.x86.auRegs[X86_GREG_x13] = pInitialCtx->r13;
     182            m_State.u.x86.auRegs[X86_GREG_x14] = pInitialCtx->r14;
     183            m_State.u.x86.auRegs[X86_GREG_x15] = pInitialCtx->r15;
     184            m_State.uPc                        = pInitialCtx->rip;
     185            m_State.u.x86.uRFlags              = pInitialCtx->rflags.u;
     186            m_State.u.x86.auSegs[X86_SREG_ES]  = pInitialCtx->es.Sel;
     187            m_State.u.x86.auSegs[X86_SREG_CS]  = pInitialCtx->cs.Sel;
     188            m_State.u.x86.auSegs[X86_SREG_SS]  = pInitialCtx->ss.Sel;
     189            m_State.u.x86.auSegs[X86_SREG_DS]  = pInitialCtx->ds.Sel;
     190            m_State.u.x86.auSegs[X86_SREG_GS]  = pInitialCtx->gs.Sel;
     191            m_State.u.x86.auSegs[X86_SREG_FS]  = pInitialCtx->fs.Sel;
     192            m_State.u.x86.fRealOrV86           = CPUMIsGuestInRealOrV86ModeEx(pInitialCtx);
    104193        }
    105194
     
    154243
    155244/**
     245 * @interface_method_impl{DBGFUNWINDSTATE,pfnReadStack}
     246 */
     247static DECLCALLBACK(int) dbgfR3StackReadCallback(PDBGFUNWINDSTATE pThis, RTUINTPTR uSp, size_t cbToRead, void *pvDst)
     248{
     249    Assert(   pThis->enmArch == RTLDRARCH_AMD64
     250           || pThis->enmArch == RTLDRARCH_X86_32);
     251
     252    PDBGFUNWINDCTX pUnwindCtx = (PDBGFUNWINDCTX)pThis->pvUser;
     253    DBGFADDRESS SrcAddr;
     254    int rc = VINF_SUCCESS;
     255    if (   pThis->enmArch == RTLDRARCH_X86_32
     256        || pThis->enmArch == RTLDRARCH_X86_16)
     257    {
     258        if (!pThis->u.x86.fRealOrV86)
     259            rc = DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &SrcAddr, pThis->u.x86.auSegs[X86_SREG_SS], uSp);
     260        else
     261            DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &SrcAddr, uSp + ((uint32_t)pThis->u.x86.auSegs[X86_SREG_SS] << 4));
     262    }
     263    else
     264        DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &SrcAddr, uSp);
     265    if (RT_SUCCESS(rc))
     266        rc = DBGFR3MemRead(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &SrcAddr, pvDst, cbToRead);
     267    return rc;
     268}
     269
     270
     271/**
    156272 * Sets PC and SP.
    157273 *
     
    163279static bool dbgfR3UnwindCtxSetPcAndSp(PDBGFUNWINDCTX pUnwindCtx, PCDBGFADDRESS pAddrPC, PCDBGFADDRESS pAddrStack)
    164280{
     281    Assert(   pUnwindCtx->m_State.enmArch == RTLDRARCH_AMD64
     282           || pUnwindCtx->m_State.enmArch == RTLDRARCH_X86_32);
     283
    165284    if (!DBGFADDRESS_IS_FAR(pAddrPC))
    166         pUnwindCtx->m_uPc = pAddrPC->FlatPtr;
     285        pUnwindCtx->m_State.uPc = pAddrPC->FlatPtr;
    167286    else
    168287    {
    169         pUnwindCtx->m_uPc = pAddrPC->off;
    170         pUnwindCtx->m_uCs = pAddrPC->Sel;
     288        pUnwindCtx->m_State.uPc                      = pAddrPC->off;
     289        pUnwindCtx->m_State.u.x86.auSegs[X86_SREG_CS] = pAddrPC->Sel;
    171290    }
    172291    if (!DBGFADDRESS_IS_FAR(pAddrStack))
    173         pUnwindCtx->m_auRegs[X86_GREG_xSP] = pAddrStack->FlatPtr;
     292        pUnwindCtx->m_State.u.x86.auRegs[X86_GREG_xSP] = pAddrStack->FlatPtr;
    174293    else
    175294    {
    176         pUnwindCtx->m_auRegs[X86_GREG_xSP] = pAddrStack->off;
    177         pUnwindCtx->m_uSs                  = pAddrStack->Sel;
     295        pUnwindCtx->m_State.u.x86.auRegs[X86_GREG_xSP] = pAddrStack->off;
     296        pUnwindCtx->m_State.u.x86.auSegs[X86_SREG_SS]  = pAddrStack->Sel;
    178297    }
    179298    return true;
     
    184303 * Try read a 16-bit value off the stack.
    185304 *
     305 * @returns pfnReadStack result.
    186306 * @param   pUnwindCtx      The unwind context.
    187307 * @param   uSrcAddr        The stack address.
    188308 * @param   puDst           The read destination.
    189309 */
    190 static void dbgfR3UnwindCtxLoadU16(PDBGFUNWINDCTX pUnwindCtx, uint64_t uSrcAddr, uint16_t *puDst)
    191 {
    192     DBGFADDRESS SrcAddr;
    193     DBGFR3MemRead(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu,
    194                   DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &SrcAddr, uSrcAddr),
    195                   puDst, sizeof(*puDst));
     310DECLINLINE(int) dbgUnwindLoadStackU16(PDBGFUNWINDSTATE pThis, uint64_t uSrcAddr, uint16_t *puDst)
     311{
     312    return pThis->pfnReadStack(pThis, uSrcAddr, sizeof(*puDst), puDst);
    196313}
    197314
     
    200317 * Try read a 64-bit value off the stack.
    201318 *
     319 * @returns pfnReadStack result.
    202320 * @param   pUnwindCtx      The unwind context.
    203321 * @param   uSrcAddr        The stack address.
    204322 * @param   puDst           The read destination.
    205323 */
    206 static void dbgfR3UnwindCtxLoadU64(PDBGFUNWINDCTX pUnwindCtx, uint64_t uSrcAddr, uint64_t *puDst)
    207 {
    208     DBGFADDRESS SrcAddr;
    209     DBGFR3MemRead(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu,
    210                   DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &SrcAddr, uSrcAddr),
    211                   puDst, sizeof(*puDst));
     324DECLINLINE(int) dbgUnwindLoadStackU64(PDBGFUNWINDSTATE pThis, uint64_t uSrcAddr, uint64_t *puDst)
     325{
     326    return pThis->pfnReadStack(pThis, uSrcAddr, sizeof(*puDst), puDst);
    212327}
    213328
     
    217332 *
    218333 * @returns RVA of unwind info on success, UINT32_MAX on failure.
    219  * @param   paFunctions     The table to lookup @a offFunctionRva in.
     334 * @param   paFunctions     The table to lookup @a uRva in.
    220335 * @param   iEnd            Size of the table.
    221336 * @param   uRva            The RVA of the function we want.
     
    244359 *
    245360 * @returns true.
    246  * @param   pUnwindCtx      The unwind context.
     361 * @param   pThis           The unwind state being worked.
    247362 * @param   fErrCd          Non-zero if there is an error code on the stack.
    248  * @param   pAddrFrame      Where to return the frame pointer.
    249  * @param   penmRetType     Where to return the return type.
    250  */
    251 static bool dbgfR3UnwindCtxDoOneIRet(PDBGFUNWINDCTX pUnwindCtx, uint8_t fErrCd,
    252                                      PDBGFADDRESS pAddrFrame, DBGFRETURNTYPE *penmRetType)
     363 */
     364static bool dbgUnwindPeAmd64DoOneIRet(PDBGFUNWINDSTATE pThis, uint8_t fErrCd)
    253365{
    254366    Assert(fErrCd <= 1);
    255     if (fErrCd)
    256         pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8; /* error code */
    257 
    258     *penmRetType = DBGFRETURNTYPE_IRET64;
    259     DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, pAddrFrame,
    260                        pUnwindCtx->m_auRegs[X86_GREG_xSP] - /* pretend rbp is pushed on the stack */ 8);
    261 
    262     dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP], &pUnwindCtx->m_uPc);
    263     pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8; /* RIP */
    264 
    265     dbgfR3UnwindCtxLoadU16(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP], &pUnwindCtx->m_uCs);
    266     pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8; /* CS */
    267 
    268     dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP], &pUnwindCtx->m_uRFlags);
    269     pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8; /* EFLAGS */
    270 
    271     uint64_t uNewRsp = (pUnwindCtx->m_auRegs[X86_GREG_xSP] - 8) & ~(uint64_t)15;
    272     dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP], &uNewRsp);
    273     pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8; /* RSP */
    274 
    275     dbgfR3UnwindCtxLoadU16(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP], &pUnwindCtx->m_uSs);
    276     pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8; /* SS */
    277 
    278     pUnwindCtx->m_auRegs[X86_GREG_xSP] = uNewRsp;
     367    if (!fErrCd)
     368        pThis->u.x86.Loaded.s.fErrCd = 0;
     369    else
     370    {
     371        pThis->u.x86.uErrCd = 0;
     372        pThis->u.x86.Loaded.s.fErrCd = 1;
     373        dbgUnwindLoadStackU64(pThis, pThis->u.x86.auRegs[X86_GREG_xSP], &pThis->u.x86.uErrCd);
     374        pThis->u.x86.auRegs[X86_GREG_xSP] += 8;
     375    }
     376
     377    pThis->enmRetType = DBGFRETURNTYPE_IRET64;
     378    pThis->u.x86.FrameAddr.off = pThis->u.x86.auRegs[X86_GREG_xSP] - /* pretend rbp is pushed on the stack */ 8;
     379    pThis->u.x86.FrameAddr.sel = pThis->u.x86.auSegs[X86_SREG_SS];
     380
     381    dbgUnwindLoadStackU64(pThis, pThis->u.x86.auRegs[X86_GREG_xSP], &pThis->uPc);
     382    pThis->u.x86.auRegs[X86_GREG_xSP] += 8; /* RIP */
     383
     384    dbgUnwindLoadStackU16(pThis, pThis->u.x86.auRegs[X86_GREG_xSP], &pThis->u.x86.auSegs[X86_SREG_CS]);
     385    pThis->u.x86.auRegs[X86_GREG_xSP] += 8; /* CS */
     386
     387    dbgUnwindLoadStackU64(pThis, pThis->u.x86.auRegs[X86_GREG_xSP], &pThis->u.x86.uRFlags);
     388    pThis->u.x86.auRegs[X86_GREG_xSP] += 8; /* EFLAGS */
     389
     390    uint64_t uNewRsp = (pThis->u.x86.auRegs[X86_GREG_xSP] - 8) & ~(uint64_t)15;
     391    dbgUnwindLoadStackU64(pThis, pThis->u.x86.auRegs[X86_GREG_xSP], &uNewRsp);
     392    pThis->u.x86.auRegs[X86_GREG_xSP] += 8; /* RSP */
     393
     394    dbgUnwindLoadStackU16(pThis, pThis->u.x86.auRegs[X86_GREG_xSP], &pThis->u.x86.auSegs[X86_SREG_SS]);
     395    pThis->u.x86.auRegs[X86_GREG_xSP] += 8; /* SS */
     396
     397    pThis->u.x86.auRegs[X86_GREG_xSP] = uNewRsp;
     398
     399    pThis->u.x86.Loaded.s.fRegs        |= RT_BIT(X86_GREG_xSP);
     400    pThis->u.x86.Loaded.s.fSegs        |= RT_BIT(X86_SREG_CS) | RT_BIT(X86_SREG_SS);
     401    pThis->u.x86.Loaded.s.fPc           = 1;
     402    pThis->u.x86.Loaded.s.fFrameAddr    = 1;
     403    pThis->u.x86.Loaded.s.fRFlags       = 1;
    279404    return true;
    280405}
     
    285410 *
    286411 * @returns true on success, false on failure.
    287  * @param   pUnwindCtx      The unwind context.
     412 * @param   hMod            The debug module to retrieve unwind info from.
     413 * @param   paFunctions     The table to lookup @a uRvaRip in.
     414 * @param   cFunctions      Size of the lookup table.
    288415 * @param   uRvaRip         The RVA of the RIP.
    289  * @param   pAddrFrame      Where to return the frame pointer.
    290  * @param   penmRetType     Where to return the return type.
    291  */
    292 static bool dbgfR3UnwindCtxDoOneFrameCached(PDBGFUNWINDCTX pUnwindCtx, uint32_t uRvaRip,
    293                                             PDBGFADDRESS pAddrFrame, DBGFRETURNTYPE *penmRetType)
     416 *
     417 * @todo Move this down to IPRT in the ldrPE.cpp / dbgmodcodeview.cpp area.
     418 */
     419static bool dbgUnwindPeAmd64DoOne(RTDBGMOD hMod, PCIMAGE_RUNTIME_FUNCTION_ENTRY paFunctions, size_t cFunctions,
     420                                  PDBGFUNWINDSTATE pThis, uint32_t uRvaRip)
    294421{
    295422    /*
    296423     * Lookup the unwind info RVA and try read it.
    297424     */
    298     PCIMAGE_RUNTIME_FUNCTION_ENTRY pEntry = dbgfR3UnwindCtxLookupUnwindInfoRva(pUnwindCtx->m_paFunctions,
    299                                                                                pUnwindCtx->m_cFunctions, uRvaRip);
     425    PCIMAGE_RUNTIME_FUNCTION_ENTRY pEntry = dbgfR3UnwindCtxLookupUnwindInfoRva(paFunctions, cFunctions, uRvaRip);
    300426    if (pEntry)
    301427    {
     
    322448            uBuf.uRva = pEntry->UnwindInfoAddress;
    323449            size_t cbBuf = sizeof(uBuf);
    324             int rc = RTDbgModImageQueryProp(pUnwindCtx->m_hCached, RTLDRPROP_UNWIND_INFO, &uBuf, cbBuf, &cbBuf);
     450            int rc = RTDbgModImageQueryProp(hMod, RTLDRPROP_UNWIND_INFO, &uBuf, cbBuf, &cbBuf);
    325451            if (RT_FAILURE(rc))
    326452                return false;
     
    402528                {
    403529                    Assert(pInfo->aOpcodes[iOpcode].u.CodeOffset <= offPc);
    404                     switch (pInfo->aOpcodes[iOpcode].u.UnwindOp)
     530                    uint8_t const uOpInfo   = pInfo->aOpcodes[iOpcode].u.OpInfo;
     531                    uint8_t const uUnwindOp = pInfo->aOpcodes[iOpcode].u.UnwindOp;
     532                    switch (uUnwindOp)
    405533                    {
    406534                        case IMAGE_AMD64_UWOP_PUSH_NONVOL:
    407                             pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8;
    408                             dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP],
    409                                                    &pUnwindCtx->m_auRegs[pInfo->aOpcodes[iOpcode].u.OpInfo]);
     535                            pThis->u.x86.auRegs[X86_GREG_xSP] += 8;
     536                            dbgUnwindLoadStackU64(pThis, pThis->u.x86.auRegs[X86_GREG_xSP], &pThis->u.x86.auRegs[uOpInfo]);
     537                            pThis->u.x86.Loaded.s.fRegs |= RT_BIT(uOpInfo);
    410538                            iOpcode++;
    411539                            break;
    412540
    413541                        case IMAGE_AMD64_UWOP_ALLOC_LARGE:
    414                             if (pInfo->aOpcodes[iOpcode].u.OpInfo == 0)
     542                            if (uOpInfo == 0)
    415543                            {
    416544                                iOpcode += 2;
    417545                                AssertBreak(iOpcode <= cOpcodes);
    418                                 pUnwindCtx->m_auRegs[X86_GREG_xSP] += pInfo->aOpcodes[iOpcode - 1].FrameOffset * 8;
     546                                pThis->u.x86.auRegs[X86_GREG_xSP] += pInfo->aOpcodes[iOpcode - 1].FrameOffset * 8;
    419547                            }
    420548                            else
     
    422550                                iOpcode += 3;
    423551                                AssertBreak(iOpcode <= cOpcodes);
    424                                 pUnwindCtx->m_auRegs[X86_GREG_xSP] += RT_MAKE_U32(pInfo->aOpcodes[iOpcode - 2].FrameOffset,
     552                                pThis->u.x86.auRegs[X86_GREG_xSP] += RT_MAKE_U32(pInfo->aOpcodes[iOpcode - 2].FrameOffset,
    425553                                                                                  pInfo->aOpcodes[iOpcode - 1].FrameOffset);
    426554                            }
     
    429557                        case IMAGE_AMD64_UWOP_ALLOC_SMALL:
    430558                            AssertBreak(iOpcode <= cOpcodes);
    431                             pUnwindCtx->m_auRegs[X86_GREG_xSP] += pInfo->aOpcodes[iOpcode].u.OpInfo * 8 + 8;
     559                            pThis->u.x86.auRegs[X86_GREG_xSP] += uOpInfo * 8 + 8;
    432560                            iOpcode++;
    433561                            break;
    434562
    435563                        case IMAGE_AMD64_UWOP_SET_FPREG:
    436                             iFrameReg = pInfo->aOpcodes[iOpcode].u.OpInfo;
     564                            iFrameReg = uOpInfo;
    437565                            offFrameReg = pInfo->FrameOffset * 16;
    438566                            iOpcode++;
     
    442570                        case IMAGE_AMD64_UWOP_SAVE_NONVOL_FAR:
    443571                        {
    444                             bool const     fFar  = pInfo->aOpcodes[iOpcode].u.UnwindOp == IMAGE_AMD64_UWOP_SAVE_NONVOL_FAR;
    445                             unsigned const iGreg = pInfo->aOpcodes[iOpcode].u.OpInfo;
    446                             uint32_t       off   = 0;
     572                            uint32_t off = 0;
    447573                            iOpcode++;
    448574                            if (iOpcode < cOpcodes)
     
    450576                                off = pInfo->aOpcodes[iOpcode].FrameOffset;
    451577                                iOpcode++;
    452                                 if (fFar && iOpcode < cOpcodes)
     578                                if (uUnwindOp == IMAGE_AMD64_UWOP_SAVE_NONVOL_FAR && iOpcode < cOpcodes)
    453579                                {
    454580                                    off |= (uint32_t)pInfo->aOpcodes[iOpcode].FrameOffset << 16;
     
    457583                            }
    458584                            off *= 8;
    459                             dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP] + off, &pUnwindCtx->m_auRegs[iGreg]);
     585                            dbgUnwindLoadStackU64(pThis, pThis->u.x86.auRegs[X86_GREG_xSP] + off, &pThis->u.x86.auRegs[uOpInfo]);
     586                            pThis->u.x86.Loaded.s.fRegs |= RT_BIT(uOpInfo);
    460587                            break;
    461588                        }
     
    470597
    471598                        case IMAGE_AMD64_UWOP_PUSH_MACHFRAME:
    472                             return dbgfR3UnwindCtxDoOneIRet(pUnwindCtx, pInfo->aOpcodes[iOpcode].u.OpInfo, pAddrFrame, penmRetType);
     599                            return dbgUnwindPeAmd64DoOneIRet(pThis, uOpInfo);
    473600
    474601                        case IMAGE_AMD64_UWOP_EPILOG:
     
    480607
    481608                        default:
    482                             AssertMsgFailedReturn(("%u\n", pInfo->aOpcodes[iOpcode].u.UnwindOp), false);
     609                            AssertMsgFailedReturn(("%u\n", uUnwindOp), false);
    483610                    }
    484611                }
     
    495622                while (iOpcode < cOpcodes)
    496623                {
    497                     switch (pInfo->aOpcodes[iOpcode].u.UnwindOp)
     624                    uint8_t const uOpInfo   = pInfo->aOpcodes[iOpcode].u.OpInfo;
     625                    uint8_t const uUnwindOp = pInfo->aOpcodes[iOpcode].u.UnwindOp;
     626                    switch (uUnwindOp)
    498627                    {
    499628                        case IMAGE_AMD64_UWOP_PUSH_NONVOL:
    500                             pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8;
     629                            pThis->u.x86.auRegs[X86_GREG_xSP] += 8;
    501630                            if (offEpilog == 0)
    502                                 dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP],
    503                                                        &pUnwindCtx->m_auRegs[pInfo->aOpcodes[iOpcode].u.OpInfo]);
     631                            {
     632                                dbgUnwindLoadStackU64(pThis, pThis->u.x86.auRegs[X86_GREG_xSP], &pThis->u.x86.auRegs[uOpInfo]);
     633                                pThis->u.x86.Loaded.s.fRegs |= RT_BIT(uOpInfo);
     634                            }
    504635                            else
    505636                            {
    506637                                /* Decrement offEpilog by estimated POP instruction length. */
    507638                                offEpilog -= 1;
    508                                 if (offEpilog > 0 && pInfo->aOpcodes[iOpcode].u.OpInfo >= 8)
     639                                if (offEpilog > 0 && uOpInfo >= 8)
    509640                                    offEpilog -= 1;
    510641                            }
     
    513644
    514645                        case IMAGE_AMD64_UWOP_PUSH_MACHFRAME: /* Must terminate an epilog, so always execute this. */
    515                             return dbgfR3UnwindCtxDoOneIRet(pUnwindCtx, pInfo->aOpcodes[iOpcode].u.OpInfo, pAddrFrame, penmRetType);
     646                            return dbgUnwindPeAmd64DoOneIRet(pThis, uOpInfo);
    516647
    517648                        case IMAGE_AMD64_UWOP_ALLOC_SMALL:
     
    531662
    532663                        default:
    533                             AssertMsgFailedReturn(("%u\n", pInfo->aOpcodes[iOpcode].u.UnwindOp), false);
     664                            AssertMsgFailedReturn(("%u\n", uUnwindOp), false);
    534665                    }
    535666                }
     
    549680         * RSP should now give us the return address, so perform a RET.
    550681         */
    551         *penmRetType = DBGFRETURNTYPE_NEAR64;
    552         DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, pAddrFrame,
    553                            pUnwindCtx->m_auRegs[X86_GREG_xSP] - /* pretend rbp is pushed on the stack */ 8);
    554 
    555         dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP], &pUnwindCtx->m_uPc);
    556         pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8;
     682        pThis->enmRetType = DBGFRETURNTYPE_NEAR64;
     683
     684        pThis->u.x86.FrameAddr.off = pThis->u.x86.auRegs[X86_GREG_xSP] - /* pretend rbp is pushed on the stack */ 8;
     685        pThis->u.x86.FrameAddr.sel = pThis->u.x86.auSegs[X86_SREG_SS];
     686        pThis->u.x86.Loaded.s.fFrameAddr = 1;
     687
     688        dbgUnwindLoadStackU64(pThis, pThis->u.x86.auRegs[X86_GREG_xSP], &pThis->uPc);
     689        pThis->u.x86.auRegs[X86_GREG_xSP] += 8;
     690        pThis->u.x86.Loaded.s.fPc = 1;
    557691        return true;
    558692    }
    559693
    560     RT_NOREF_PV(pAddrFrame);
    561694    return false;
    562695}
     
    568701 * @returns true on success, false on failure.
    569702 * @param   pUnwindCtx      The unwind context.
    570  * @param   pAddrFrame      Where to return the frame pointer.
    571  * @param   penmRetType     Where to return the return type.
    572  */
    573 static bool dbgfR3UnwindCtxDoOneFrame(PDBGFUNWINDCTX pUnwindCtx, PDBGFADDRESS pAddrFrame, DBGFRETURNTYPE *penmRetType)
     703 */
     704static bool dbgfR3UnwindCtxDoOneFrame(PDBGFUNWINDCTX pUnwindCtx)
    574705{
    575706    /*
    576707     * Hope for the same module as last time around.
    577708     */
    578     RTUINTPTR offCache = pUnwindCtx->m_uPc - pUnwindCtx->m_uCachedMapping;
     709    RTUINTPTR offCache = pUnwindCtx->m_State.uPc - pUnwindCtx->m_uCachedMapping;
    579710    if (offCache < pUnwindCtx->m_cbCachedMapping)
    580         return dbgfR3UnwindCtxDoOneFrameCached(pUnwindCtx, offCache, pAddrFrame, penmRetType);
     711        return dbgUnwindPeAmd64DoOne(pUnwindCtx->m_hCached, pUnwindCtx->m_paFunctions, pUnwindCtx->m_cFunctions,
     712                                     &pUnwindCtx->m_State, offCache);
    581713
    582714    /*
     
    586718    RTUINTPTR       uBase   = 0;
    587719    RTDBGSEGIDX     idxSeg  = NIL_RTDBGSEGIDX;
    588     int rc = RTDbgAsModuleByAddr(pUnwindCtx->m_hAs, pUnwindCtx->m_uPc, &hDbgMod, &uBase, &idxSeg);
     720    int rc = RTDbgAsModuleByAddr(pUnwindCtx->m_hAs, pUnwindCtx->m_State.uPc, &hDbgMod, &uBase, &idxSeg);
    589721    if (RT_SUCCESS(rc))
    590722    {
     
    622754                        pUnwindCtx->m_cFunctions   = cbNeeded / sizeof(*pUnwindCtx->m_paFunctions);
    623755
    624                         return dbgfR3UnwindCtxDoOneFrameCached(pUnwindCtx, pUnwindCtx->m_uPc - pUnwindCtx->m_uCachedMapping,
    625                                                                pAddrFrame, penmRetType);
     756                        return dbgUnwindPeAmd64DoOne(pUnwindCtx->m_hCached, pUnwindCtx->m_paFunctions, pUnwindCtx->m_cFunctions,
     757                                                     &pUnwindCtx->m_State, pUnwindCtx->m_State.uPc - pUnwindCtx->m_uCachedMapping);
    626758                    }
    627759                    RTMemFree(pvBuf);
     
    659791        *pcbRead = cb;
    660792    return rc;
     793}
     794
     795static int dbgfR3StackWalkCollectRegisterChanges(PUVM pUVM, PDBGFSTACKFRAME pFrame, PDBGFUNWINDSTATE pState)
     796{
     797    pFrame->cSureRegs  = 0;
     798    pFrame->paSureRegs = NULL;
     799
     800    if (   pState->enmArch == RTLDRARCH_AMD64
     801        || pState->enmArch == RTLDRARCH_X86_32
     802        || pState->enmArch == RTLDRARCH_X86_16)
     803    {
     804        if (pState->u.x86.Loaded.fAll)
     805        {
     806            /*
     807             * Count relevant registers.
     808             */
     809            uint32_t cRegs = 0;
     810            if (pState->u.x86.Loaded.s.fRegs)
     811                for (uint32_t f = 1; f < RT_BIT_32(RT_ELEMENTS(pState->u.x86.auRegs)); f <<= 1)
     812                    if (pState->u.x86.Loaded.s.fRegs & f)
     813                        cRegs++;
     814            if (pState->u.x86.Loaded.s.fSegs)
     815                for (uint32_t f = 1; f < RT_BIT_32(RT_ELEMENTS(pState->u.x86.auSegs)); f <<= 1)
     816                    if (pState->u.x86.Loaded.s.fSegs & f)
     817                        cRegs++;
     818            if (pState->u.x86.Loaded.s.fRFlags)
     819                cRegs++;
     820            if (pState->u.x86.Loaded.s.fErrCd)
     821                cRegs++;
     822            if (cRegs > 0)
     823            {
     824                /*
     825                 * Allocate the arrays.
     826                 */
     827                PDBGFREGVALEX paSureRegs = (PDBGFREGVALEX)MMR3HeapAllocZU(pUVM, MM_TAG_DBGF_STACK, sizeof(DBGFREGVALEX) * cRegs);
     828                AssertReturn(paSureRegs, VERR_NO_MEMORY);
     829                pFrame->paSureRegs = paSureRegs;
     830                pFrame->cSureRegs  = cRegs;
     831
     832                /*
     833                 * Popuplate the arrays.
     834                 */
     835                uint32_t iReg = 0;
     836                if (pState->u.x86.Loaded.s.fRegs)
     837                    for (uint32_t i = 1; i < RT_ELEMENTS(pState->u.x86.auRegs); i++)
     838                        if (pState->u.x86.Loaded.s.fRegs & RT_BIT(i))
     839                        {
     840                            paSureRegs[iReg].Value.u64 = pState->u.x86.auRegs[i];
     841                            paSureRegs[iReg].enmType   = DBGFREGVALTYPE_U64;
     842                            paSureRegs[iReg].enmReg    = (DBGFREG)(DBGFREG_RAX + i);
     843                            iReg++;
     844                        }
     845
     846                if (pState->u.x86.Loaded.s.fSegs)
     847                    for (uint32_t i = 1; i < RT_ELEMENTS(pState->u.x86.auSegs); i++)
     848                        if (pState->u.x86.Loaded.s.fSegs & RT_BIT(i))
     849                        {
     850                            paSureRegs[iReg].Value.u16 = pState->u.x86.auSegs[i];
     851                            paSureRegs[iReg].enmType   = DBGFREGVALTYPE_U16;
     852                            switch (i)
     853                            {
     854                                case X86_SREG_ES: paSureRegs[iReg].enmReg = DBGFREG_ES; break;
     855                                case X86_SREG_CS: paSureRegs[iReg].enmReg = DBGFREG_CS; break;
     856                                case X86_SREG_SS: paSureRegs[iReg].enmReg = DBGFREG_SS; break;
     857                                case X86_SREG_DS: paSureRegs[iReg].enmReg = DBGFREG_DS; break;
     858                                case X86_SREG_FS: paSureRegs[iReg].enmReg = DBGFREG_FS; break;
     859                                case X86_SREG_GS: paSureRegs[iReg].enmReg = DBGFREG_GS; break;
     860                                default:          AssertFailedBreak();
     861                            }
     862                            iReg++;
     863                        }
     864
     865                if (iReg < cRegs)
     866                {
     867                    if (pState->u.x86.Loaded.s.fRFlags)
     868                    {
     869                        paSureRegs[iReg].Value.u64 = pState->u.x86.uRFlags;
     870                        paSureRegs[iReg].enmType   = DBGFREGVALTYPE_U64;
     871                        paSureRegs[iReg].enmReg    = DBGFREG_RFLAGS;
     872                        iReg++;
     873                    }
     874                    if (pState->u.x86.Loaded.s.fErrCd)
     875                    {
     876                        paSureRegs[iReg].Value.u64 = pState->u.x86.uErrCd;
     877                        paSureRegs[iReg].enmType   = DBGFREGVALTYPE_U64;
     878                        paSureRegs[iReg].enmReg    = DBGFREG_END;
     879                        paSureRegs[iReg].pszName   = "trap-errcd";
     880                        iReg++;
     881                    }
     882                }
     883                Assert(iReg == cRegs);
     884            }
     885        }
     886    }
     887
     888    return VINF_SUCCESS;
    661889}
    662890
     
    707935                pFrame->enmReturnFrameReturnType = DBGFRETURNTYPE_INVALID;
    708936            }
     937        }
     938    }
     939
     940    /*
     941     * Enagage the OS layer and collect register changes.
     942     */
     943    if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO)
     944    {
     945        /** @todo engage the OS buggers to identify trap frames and update unwindctx accordingly. */
     946        if (!fFirst)
     947        {
     948            int rc = dbgfR3StackWalkCollectRegisterChanges(pUnwindCtx->m_pUVM, pFrame, &pUnwindCtx->m_State);
     949            if (RT_FAILURE(rc))
     950                return rc;
    709951        }
    710952    }
     
    7841026            || pFrame->enmReturnType == DBGFRETURNTYPE_IRET64)
    7851027            DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnFrame,
    786                                  pUnwindCtx->m_uSs, pUnwindCtx->m_auRegs[X86_GREG_xBP]);
     1028                                 pUnwindCtx->m_State.u.x86.auSegs[X86_SREG_SS], pUnwindCtx->m_State.u.x86.auRegs[X86_GREG_xBP]);
    7871029        else if (pFrame->enmReturnType == DBGFRETURNTYPE_IRET32_V86)
    7881030            DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &pFrame->AddrReturnFrame,
    789                                ((uint32_t)pUnwindCtx->m_uSs << 4) + pUnwindCtx->m_auRegs[X86_GREG_xBP]);
     1031                                 ((uint32_t)pUnwindCtx->m_State.u.x86.auSegs[X86_SREG_SS] << 4)
     1032                               + pUnwindCtx->m_State.u.x86.auRegs[X86_GREG_xBP]);
    7901033        else
    7911034        {
    792             pFrame->AddrReturnFrame.off      = pUnwindCtx->m_auRegs[X86_GREG_xBP];
     1035            pFrame->AddrReturnFrame.off      = pUnwindCtx->m_State.u.x86.auRegs[X86_GREG_xBP];
    7931036            pFrame->AddrReturnFrame.FlatPtr += pFrame->AddrReturnFrame.off - pFrame->AddrFrame.off;
    7941037        }
     
    8531096            || pFrame->enmReturnType == DBGFRETURNTYPE_IRET64)
    8541097            DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnStack,
    855                                  pUnwindCtx->m_uSs, pUnwindCtx->m_auRegs[X86_GREG_xSP]);
     1098                                 pUnwindCtx->m_State.u.x86.auSegs[X86_SREG_SS], pUnwindCtx->m_State.u.x86.auRegs[X86_GREG_xSP]);
    8561099        else if (pFrame->enmReturnType == DBGFRETURNTYPE_IRET32_V86)
    8571100            DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &pFrame->AddrReturnStack,
    858                                ((uint32_t)pUnwindCtx->m_uSs << 4) + pUnwindCtx->m_auRegs[X86_GREG_xSP]);
     1101                                 ((uint32_t)pUnwindCtx->m_State.u.x86.auSegs[X86_SREG_SS] << 4)
     1102                               + pUnwindCtx->m_State.u.x86.auRegs[X86_GREG_xSP]);
    8591103        else
    8601104        {
    861             pFrame->AddrReturnStack.off      = pUnwindCtx->m_auRegs[X86_GREG_xSP];
     1105            pFrame->AddrReturnStack.off      = pUnwindCtx->m_State.u.x86.auRegs[X86_GREG_xSP];
    8621106            pFrame->AddrReturnStack.FlatPtr += pFrame->AddrReturnStack.off - pFrame->AddrStack.off;
    8631107        }
     
    8771121        if (DBGFReturnTypeIsNear(pFrame->enmReturnType))
    8781122        {
    879             pFrame->AddrReturnPC.off      = pUnwindCtx->m_uPc;
     1123            pFrame->AddrReturnPC.off      = pUnwindCtx->m_State.uPc;
    8801124            pFrame->AddrReturnPC.FlatPtr += pFrame->AddrReturnPC.off - pFrame->AddrPC.off;
    8811125        }
    8821126        else
    8831127            DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC,
    884                                  pUnwindCtx->m_uCs, pUnwindCtx->m_uPc);
     1128                                 pUnwindCtx->m_State.u.x86.auSegs[X86_SREG_CS], pUnwindCtx->m_State.uPc);
    8851129    }
    8861130    else
     
    9831227        }
    9841228        /** @todo Reevaluate CS if the previous frame return type isn't near. */
    985 
    986         DBGFADDRESS    AddrReturnFrame = pFrame->AddrReturnFrame;
    987         DBGFRETURNTYPE enmReturnType   = pFrame->enmReturnType;
    988         if (dbgfR3UnwindCtxDoOneFrame(pUnwindCtx, &AddrReturnFrame, &enmReturnType))
    989         {
     1229        if (   pUnwindCtx->m_State.enmArch == RTLDRARCH_AMD64
     1230            || pUnwindCtx->m_State.enmArch == RTLDRARCH_X86_32
     1231            || pUnwindCtx->m_State.enmArch == RTLDRARCH_X86_16)
     1232            pUnwindCtx->m_State.u.x86.Loaded.fAll = 0;
     1233        else
     1234            AssertFailed();
     1235        if (dbgfR3UnwindCtxDoOneFrame(pUnwindCtx))
     1236        {
     1237            DBGFADDRESS AddrReturnFrame = pFrame->AddrReturnFrame;
     1238            int rc = DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &AddrReturnFrame,
     1239                                          pUnwindCtx->m_State.u.x86.FrameAddr.sel, pUnwindCtx->m_State.u.x86.FrameAddr.off);
     1240            if (RT_SUCCESS(rc))
     1241                pFrame->AddrReturnFrame      = AddrReturnFrame;
     1242            pFrame->enmReturnFrameReturnType = pUnwindCtx->m_State.enmRetType;
    9901243            pFrame->fFlags                  |= DBGFSTACKFRAME_FLAGS_UNWIND_INFO_RET;
    991             pFrame->AddrReturnFrame          = AddrReturnFrame;
    992             pFrame->enmReturnFrameReturnType = enmReturnType;
    9931244        }
    9941245    }
     
    10941345        else if (   RT_SUCCESS(rc)
    10951346                 && dbgfR3UnwindCtxSetPcAndSp(&UnwindCtx, &pCur->AddrPC, &pCur->AddrStack)
    1096                  && dbgfR3UnwindCtxDoOneFrame(&UnwindCtx, &pCur->AddrFrame, &pCur->enmReturnType))
    1097         {
     1347                 && dbgfR3UnwindCtxDoOneFrame(&UnwindCtx))
     1348        {
     1349            pCur->enmReturnType = UnwindCtx.m_State.enmRetType;
    10981350            pCur->fFlags |= DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO;
     1351            rc = DBGFR3AddrFromSelOff(UnwindCtx.m_pUVM, UnwindCtx.m_idCpu, &pCur->AddrFrame,
     1352                                      UnwindCtx.m_State.u.x86.FrameAddr.sel, UnwindCtx.m_State.u.x86.FrameAddr.off);
    10991353        }
    11001354        else if (enmCodeType != DBGFCODETYPE_GUEST)
     
    11331387    while (!(pCur->fFlags & (DBGFSTACKFRAME_FLAGS_LAST | DBGFSTACKFRAME_FLAGS_MAX_DEPTH | DBGFSTACKFRAME_FLAGS_LOOP)))
    11341388    {
     1389        Next.cSureRegs  = 0;
     1390        Next.paSureRegs = NULL;
     1391
    11351392        /* try walk. */
    11361393        rc = dbgfR3StackWalk(&UnwindCtx, &Next, false /*fFirst*/);
     
    13431600        RTDbgLineFree(pCur->pLineReturnPC);
    13441601
     1602        if (pCur->paSureRegs)
     1603        {
     1604            MMR3HeapFree(pCur->paSureRegs);
     1605            pCur->paSureRegs = NULL;
     1606            pCur->cSureRegs = 0;
     1607        }
     1608
    13451609        pCur->pNextInternal = NULL;
    13461610        pCur->pFirstInternal = NULL;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette