简体   繁体   English

在 Xperf 中捕获调用堆栈和事件

[英]Capture callstack and events in Xperf

Sorry about the dumb question.抱歉这个愚蠢的问题。 I am new to Xperf.我是 Xperf 的新手。

I am on 64-bit Windows 8.1 and my application is also x64.我在 64 位 Windows 8.1 上,我的应用程序也是 x64。 I want to capture both the callstacks and my defined events in the application using Xperf.我想使用 Xperf 捕获应用程序中的调用堆栈和我定义的事件。

I registered the GUID 35f7872e-9b6d-4a9b-a674-66f1edd66d5c in my application.我在我的应用程序中注册了 GUID 35f7872e-9b6d-4a9b-a674-66f1edd66d5c

When I was using:当我使用:

xperf -on PROC_THREAD+LOADER+Base -start UserSession -on 35f7872e-9b6d-4a9b-a674-66f1edd66d5c -BufferSize 1024 -stackwalk profile

I can get all the events but no callstack.我可以获得所有事件,但没有调用堆栈。 However if I remove -on 35f7872e-9b6d-4a9b-a674-66f1edd66d5c and the command lines becomes:但是,如果我删除-on 35f7872e-9b6d-4a9b-a674-66f1edd66d5c并且命令行变为:

xperf -on PROC_THREAD+LOADER+Base -start UserSession -BufferSize 1024 -stackwalk profile

This way, I am able to capture all the callstack but no defined events.这样,我能够捕获所有调用堆栈但没有定义的事件。

Can anyone tell me what's the correct command line to use to capture both the callstack and the events?谁能告诉我用于捕获调用堆栈和事件的正确命令行是什么? Also if you can point me to any good Xperf reference it would be even greater.此外,如果您可以向我指出任何好的 Xperf 参考,那就更好了。

I voted up this question even though it was poorly formed, because it shows a common source of confusion.我投票赞成这个问题,尽管它的形式很差,因为它显示了一个常见的混淆来源。 The original question asked about "how to record callstacks" but that is not a well formed question.最初的问题询问了“如何记录调用堆栈”,但这不是一个结构良好的问题。 xperf can record call stacks for the sampling profiler, context switches, file I/O, disk I/O, registry activity, or custom events. xperf 可以记录采样分析器、上下文切换、文件 I/O、磁盘 I/O、注册表活动或自定义事件的调用堆栈。 The question didn't specify what type of call stacks were recorded, which lead to some confusion.这个问题没有具体说明记录的是什么类型的调用栈,这导致了一些混淆。

Let's look at the original command line.让我们看看原始的命令行。 I've simplified it by removing PROC_THREAD+LOADER because BASE includes those.我通过删除 PROC_THREAD+LOADER 来简化它,因为 BASE 包含这些。 I've also removed -BufferSize 1024 because I think it's misplaced, and I've replaced the GUID with a name -- you should give your providers a name and use it.我还删除了 -BufferSize 1024 ,因为我认为它放错了位置,并且我已经用名称替换了 GUID - 您应该为您的提供者提供一个名称并使用它。 So, we have:所以,我们有:

xperf -on Base -start UserSession -on MyProvider -stackwalk profile

It is important to note that we have two "-on" directives.需要注意的是,我们有两个“-on”指令。 This means that we are starting two sessions.这意味着我们将开始两个会话。 This is equivalent to:这相当于:

xperf -on Base
xperf -start UserSession -on MyProvider -stackwalk profile

The first command starts or connects to the kernel logger (no session name) with the 'Base' provider.第一个命令使用“Base”提供程序启动或连接到内核记录器(无会话名称)。 The second command starts a user session called "UserSession" with the "MyProvider" provider.第二个命令使用“MyProvider”提供程序启动一个名为“UserSession”的用户会话。

Now we can see the problem.现在我们可以看到问题了。 "profile" is only a valid option for -stackwalk in the context of the kernel logger.在内核记录器的上下文中,“profile”只是 -stackwalk 的一个有效选项。 It makes no sense to ask the user session to record call stacks on profile events, because it isn't recording profile events!要求用户会话记录配置文件事件的调用堆栈是没有意义的,因为它没有记录配置文件事件! So that gets us to this variant of the OP's question:所以这让我们想到了 OP 问题的这个变体:

xperf -on Base -stackwalk profile
xperf -start UserSession -on MyProvider
@rem Run tests here
xperf -stop UserSession -stop -d trace.etl

But wait!可是等等! What about call stacks for the user events in MyProvider? MyProvider 中用户事件的调用堆栈怎么样? That's what the first answer was trying to explain -- we need to add :::'stack':这就是第一个答案试图解释的内容——我们需要添加 :::'stack':

xperf -on Base -stackwalk profile
xperf -start UserSession -on MyProvider:::'stack'
@rem Run tests here
xperf -stop UserSession -stop -d trace.etl

Those call stacks will be available as a Stack column in the Generic Events view in WPA.这些调用堆栈将在 WPA 的通用事件视图中作为堆栈列提供。 For a list of the many other things for which you can record a call stack, see "xperf -help stackwalk".有关可以记录调用堆栈的许多其他内容的列表,请参阅“xperf -help stackwalk”。 And remember, it only makes sense to ask for call stacks for an event you are actually recording.请记住,只有为您实际记录的事件请求调用堆栈才有意义。 Luckily Base includes Profile so we're okay.幸运的是 Base 包含 Profile,所以我们没问题。

Oh yeah -- if you want to set the buffer size and buffer count, be sure to be careful about which session (possibly both) you are setting it for.哦,是的——如果你想设置缓冲区大小和缓冲区计数,一定要小心你为哪个会话(可能两个)设置它。

For much information, especially about how to analyze xperf traces, see: https://randomascii.wordpress.com/category/xperf/有关更多信息,尤其是有关如何分析 xperf 跟踪的信息,请参阅: https : //randomascii.wordpress.com/category/xperf/

For a much easier way to record ETW traces see this open-source UI for controlling trace recording - you could easily add your own provider to the list being recorded: https://github.com/google/UIforETW/releases有关记录 ETW 跟踪的更简单方法,请参阅此用于控制跟踪记录的开源 UI - 您可以轻松地将自己的提供程序添加到正在记录的列表中: https : //github.com/google/UIforETW/releases

You need to add :::'stack' to the command line to capture stacks for user mode events.您需要将:::'stack'添加到命令行以捕获用户模式事件的堆栈。

xperf -start UserSession -on 35f7872e-9b6d-4a9b-a674-66f1edd66d5c:::'stack'

A good xperf reference is the book "Inside Windows Debugging" and this blog .一个很好的 xperf 参考是“Inside Windows Debugging”一书和这个博客

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM