代码之家  ›  专栏  ›  技术社区  ›  Qwertie

如何解码WindowsCE调用堆栈?

  •  4
  • Qwertie  · 技术社区  · 14 年前

    a library for decoding the call stack 变成人类可读的东西。

    我需要一个类似的工具,但对于Windows CE。WinCE有一个函数来获取调用堆栈, GetThreadCallStack ,但是一旦有了原始的返回地址

    1. 从每个程序计数器确定模块(DLL或EXE)?

    如果对任何人都有帮助,我也发现 OS-agnostic code

    3 回复  |  直到 11 年前
        1
  •  4
  •   Community CDub    8 年前

    我算了一半。你需要打电话 GetThreadCallStack ...

    CallSnapshot frames[100];
    
    HANDLE hThread = GetCurrentThread();
    SetLastError(ERROR_SUCCESS);
    int funcCount = GetThreadCallStack(hThread, 100, frames, STACKSNAP_RETURN_FRAMES_ON_ERROR, 0);
    bool success = GetLastError() == ERROR_SUCCESS;
    

    但由于某些原因,它的头文件不包括在Windows CE SDKs中。因此,您需要手动声明它:

    extern "C" {
        typedef struct _CallSnapshot {
            DWORD dwReturnAddr;
        } CallSnapshot;
    
        typedef struct _CallSnapshotEx {
            DWORD dwReturnAddr;
            DWORD dwFramePtr;
            DWORD dwCurProc;
            DWORD dwParams[4];
        } CallSnapshotEx;
    
        ULONG GetThreadCallStack (HANDLE hThrd, ULONG dwMaxFrames, LPVOID lpFrames, DWORD dwFlags, DWORD dwSkip);
        ULONG GetCallStackSnapshot (ULONG dwMaxFrames, CallSnapshot lpFrames[], DWORD dwFlags, DWORD dwSkip);
    
        #define STACKSNAP_FAIL_IF_INCOMPLETE     1
        #define STACKSNAP_EXTENDED_INFO          2
        #define STACKSNAP_INPROC_ONLY            4
        #define STACKSNAP_RETURN_FRAMES_ON_ERROR 8
    }
    

    我问过 another question about getting the module from a code address ;理论上,可以将映射文件解析为 figure out which function (in that module) the address belongs to (谢谢ctacke的链接)。

        2
  •  3
  •   Pavel P    12 年前

    我也使用GetThreadCallStack,它工作得很好。一般来说,在调试方面,wince是最差的平台,工具也最差。msdn上所有关于doctorwatson的BS都需要成为合作伙伴或使用platform builder。那些需要在发布应用程序运行时解决崩溃源的普通开发人员呢?!在数字时代和计算机时代,这些地图文件的“酷”技巧听起来相当迟钝;这种任务完全适合计算机。

    对于那些拒绝使用那些混乱的地图文件的人,我可以推荐一个可以帮助你避免这一步的工具。约翰·罗宾斯的 CrashFinder.exe 能为你做那部分。

    unsigned addr = addr1 & 0x00ffffff;
    

    然后,在crash finder中,你需要打开wince应用程序的exe文件,你可以查询地址,如果地址在你的应用程序中,它会显示你的函数名。通常,如果崩溃发生在winapi中的某个地方,我需要从callstack手动输入每个地址,直到找到我的应用程序中的最后一个地址。

        3
  •  2
  •   marcinj    11 年前

    这些文章都讨论了如何在源代码中将地址转换为一行代码,可能会有帮助: