4

目前我使用dbghelp库遍历某个进程线程的堆栈(使用GetThreadContext()StackWalk64())并仅收集每个帧包含的返回地址。

但是,这样做的开销对于系统需求来说太大了 - 总时间是 apx。每次堆栈步行 5 毫秒(10-15 帧)。这次包括 GetThreadContext() 和调用 StackWalk64() 以获取所有帧的循环。

无论如何,我必须找到一种更快的方法。任何人都知道我该怎么做?


编辑:

有人知道 ETW(Windows 事件跟踪)机制吗?

如果是这样,我如何跟踪在某个时间段内发生的所有上下文切换?是否有一个事件提供者在每个上下文切换上发布一个事件?

4

3 回答 3

3

我能想到的最快方法是创建您自己的版本,GetThreadContextStackWalk64通过创建一个内核驱动程序来获取您尝试监视的线程kernelStack的结构字段。是一篇关于这个主题的好文章。ETHREAD

于 2011-12-06T22:53:42.603 回答
2

如果您使用的是 Windows Vista 或更高版本,则应使用 ETW,句号。您可以激活所有您正在谈论的内容,包括 Context Switches 和 Sample Profile 事件,而且非常高效。对于 X86,它基本上是遍历 EBP 寄存器链,这是一个需要迭代的地址链表。在 64 位域中,堆栈遍历器必须展开堆栈,因此效率较低,但我可以告诉您,如果您在应用程序中做任何合理的工作,堆栈遍历的效果将不会显示向上。它肯定不在毫秒范围内。

于 2012-01-20T08:09:10.490 回答
1

ETW 部分实际上是一个独立的问题。Windows 性能分析工具可以捕获所有上下文切换,以及“资源争用并发分析”模式下的Visual Studio Profiler。您还可以使用 logman 手动将所有事件转储到文件中,请参阅此处的说明。

于 2011-12-07T18:31:25.447 回答