事件查看器
在性能探查器中,可以在应用仍在运行时收集诊断信息,然后在应用停止后检查收集的信息(如事后分析)。
通用事件查看器通过一系列事件(如模块加载、线程启动和系统配置)显示应用活动。 此视图有助于在 Visual Studio 探查器中更好地诊断应用的运行情况。
安装
在 Visual Studio 中,按 Alt+F2 打开性能探查器。
选中“事件查看器”复选框。
选择“开始”按钮,以运行此工具。
在此工具开始运行后,在应用中完成要探查的方案。 然后,选择“停止收集”或关闭应用,以查看数据。
若要详细了解如何提高此工具的效率,请参阅优化分析设置。
了解数据
列名称 | 描述 |
---|---|
提供商名称 | 事件源 |
事件名称 | 由其提供程序指定的事件 |
Text | 事件的提供程序、事件名称和 ID 的说明 |
时间戳(毫秒) | 事件发生的时间 |
提供程序 GUID | 事件提供程序的 ID |
事件 ID | 事件的 ID |
进程 ID | 发生事件所在的进程(如果已知) |
进程名 | 当前正在运行的进程的名称 |
线程 ID | 发生事件所在的线程的 ID(如果已知) |
如果默认情况下缺少任何列,请右键单击现有列标题之一,然后选择要添加的列。
选择事件后,就会看到“其他属性”窗口。 “通用属性”列出了将会为所有事件显示的属性。 “有效负载属性”显示了特定于事件的属性。 对于某些事件,还可以查看“堆栈”。
整理数据
除了“文本”列以外的其他所有列都是可排序的。
事件查看器一次最多可显示 20,000 个事件。 若要专注于相关事件,可以通过选择事件筛选器来筛选显示的事件。 还可以查看每个提供程序发生的事件总数所占的百分比,此信息为你提供时间分配的明细。 如果将鼠标悬停在一个事件筛选器上,就能看到显示以下内容的工具提示:
- 事件名称
- 提供程序
- GUID
- 事件总数所占的百分比
- 事件计数
提供程序筛选器显示了每个提供程序发生的事件总数所占的百分比。 如果将鼠标悬停在一个提供程序上,可以看到显示提供程序名称、事件总数所占百分比和事件计数的类似工具提示。
启用自定义 ETW 事件
可以使用自定义 ETW 事件检测代码,并允许它们显示在事件查看器中。 若要启用自定义事件:
生成自定义事件代码。
本部分末尾提供了 C++ 自定义事件代码的示例。
打开性能探查器 (Alt + F2),启用事件查看器,然后选择 其旁边的“设置”图标(齿轮图标)。
在对话框中,在“其他提供程序”下启用第一行,然后执行以下操作之一:
选择“确定”。
收集诊断跟踪并打开自定义事件时,自定义事件将显示在事件查看器中。 下图显示了事件查看器中的自定义事件,其中筛选设置为仅显示自定义事件。
下面是 C++ 的自定义事件代码示例。
#include <Windows.h>
#include <evntprov.h>
#include <iostream>
#include <thread>
// This GUID must be regenerated so it is unique for your provider
// {7369B7AC-64EB-4618-B6B6-C8442B12E8F2}
GUID customEventProvider = { 0x7369b7ac, 0x64eb, 0x4618, { 0xb6, 0xb6, 0xc8, 0x44, 0x2b, 0x12, 0xe8, 0xf2 } };
REGHANDLE _customEventProviderRegHandle = 0;
// Id, Version, Channel, Level, OpCode, Task, Keyword
const EVENT_DESCRIPTOR CustomEventDescriptor = { 1, 0, 0, 0, 0, 0, 1 };
int main()
{
// Register the provider
ULONG res = ::EventRegister(&customEventProvider, nullptr, nullptr, &_customEventProviderRegHandle);
if (res != ERROR_SUCCESS)
{
return res;
}
byte data[] = { 0xFF, 0xFF, 0xFF, 0xFF };
EVENT_DATA_DESCRIPTOR eventData[1];
::EventDataDescCreate(&(eventData[0]), &data, sizeof(data));
for (int i = 0; i < 10; ++i)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
::EventWrite(_customEventProviderRegHandle, &CustomEventDescriptor, _countof(eventData), eventData);
std::cout << "Wrote event\n";
}
res = ::EventUnregister(_customEventProviderRegHandle);
if (res != ERROR_SUCCESS)
{
return res;
}
return 0;
}