Win32 - Backtrace from C code

后端 未结 3 1686
离开以前
离开以前 2020-11-28 21:27

I\'m currently looking for a way to get backtrace information under Windows, from C code (no C++).

I\'m building a cross-platform C library, with reference-counting

3条回答
  •  无人及你
    2020-11-28 22:15

    @Jon Bright: You say "who known whether the stack is valid...": Well there's a way to find out, as the stack addresses are known. Assuming you need a trace in the current thread, of course:

        NT_TIB*     pTEB = GetTEB();
        UINT_PTR    ebp = GetEBPForStackTrace();
        HANDLE      hCurProc = ::GetCurrentProcess();
    
        while (
            ((ebp & 3) == 0) &&
            ebp + 2*sizeof(VOID*) < (UINT_PTR)pTEB->StackBase &&
            ebp >= (UINT_PTR)pTEB->StackLimit &&
            nAddresses < nTraceBuffers)
            {
            pTraces[nAddresses++]._EIP = ((UINT_PTR*)ebp)[1];
            ebp = ((UINT_PTR*)ebp)[0];
            }
    

    My "GetTEB()" is NtCurrentTeb() from NTDLL.DLL - and it is not only Windows 7 and above as stated in the current MSDN. MS junks up the documentation. It was there for a long time. Using the ThreadEnvironment Block (TEB), you do not need ReadProcessMemory() as you know the stack's lower and upper limit. I assume this is the fastest way to do it.

    Using the MS compiler, GetEBPForStackTrace() can be

    inline __declspec(naked) UINT_PTR GetEBPForStackTrace()
    {
        __asm
            {
            mov eax, ebp
            ret
            }
    }
    

    as easy way to get EBP of the current thread (but you can pass any valid EBP to this loop as long as it is for the current thread).

    Limitation: This is valid for x86 under Windows.

提交回复
热议问题