内核模式驱动程序和组件的 TraceLogging

本主题介绍如何在内核模式驱动程序和组件中使用 TraceLogging API。

先决条件:

  • Windows 10
  • Visual Studio 2013 (或更高版本)
  • Windows 10 SDK
  • 适用于 Windows 10 的 Windows 驱动程序工具包 (WDK)

包括 TraceLogging 头文件

若要使用 TraceLogging API,请包含 TraceLogging 头文件 TraceLoggingProvider.h。 另一个 TraceLogging API 头文件 TraceLoggingActivity.h 仅适用于用 C++ 编写的用户模式驱动程序。

#include <wdm.h>
#include <TraceLoggingProvider.h> 

注意

开发内核模式驱动程序时,TraceLoggingProvider.h 需要 wdm.h 文件。

将驱动程序声明为 TraceLogging 提供程序

  1. 添加 TRACELOGGING_DECLARE_PROVIDER 宏以声明提供程序句柄变量。 宏的语法如下:

    TRACELOGGING_DECLARE_PROVIDER(hProviderVariableName)
    

    以下示例 TraceLogging 语句声明了名为 g_hProvider 的变量。

    TRACELOGGING_DECLARE_PROVIDER(g_hProvider);
    

    稍后在代码中调用 TRACELOGGING_DEFINE_PROVIDER宏时 ,使用 TRACELOGGING_DECLARE_PROVIDER 声明的变量将成为提供程序的句柄。

    注意

    你可能希望将此宏放在头文件中,以便 TraceLogging 提供程序的句柄全局可用。

  2. 添加 TRACELOGGING_DEFINE_PROVIDER 宏,并指定跟踪提供程序的名称和跟踪提供程序句柄。 句柄是在步骤 1 中声明的变量。 宏的语法为:

    TRACELOGGING_DEFINE_PROVIDER(hProviderVariableName, "ProviderName", providerId [,option])
    

    例如,以下语句定义名为 MyTraceLoggingProviderKM 的提供程序,并将其分配给句柄g_hProvider。 providerId 参数是 ETW 提供程序 GUID。

    TRACELOGGING_DEFINE_PROVIDER(g_hProvider, "MyTraceLoggingProviderKM",
        (0xb3864c38, 0x4273, 0x58c5, 0x54, 0x5b, 0x8b, 0x36, 0x08, 0x34, 0x34, 0x71));
    

    TRACELOGGING_DEFINE_PROVIDER宏为提供程序分配存储,并定义一个相应的变量,该变量是提供程序的全局句柄。 提供程序名称必须是字符串文本 (不是) 变量,并且不得包含任何“\0”字符。 只要原始句柄在范围内,句柄和副本就有效。

    首次使用 TRACELOGGING_DEFINE_PROVIDER 宏创建句柄时,提供程序处于未注册状态。 在此状态下,提供程序将忽略任何跟踪写入调用,直到注册。

    注意

    对于内核模式,请注意,虽然提供程序元数据显式存储在 TLG_METADATA_SEGMENT (.rdata) 中,但为句柄创建的变量 (例如,g_hProvider) 和提供程序的名称 (例如“MyTraceLoggingProviderKM”) 未显式分配段,并且将使用当前隐式段。

TRACELOGGING_DEFINE_PROVIDER宏要求传递给它的变量位于非分页池中。 如果不是这种情况,调用方必须在调用 TRACELOGGING_DEFINE_PROVIDER 宏之前,通过 #pragma data_seg (为 uniqueVarName) 设置数据段,或者通过 #pragma const_seg (为 g_hMyProvider) 设置 const 段。

将驱动程序注册到 TraceLogging

DriverEntry 函数中,必须注册 TraceLogging 提供程序。 若要向 TraceLogging 注册提供程序,请将 TraceLoggingRegister 宏添加到 DriverEntry

// Register the TraceLogging provider in the DriverEntry method.
TraceLoggingRegister(g_hProvider);

在驱动程序卸载或清理例程中注销提供程序

DriverUnload 或 cleanup 函数中,取消注册 TraceLogging 提供程序。

// Stop TraceLogging and unregister the provider
TraceLoggingUnregister(g_hProvider);

在代码中记录事件

TraceLogging 为记录事件提供宏。

基本宏为 TraceLoggingWrite。 此宏具有以下语法:

TraceLoggingWrite(g_hProvider, "EventName", args...)

其中,g_hProvider是定义的提供程序的句柄,“EventName”是字符串文本 (不是用于标识特定事件的变量) 。 与 printfDbgPrint 一样, TraceLoggingWrite 宏支持可变数量的附加参数, (最多 99) 。 (参数) 必须是 TraceLogging 包装宏,例如 TraceLoggingLevelTraceLoggingInt32TraceLoggingString。 TraceLoggingProvider.h 中定义了 TraceLogging 包装宏。

注意

如果使用 C++,则可以使用 TraceLoggingValue 包装器宏自动调整类型。 如果要使用 C 编写驱动程序,则必须使用特定于类型的字段宏 (例如 TraceLoggingInt32TraceLoggingUnicodeString) 。

以下示例记录提供程序的事件,g_hProvider。 该事件称为“MyDriverEntryEvent”。宏使用 TraceLoggingPointer 和 TraceLoggingUnicodeString 包装器将指向驱动程序对象的指针和注册表路径写入跟踪日志。 TraceLoggingUnicodeString 包装器采用可选名称。 在此示例中,“RegPath”是 RegistryPath 值的名称。 如果未指定名称,则值将用作名称。

TraceLoggingWrite(
        g_hProvider,
        "MyDriverEntryEvent",
        TraceLoggingPointer(DriverObject),
        TraceLoggingUnicodeString(RegistryPath, "RegPath")); 
);

如果要在 C) 中检测内核模式驱动程序 (,则链接到 TraceLoggingProvider.h,可以使用 TraceLoggingWriteTraceLoggingWriteActivityTraceLoggingActivityMarker 宏。 有关跟踪日志记录的示例,请参阅 TraceLogging Examples

如果要检测用 C++ 编写的驱动程序或组件,可以链接到 TraceLoggingProvider.h 和 TraceLoggingActivity.h。 链接到 C++ 标头时,可以使用 TraceLoggingWriteStartTraceLoggingWriteStopTraceLoggingWriteTagged 宏记录事件。

有关如何捕获和查看 TraceLogging 数据的示例,请参阅 捕获和查看 TraceLogging 数据