目前我使用 dbghelp 库来遍历某个进程'线程的堆栈(使用 GetThreadContext()和 StackWalk64())并且只收集每个帧包含的返回地址。
然而,这样做的开销对于系统需求来说太大了 - 总体时间是apx。每个堆栈步行5毫秒(10-15帧)。这次包括GetThreadContext()和调用StackWalk64()以获取所有帧的循环。
无论如何,我必须找到一种方法来更快地完成它。任何人都知道我该怎么做?
有没有人知道ETW(Windows事件跟踪)机制?
如果是这样,我如何跟踪在特定时间段内发生的所有上下文切换? 是否存在在每个上下文切换上发布事件的事件提供程序?
答案 0 :(得分:3)
我能想到的最快的方法是通过创建一个抓取GetThreadContext
结构的StackWalk64
字段的内核驱动程序来创建自己的kernelStack
和ETHREAD
版本您尝试监控的主题。 Here是关于这个主题的好文章。
答案 1 :(得分:2)
如果您使用的是Windows Vista或更高版本,则应使用ETW,period。您可以激活所有您正在谈论的内容,包括上下文切换和示例配置文件事件,它非常有效。对于X86,它基本上是走EBP寄存器链,这是一个需要迭代的地址链表。在64位的情况下,堆栈步行器必须展开堆栈,因此效率稍低,但我可以告诉你,如果你在应用程序中做了任何合理的工作量,堆栈行走的效果将不会显示起来。它肯定不在毫秒范围内。
答案 2 :(得分:1)
ETW部分实际上是一个独立的问题。 Windows Performance Analysis Tools可以捕获所有上下文切换,以及“资源争用并发性分析”模式中的Visual Studio Profiler。您也可以使用logman手动将所有事件转储到文件中,请参阅说明here。