【发布时间】:2016-04-02 18:42:58
【问题描述】:
正如你们大多数人可能知道的那样,存在许多不同的机制来遍历堆栈跟踪,从 windows api 开始,并继续深入到神奇的汇编世界 - 让我在这里列出一些我已经研究过的链接。
首先让我提一下,我想要对混合模式(托管和非托管)/ 64 位 + AnyCPU 应用程序和所有 windows api 的 CaptureStackBackTrace 的内存泄漏分析机制最适合我的需求,但是因为我已分析 - 它不支持托管代码堆栈遍历。 但该函数 API 最接近我的需要(因为它还计算回溯哈希 - 特定调用堆栈的唯一标识符)。
我已经排除了定位内存泄漏的不同方法 - 我尝试过的大多数软件要么崩溃,要么运行不可靠,或者结果不佳。
另外,我不想重新编译现有软件并覆盖 malloc / 新的其他机制 - 因为这是一项繁重的任务(我们有大量的代码库和大量的 dll)。此外,我怀疑这不是我需要执行的一次性工作 - 问题会以 1-2 年的周期出现,具体取决于编码的人员和内容,因此我更愿意在应用程序本身中进行内置的内存泄漏检测(内存api hooking)而不是一遍又一遍地解决这个问题。
http://www.codeproject.com/Articles/11132/Walking-the-callstack
使用 StackWalk64 windows API 函数,但不适用于托管代码。此外,64 位支持对我来说并不完全清楚 - 我已经看到了一些 64 位问题的解决方法 - 我怀疑当堆栈遍历在同一个线程中完成时,这段代码不能完全工作。
那么存在进程hacker: http://processhacker.sourceforge.net/
它也使用 StackWalk64,但扩展了它的回调函数(第 7 个和第 8 个参数)以支持混合模式堆栈行走。 在经历了 7/8 回调函数的许多复杂性之后,我设法通过混合模式支持实现了对 StackWalk64 的支持(将堆栈跟踪作为向量 - 每个指针都指向调用经过的程序集 / dll 位置)。 但正如您可能猜到的 - StackWalk64 的性能不足以满足我的需求 - 即使使用 C# 端的简单消息框,应用程序也只是“挂起”一段时间,直到它正确启动。
我没有看到 CaptureStackBackTrace 函数调用出现如此严重的延迟,所以我认为 StackWalk64 的性能不足以满足我的需求。
还存在基于 COM 的堆栈跟踪确定方法 - 如下所示: http://www.codeproject.com/Articles/371137/A-Mixed-Mode-Stackwalk-with-the-IDebugClient-Inter
http://blog.steveniemitz.com/building-a-mixed-mode-stack-walker-part-1/
但我担心的是——它需要 COM ,并且线程需要初始化 com ,并且由于内存 api 挂钩,我不应该在任何线程中触及 com 状态,因为它会导致更严重的问题(例如不正确的公寓初始化,其他故障)
现在我已经到了 Windows API 无法满足我自己需求的地步,我需要手动遍历调用堆栈。 例如,可以找到这样的例子:
http://www.codeproject.com/Articles/11221/Easy-Detection-of-Memory-Leaks 请参见函数 FillStackInfo / 仅 32 位,不支持托管代码。
关于反转堆栈跟踪有几处提到 - 例如在以下链接中:
- http://blog.airesoft.co.uk/2009/02/grabbing-kernel-thread-contexts-the-process-explorer-way/
- http://cbloomrants.blogspot.fi/2009/01/01-30-09-stack-tracing-on-windows.html
- http://www.gamedev.net/topic/364861-stack-dump-on-win32-how-to-get-api-addresses/
- http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/
尤其是 1、3、4 链接提供了一些有趣的夜间阅读。 :-)
但即使这样它们是相当有趣的机制,也没有关于它们的完整工作演示示例。
我想其中一个例子是 Wine 的 dbghelp 实现(Linux 的 Windows“模拟器”),它还显示了 StackWalk64 到底是如何工作的,但我怀疑它与 DWARF2 文件格式可执行文件密切相关,因此它与当前 windows PE 可执行文件格式。
有人可以指出我在 64 位架构上工作的堆栈遍历的良好实现,具有混合模式支持(可以跟踪本机和托管内存分配),这纯粹是在寄存器/调用堆栈/代码分析中绑定的。 (1、3、4的组合实现)
是否有人与 Microsoft 开发团队有良好的联系,可以回答这个问题?
【问题讨论】:
标签: windows memory-leaks stack-trace mixed-mode