Changeset 3593 for trunk


Ignore:
Timestamp:
Sep 30, 2007, 11:41:15 PM (18 years ago)
Author:
bird
Message:

Fixed some unwinding stuff on msc+amd64.

Location:
trunk/kStuff/kProfiler2
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/kStuff/kProfiler2/Makefile.kmk

    r3591 r3593  
    142142        $(PATH_kPrf2)/kPrf2.lib
    143143
     144PROGRAMS += tstlongjmp
     145tstlongjmp_TEMPLATE = kStuffEXE
     146tstlongjmp_CFLAGS.win = -GH -Gh -Zi
     147tstlongjmp_SOURCES = tstlongjmp.c
     148tstlongjmp_LIBS = \
     149        $(PATH_kPrf2)/kPrf2.lib
     150
    144151# Generate the rules
    145152include $(PATH_KBUILD)/subfooter.kmk
  • trunk/kStuff/kProfiler2/prfamd64msc.asm

    r3592 r3593  
    9191        or      r8, rax                 ; param 3 - the timestamp
    9292        mov     [rsp + 20h], r8         ; save the tsc for later use.
    93         lea     rdx, [rsp + 8*8 + 28h]  ; Param 2 - frame pointer (pointer to the return address of the function calling us)
     93        lea     rdx, [rsp + 8*8 + 28h]  ; Param 2 - default frame pointer
    9494        mov     rcx, [rdx]              ; Param 1 - The function address
     95
     96        ; MSC seems to put the _penter both before and after the typical sub rsp, xxh
     97        ; statement as if it cannot quite make up its mind. We'll try adjust for this
     98        ; to make the unwinding a bit more accurate wrt to longjmp/throw. But since
     99        ; there are also an uneven amount of push/pop around the _penter/_pexit we
     100        ; can never really make a perfect job of it. sigh.
     101        cmp     word [rcx - 5 - 4], 08348h  ; sub rsp, imm8
     102        jne     .not_byte_sub
     103        cmp     byte [rcx - 5 - 2], 0ech
     104        jne     .not_byte_sub
     105        movzx   eax, byte [rcx - 5 - 1]     ; imm8
     106        add     rdx, rax
     107        jmp     .call_prf_enter
     108.not_byte_sub:
     109        cmp     word [rcx - 5 - 7], 08148h  ; sub rsp, imm8
     110        jne     .not_dword_sub
     111        cmp     byte [rcx - 5 - 5], 0ech
     112        jne     .not_dword_sub
     113        mov     eax, [rcx - 5 - 4]          ; imm32
     114        add     rdx, rax
     115;        jmp     .call_prf_enter
     116.not_dword_sub:
     117.call_prf_enter:
    95118        call    KPRF_ENTER
    96119        jmp     common_return_path
     
    135158        or      r8, rax                 ; param 3 - the timestamp
    136159        mov     [rsp + 20h], r8         ; save the tsc for later use.
    137         lea     rdx, [rsp + 8*8 + 28h]  ; Param 2 - frame pointer (pointer to the return address of the function calling us)
     160        lea     rdx, [rsp + 8*8 + 28h]  ; Param 2 - frame pointer.
    138161        mov     rcx, [rdx]              ; Param 1 - The function address
     162
     163        ; MSC some times put the _pexit before the add rsp, xxh. To try match up with
     164        ; any adjustments made in _penter, we'll try detect this.
     165        cmp     word [rcx], 08348h      ; add rsp, imm8
     166        jne     .not_byte_sub
     167        cmp     byte [rcx + 2], 0c4h
     168        jne     .not_byte_sub
     169        movzx   eax, byte [rcx + 3]     ; imm8
     170        add     rdx, rax
     171        jmp     .call_prf_leave
     172.not_byte_sub:
     173        cmp     word [rcx], 08148h      ; add rsp, imm32
     174        jne     .not_dword_sub
     175        cmp     byte [rcx + 2], 0c4h
     176        jne     .not_dword_sub
     177        mov     eax, [rcx + 3]          ; imm32
     178        add     rdx, rax
     179;        jmp     .call_prf_leave
     180.not_dword_sub:
     181.call_prf_leave:
    139182        call    KPRF_LEAVE
    140183        jmp common_return_path
  • trunk/kStuff/kProfiler2/prfcore.cpp.h

    r3566 r3593  
    141141/**
    142142 * Unwinds the stack.
     143 *
     144 * On MSC+AMD64 we have to be very very careful here, because the uFramePtr cannot be trusted.
    143145 */
    144146static KU64* KPRF_NAME(UnwindInt)(KPRF_TYPE(P,HDR) pHdr, KPRF_TYPE(P,STACK) pStack, KPRF_TYPE(,UPTR) uPC, KPRF_TYPE(,UPTR) uFramePtr, KU64 TS)
     
    151153    KI32 iFrame = pStack->cFrames - 1;
    152154    KPRF_TYPE(P,FRAME) pFrame = &pStack->aFrames[iFrame];
     155
    153156    /* the most frequent case first. */
     157#if K_OS == K_OS_WINDOWS && K_ARCH == K_ARCH_AMD64
     158    if (    uFramePtr == pFrame->uFramePtr
     159        ||  (   pFrame->uFramePtr < uFramePtr
     160             && iFrame > 0
     161             && pFrame[-1].uFramePtr > uFramePtr))
     162        return KPRF_NAME(UnwindOne)(pHdr, pStack, uPC, TS);
     163#else
    154164    if (uFramePtr == pFrame->uFramePtr)
    155165        return KPRF_NAME(UnwindOne)(pHdr, pStack, uPC, TS);
     166#endif
    156167
    157168    /* none?  */
     
    161172    /* one or more, possibly all */
    162173    KU64 *pCurOverheadTicks = KPRF_NAME(UnwindOne)(pHdr, pStack, uPC, TS);
    163     pFrame++;
     174    pFrame--;
    164175    if (    iFrame > 0
     176#if K_OS == K_OS_WINDOWS && K_ARCH == K_ARCH_AMD64
     177        &&  pFrame->uFramePtr <= uFramePtr
     178        &&  pFrame[-1].uFramePtr > uFramePtr)
     179#else
    165180        &&  pFrame->uFramePtr <= uFramePtr)
     181#endif
    166182    {
    167183        KPRF_TYPE(P,THREAD) pThread = KPRF_OFF2PTR(P,THREAD, pStack->offThread, pHdr);
     
    170186        pCurOverheadTicks = KPRF_NAME(UnwindOne)(pHdr, pStack, uPC, TS);
    171187        iFrame -= 2;
    172         pFrame++;
     188        pFrame--;
     189#if K_OS == K_OS_WINDOWS && K_ARCH == K_ARCH_AMD64
     190        while (     iFrame > 0
     191               &&   pFrame->uFramePtr <= uFramePtr
     192               &&   pFrame[-1].uFramePtr > uFramePtr)
     193#else
    173194        while (     iFrame >= 0
    174195               &&   pFrame->uFramePtr <= uFramePtr)
     196#endif
    175197        {
    176198            pCurOverheadTicks = KPRF_NAME(UnwindOne)(pHdr, pStack, uPC, TS);
    177199            iFrame--;
    178             pFrame++;
     200            pFrame--;
    179201        }
    180202    }
     
    255277    KPRF_TYPE(P,FRAME) pFrame = &pStack->aFrames[iFrame];
    256278    if (    iFrame
     279#if K_OS == K_OS_WINDOWS && K_ARCH == K_ARCH_AMD64
     280        &&  0) /* don't bother her yet because of _penter/_pexit frame problems. */
     281#else
    257282        &&  pThread->uStackBasePtr >= uFramePtr                                     /* ASSUMES stack direction */
    258283        &&  pFrame[-1].uFramePtr + (KPRF_BITS - 8) / 8 < uFramePtr)                 /* ASSUMES stack direction */
     284#endif
    259285    {
    260286        KPRF_NAME(UnwindInt)(pHdr, pStack, uPC, uFramePtr, TS);
  • trunk/kStuff/kProfiler2/prfcore.h.h

    r3566 r3593  
    270270    /** Stack address of this frame.
    271271     * This is used to detect throw and longjmp, and is also used to deal with overflow. (relative address) */
    272     KPRF_TYPE(,UPTR)       uFramePtr;
     272    KPRF_TYPE(,UPTR)        uFramePtr;
    273273    /** Offset (relative to the profiler header) to the function record.
    274274     * This is 0 if we're out of function space. */
     
    293293    /** The stack frames.
    294294     * The actual size of this array is specified in the header. */
    295     KPRF_TYPE(,FRAME)          aFrames[1];
     295    KPRF_TYPE(,FRAME)           aFrames[1];
    296296} KPRF_TYPE(,STACK);
    297297/** Pointer to a stack. */
Note: See TracChangeset for help on using the changeset viewer.