将 WPP 软件跟踪添加到 Windows 驱动程序

若要在跟踪提供程序(如内核模式驱动程序或用户模式应用程序)中使用 WPP 软件跟踪,需要添加代码(或 检测)驱动程序源文件并修改驱动程序项目。 本部分将介绍这些步骤。

注释

将 WPP 跟踪添加到驱动程序的最简单方法是在 Visual Studio 中使用 KMDF 或 UMDF 驱动程序模板之一。 如果使用模板,则需要添加的大部分代码都已为你完成。 在 Visual Studio 中,选择 “文件 > 新建 > 项目”,然后选择 Windows 驱动程序(用户模式或内核模式)WDF 项目。 WPP 宏定义在包含于项目的 Trace.h 头文件中。 如果使用其中一个模板,可以跳到 步骤 5

步骤 1:定义控制 GUID 和跟踪标记

必须唯一定义每个跟踪提供程序(例如驱动程序或用户模式应用)。 为此,请添加 WPP_CONTROL_GUIDS 宏,该宏定义控件 GUID、标识符和跟踪标志。 这样做可以识别和控制要跟踪的时间和内容。 虽然每个驱动程序通常具有单独的控件 GUID,但驱动程序可以有多个控件 GUID,或者多个驱动程序可以共享一个控件 GUID。

为方便起见,WPP_CONTROL_GUIDS 宏通常被定义在一个通用的头文件中。 头文件必须包含在任何要检测进行跟踪的源文件中(#include)。

若要将WPP_CONTROL_GUIDS宏添加到驱动程序,请执行以下作:

  1. 将新的C++头文件添加到 Visual Studio 项目,可用于定义 WPP 跟踪宏。 例如,在解决方案资源管理器中选择并按住(或右键单击)驱动程序,然后选择“ 添加新 > 项”。 保存文件(例如 Trace.h)。

  2. 添加 WPP_CONTROL_GUIDS 宏以指定跟踪提供程序的友好名称、定义控件 GUID 以及定义可用于限定特定跟踪消息的跟踪标志。

    WPP_CONTROL_GUIDS宏具有以下语法:

    WPP_CONTROL_GUIDS的语法

    #define WPP_CONTROL_GUIDS \
        WPP_DEFINE_CONTROL_GUID(GUIDFriendlyName, (ControlGUID),  \
            WPP_DEFINE_BIT(NameOfTraceFlag1)  \
            WPP_DEFINE_BIT(NameOfTraceFlag2)  \
            .............................   \
            .............................   \
            WPP_DEFINE_BIT(NameOfTraceFlag31) \
            )
    

    例如,以下代码使用 myDriverTraceGuid 作为 GUIDFriendlyName。 请注意, ControlGUID 的格式与 32 位十六进制 GUID 的标准格式略有不同。 ControlGUID 有五个字段,但它们用逗号分隔,用括号括起来,而不是通常的连字符和大括号。 例如,指定 ((84bdb2e9,829e,41b3,b891,02f454bc2bd7) 而不是 {84bdb2e9-829e-41b3-b891-02f454bc2bd7}。

    WPP_CONTROL_GUIDS 语句的示例

    #define WPP_CONTROL_GUIDS                                              \
        WPP_DEFINE_CONTROL_GUID(                                           \
            myDriverTraceGuid, (84bdb2e9,829e,41b3,b891,02f454bc2bd7), \
            WPP_DEFINE_BIT(MYDRIVER_ALL_INFO)        /* bit  0 = 0x00000001 */ \
            WPP_DEFINE_BIT(TRACE_DRIVER)             /* bit  1 = 0x00000002 */ \
            WPP_DEFINE_BIT(TRACE_DEVICE)             /* bit  2 = 0x00000004 */ \
            WPP_DEFINE_BIT(TRACE_QUEUE)              /* bit  3 = 0x00000008 */ \
            )                             
    

    注释

    可以将此代码片段复制到头文件中。 请务必更改控件 GUID 和友好名称。 可以使用 GUIDgen.exe 生成控件 GUID。 Visual Studio 中包括 Guidgen.exe(工具 > 创建 GUID)。 还可以使用 Visual Studio 命令提示符窗口中提供的 Uuidgen.exe 工具,键入uuidgen.exe /?获取更多信息。

  3. 定义跟踪提供程序的 跟踪标志

    WPP_CONTROL_GUIDS宏中的WPP_DEFINE_BIT元素定义了跟踪提供程序的跟踪标志。 通常,这些标志表示越来越详细的报告级别,但你可以使用标志作为生成跟踪消息的条件。 在WPP_CONTROL_GUIDS示例中,WPP_DEFINE_BIT定义了四个跟踪标志(MYDRIVER_ALL_INFO、TRACE_DRIVER、TRACE_DEVICE和TRACE_QUEUE)。

    最多可以定义 31 个跟踪标志。 WPP 按元素显示的顺序向元素分配位值,例如,位 0(0x1)、位 1(0x2)、位 2(0x4)、位 3(0x8)等。 将跟踪消息函数添加到源代码时使用跟踪标志( 步骤 5:检测驱动程序代码以在适当时间生成跟踪消息)。

    注释

    使用跟踪标志,可以控制何时跟踪特定组件(例如,特定的 I/O 请求或设备或驱动程序对象的活动)。 将跟踪标志添加到跟踪消息语句(例如 DoTraceMessage (TRACE_DRIVER, "Hello World!\n")。 使用跟踪控制器(如 Tracelog)创建跟踪会话时,指定用于该会话中的跟踪提供程序的 -flag 选项,在本例中,标志为位 1(0x1),对应于TRACE_DRIVER标志。 启动跟踪会话时,指定跟踪标志的所有跟踪消息将写入日志。

步骤 2:选择要使用哪些跟踪消息函数并为这些函数定义 WPP 宏

与调试打印函数一样,跟踪消息函数是添加到代码以编写跟踪消息的函数(或宏)。

选择跟踪消息函数

  • 默认跟踪消息函数是 DoTraceMessage 宏。 如果使用默认函数,则可以控制何时使用提供程序的 跟踪标志 值生成消息。 跟踪标志值是在步骤 1 中创建控件 GUID 时定义的标志。 如果使用 DoTraceMessage,则已为你定义默认 WPP 宏(WPP_LEVEL_ENABLED和WPP_LEVEL_LOGGER),因此可以跳过此步骤的其余部分并转到 步骤 5

  • 如果使用 KMDF 或 UMDF 模板之一, 则已定义 TraceEvents 函数和必要的 WPP 宏来启用该函数,因此可以跳到 步骤 5

  • 如果要创建自己的跟踪消息函数或转换现有调试打印函数,请继续执行此步骤的其余部分。

创建或自定义跟踪消息函数

  1. 如果使用自定义跟踪消息函数,或者想要转换调试打印函数(例如 KdPrint)来生成跟踪消息,则需要定义 WPP 宏来标识和启用跟踪提供程序中的跟踪消息函数。 将这些宏放入添加到项目的 Trace.h 头文件中。

  2. 定义 WPP 宏以启用跟踪函数。

    使用的每个跟踪消息函数都必须具有相应的宏对。 这些宏标识跟踪提供程序并指定生成消息的条件。 您通常根据默认的WPP_LEVEL_ENABLED和WPP_LEVEL_LOGGER宏定义一对宏:WPP_<条件>_LOGGERWPP_<条件>_ENABLED

术语 Description
WPP_CONDITIONS_LOGGER 用于查找与提供程序关联的跟踪会话,并向会话返回句柄。
WPP_CONDITIONS_ENABLED 用于确定是否依据指定条件启用日志记录。

对于定义的 WPP 宏, CONDITIONS 表示跟踪消息函数支持的条件,按照函数的参数列表中显示的顺序(用下划线分隔)。 例如,默认跟踪消息函数 DoTraceMessage 仅支持 跟踪标志 作为条件,因此宏名称中只有一个参数(WPP_LEVEL_ENABLED)。

注释

遗憾的是,默认宏(WPP_LEVEL_ENABLED和WPP_LEVEL_LOGGER)的名称似乎指示 跟踪级别 参数,但它们实际上引用了跟踪标志。

如果使用自定义跟踪消息函数,则可以设置其他限定符,例如 跟踪级别。 跟踪级别在 Evntrace.h 文件中定义,跟踪级别提供了将跟踪消息分类为错误、警告和信息性消息的便捷方法。

例如,可以将以下代码片段添加到添加到项目的头文件。 以下代码定义了跟踪消息函数的自定义 WPP 宏,该函数支持 跟踪级别 和跟踪标志参数作为生成跟踪消息的条件。 如果为指定的 FLAGS 值启用了日志记录,并且启用的 LEVEL 值大于或等于跟踪消息函数调用中使用的级别参数, 则WPP_LEVEL_FLAGS_ENABLED 宏将返回 TRUE。

#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \
           WPP_LEVEL_LOGGER(flags)

#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \
           (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl)

接下来,需要在 WPP 配置块(begin_wpp配置end_wpp)中指定自定义跟踪函数,例如,如果在 Visual Studio 中使用 UMDF 或 KMDF 驱动程序项目的模板,该模板将为名为 TraceEvents 的自定义跟踪消息函数定义 WPP 宏。 TraceEvents 宏函数使用跟踪级别和跟踪标志作为生成消息的条件。 如果在 Trace.h 头文件中定义了 WPP_LEVEL_FLAGS_ENABLED 宏,则可以添加以下宏定义。

//
// This comment block is scanned by the trace preprocessor to define the 
// TraceEvents function.
//
// begin_wpp config
// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...);
// end_wpp
//

还可以通过在 WPP 配置块中添加类似的 FUNC 声明,将现有的调试打印语句转换为跟踪消息语句。 例如,以下示例添加用于转换现有 KdPrint 语句的代码。 FUNC 声明还全局定义 KdPrint 以使用指定的跟踪级别和标记 {LEVEL=TRACE_LEVEL_INFORMATION, FLAGS=TRACE_DRIVER}。 调试打印语句将发送到跟踪日志,而不是将输出发送到调试器。

//
// This comment block is scanned by the trace preprocessor to define the
// TraceEvents function and conversion for KdPrint. Note the double parentheses for the KdPrint message, for compatibility with the KdPrint function.
//
// begin_wpp config
// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...);
// FUNC KdPrint{LEVEL=TRACE_LEVEL_INFORMATION, FLAGS=TRACE_DRIVER}((MSG, ...));
// end_wpp
//

注释

如果要将 KdPrintEx 转换为跟踪消息函数,则需要执行一些额外的步骤。 与 KdPrint 相比, KdPrintEx 函数采用两个附加参数。 若要转换 KdPrintEx 函数,需要为 WPP_DEFINE_BIT 定义 ComponentID,并定义自定义 WPP_<条件>_LOGGERWPP_<条件>_ENABLED 宏。 KdPrintEx 的第二个参数指定级别类似于跟踪级别值,因此不一定需要重新定义它们。


#define WPP_CONTROL_GUIDS                                              \
    WPP_DEFINE_CONTROL_GUID(\
    myDriverTraceGuid, (11C3AAE4, 0D88, 41b3, 43BD, AC38BF747E19), \    /* change GUID for your provider */
        WPP_DEFINE_BIT(MYDRIVER_ALL_INFO)        /* bit  0 = 0x00000001 */ \
        WPP_DEFINE_BIT(TRACE_DRIVER)             /* bit  1 = 0x00000002 */ \
        WPP_DEFINE_BIT(TRACE_DEVICE)             /* bit  2 = 0x00000004 */ \
        WPP_DEFINE_BIT(TRACE_QUEUE)              /* bit  3 = 0x00000008 */ \
        WPP_DEFINE_BIT(DPFLTR_IHVDRIVER_ID)      /* bit  4 = 0x00000010 */\         /* Added for the ComponentID param of KdPrintEx */
    )

#define WPP_Flags_LEVEL_LOGGER(Flags, level)                                  \
    WPP_LEVEL_LOGGER(Flags)

#define WPP_Flags_LEVEL_ENABLED(Flags, level)                                 \
    (WPP_LEVEL_ENABLED(Flags) && \
    WPP_CONTROL(WPP_BIT_ ## Flags).Level >= level)



//
// This comment block is scanned by the trace preprocessor to convert the KdPrintEx function.
// Note the double parentheses for the KdPrint message, for compatiblility with the KdPrintEx function.
//
// begin_wpp config
// FUNC KdPrintEx((Flags, LEVEL, MSG, ...));   
// end_wpp
//

步骤 3:在 C 或C++源文件中包含关联的跟踪头文件(.h 和 .tmh)

如果在头文件(例如 trace.h)中为驱动程序定义了控件 GUID 和跟踪标志,则需要在源文件中包含头文件,以便在源文件中初始化和卸载 WPP(步骤 4)或调用跟踪消息函数。

此外,还需要为跟踪消息头文件(.tmh)添加 #include 语句。 生成驱动程序或应用程序时,WPP 预处理器会为每个包含跟踪消息函数的源文件(.tmh)生成跟踪消息头文件(.tmh)。

/* -- driver.c  - include the *.tmh file that is generated by WPP --*/

#include "trace.h"     /* file that defines WPP_CONFIG_GUIDS and trace flags */
#include "driver.tmh"  /* this file is auto-generated */

步骤 4:将宏添加到相应的回调函数以初始化和清理 WPP

在驱动程序入口处初始化 WPP

  • WPP_INIT_TRACING 宏添加到内核模式驱动程序或 UMDF 2.0 驱动程序的 DriverEntry 例程,或添加到用户模式驱动程序 (UMDF 1.x) 或应用程序的 DLLMain 例程。

在驱动程序退出时清理 WPP 资源

  • WPP_CLEANUP 宏添加到内核模式驱动程序或 UMDF 2.0 驱动程序的驱动程序卸载例程(例如 DriverContextCleanupDriverUnload)。

    对于用户模式驱动程序(UMDF 1.x)或应用程序,请将 WPP_CLEANUP 宏添加到 DLLMain 例程。

    如果 DriverEntry 失败,还应将WPP_CLEANUP宏添加到 DriverEntry 例程。 例如,如果 DriverEntry 失败,则不会调用驱动程序卸载例程。 请参阅以下示例中 对 WdfDriverCreate 的调用。

DriverEntry 中使用 WPP_INIT_TRACING 和 WPP_CLEANUP 的内核模式驱动程序示例


NTSTATUS
DriverEntry(
    _In_ PDRIVER_OBJECT  DriverObject,
    _In_ PUNICODE_STRING RegistryPath
    )
{  

          //  ... 

                //
    // Initialize WPP Tracing in DriverEntry
    //
    WPP_INIT_TRACING( DriverObject, RegistryPath );

                //  ...


 //
    // Create a framework driver object to represent our driver.
    //
    status = WdfDriverCreate(
        DriverObject,
        RegistryPath,
        &attributes, // Driver Object Attributes
        &config,          // Driver Config Info
        WDF_NO_HANDLE // hDriver
        );

    if (!NT_SUCCESS(status)) {

        TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT,
                "WdfDriverCreate failed with status 0x%x\n", status);
        //
        // Cleanup tracing here because DriverContextCleanup will not be called
        // as we have failed to create WDFDRIVER object itself.
        // Please note that if you return failure from DriverEntry after the
        // WDFDRIVER object is created successfully, you don't have to
        // call WPP cleanup because in those cases DriverContextCleanup
        // will be executed when the framework deletes the DriverObject.
        //
        WPP_CLEANUP(DriverObject);

    }

                return status;

}

在 DriverContextCleanup 中使用 WPP_CLEANUP 的内核模式驱动程序示例



VOID
DriverContextCleanup(
       PDRIVER_OBJECT DriverObject
       )
{
    // ...

    // Clean up WPP resources on unload
    //
    WPP_CLEANUP(DriverObject);

   // ...

}

在 DriverEntry 中使用 WPP_INIT_TRACING 的 UMDF 2.0 驱动程序示例


/
// Driver specific #defines in trace header file (trace.h)
//
#define MYDRIVER_TRACING_ID      L"Microsoft\\UMDF2.0\\UMDF2_0Driver1 V1.0"

 // Initialize WPP Tracing in the DriverEntry routine
 //
    WPP_INIT_TRACING( MYDRIVER_TRACING_ID );

UMDF 1.0 驱动程序在 DLLMain 中使用 WPP_INIT_TRACING 和 WPP_CLEANUP 宏的示例

/
// Driver specific #defines in trace header file (for example, trace.h)
//
#define MYDRIVER_TRACING_ID      L"Microsoft\\UMDF1.X\\UMDF1_XDriver1"


//
// DLL Entry Point - UMDF 1.0 example in the source file where you implement the DLL exports.
// 

extern "C"
BOOL
WINAPI
DllMain(
    HINSTANCE hInstance,
    DWORD dwReason,
    LPVOID lpReserved
    )
{
    if (dwReason == DLL_PROCESS_ATTACH) {
        WPP_INIT_TRACING(MYDRIVER_TRACING_ID);              // Initialize WPP tracing

        g_hInstance = hInstance;
        DisableThreadLibraryCalls(hInstance);

    } else if (dwReason == DLL_PROCESS_DETACH) {
        WPP_CLEANUP();                                                                                                              // Deactivate and cleanup WPP tracing
    }

    return _AtlModule.DllMain(dwReason, lpReserved);
}

步骤 5:检测驱动程序代码以在适当点生成跟踪消息

可以使用所选的任何跟踪消息函数,前提是跟踪消息函数、跟踪标志和级别已正确定义。 默认跟踪消息函数是 DoTraceMessage 宏。 可以将此宏添加到代码中,以将消息写入日志文件。 下表列出了一些预定义的跟踪消息函数和可用于创建跟踪消息的调试打印函数。

跟踪消息函数示例 何时使用
DoTraceMessage 这是默认跟踪消息函数。 使用 DoTraceMessage 的优点是函数已为你定义。 您可以使用在WPP_CONFIG_GUIDS宏中指定的跟踪标志。 使用 DoTraceMessage 的缺点是,该函数仅采用一个条件参数,即跟踪标志。 如果要使用跟踪级别,仅记录错误或警告消息,可以使用 DoDebugTrace 宏或使用 TraceEvents,后者同时使用跟踪标志和跟踪级别。
TraceEvents 如果在 Visual Studio 中使用 WDF 模板创建驱动程序,则这是默认的跟踪消息函数。 使用 TraceEvents 的优点是跟踪消息函数、跟踪标志和 跟踪级别 已为你定义。 此外,模板还包括在函数开始和结束时将消息记录到日志文件的工具。
KdPrintKdPrintExDbgPrintDbgPrintEx 使用调试打印函数的优点是无需修改现有的调试打印语句。 可以轻松地从在调试器中查看消息切换到在文件中录制跟踪消息。 如果您自定义了跟踪消息函数以包含其中一个调试打印函数,则无需再执行任何额外工作。 使用 Logman 或 Tracelog 或其他跟踪控制器创建跟踪会话时,只需指定提供程序的标志和级别。 满足指定条件的任何调试打印语句都将打印到日志。

使用 DoTraceMessage 语句

  1. 像调试打印例程一样,将 DoTraceMessage 宏添加到代码中。 DoTraceMessage 宏采用 3 个参数:标志级别(TraceFlagName),用于定义写入跟踪消息时的条件、消息字符串和可选变量列表。

    DoTraceMessage(TraceFlagName, Message, [VariableList... ])
    

    例如,以下 DoTraceMessage 语句在为跟踪会话启用TRACE_DRIVER WPP_CONTROL_GUIDS标志时写入包含 DoTraceMessage 语句的函数的名称。

         DoTraceMessage( TRACE_DRIVER, "\nEntering %!FUNC!" );
    
    

    该示例对当前正在执行的函数使用预定义字符串(%FUNC!)。 有关 WPP 定义的格式规范字符串的详细信息,请参阅 什么是 WPP 扩展格式规范字符串?

  2. 为了生成跟踪消息,请使用 Logman 或 Tracelog 为您的跟踪提供程序创建跟踪会话,并指定一个跟踪标识符,该标识符设置了 TRACE_DRIVER 标志(位 1, 0x2)。

//
//  DoTraceMessage examples
// 

     ...

// writes the name of the function that contains the trace statement when the flag, TRACE_DRIVER (bit 1, 0x2), 
// as defined in WPP_CONTROL_GUIDS, is enabled for the trace session.

     DoTraceMessage( TRACE_DRIVER, "\nEntering %!FUNC!" );

     ...

// writes the name of the function, the line number, and the error code 

      DoTraceMessage(
            TRACE_DRIVER,
            "[%s] Failed at %d (error code= %d)\n",
            __FUNCTION__,
            __LINE__,
            dwLastError);

使用 TraceEvents 语句

如果在 Visual Studio 中使用 Windows 驱动程序模板, 则 TraceEvents 宏会在 Trace.h 头文件中为你定义。

  1. 像调试打印例程一样,将 TraceEvents 宏添加到代码。 TraceEvents 宏采用以下参数:跟踪级别(级别)和跟踪标志(标志),用于定义写入跟踪消息时的条件、消息字符串和可选变量列表。

    TraceEvents(Level, Flags, Message, [VariableList... ])
    

    例如,以下 TraceEvents 语句在满足跟踪级别和跟踪标志参数中指定的条件时写入包含 TraceEvents 语句的函数的名称。 跟踪级别是一个整数值;对于指定跟踪会话的跟踪级别或以下的任何内容,都将进行跟踪。 TRACE_LEVEL_INFORMATION在 Evntrace.h 中定义,值为 4。 WPP_CONTROL_GUIDS 中定义了 TRACE_DRIVER 标志(位 1 表示 0x2)。 如果为跟踪会话设置了此TRACE_DRIVER位,并且跟踪级别为4或更高,TraceEvents将写入跟踪消息。

            TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
    
    

    该示例对当前正在执行的函数使用预定义字符串(%FUNC!)。 有关 WPP 定义的格式规范字符串的详细信息,请参阅 什么是 WPP 扩展格式规范字符串?

  2. 若要生成跟踪消息,请使用 Logman 或 Tracelog 为跟踪提供程序创建跟踪会话。 指定跟踪级别为TRACE_LEVEL_INFORMATION(4)或更高级别,并指定一个跟踪级别以设置TRACE_DRIVER位(位1, 0x2)。

//
//  TraceEvents examples
// 


    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");

//


    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,
                       "OSRUSBFX2 Driver Sample - Driver Framework Edition.\n");

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,
                "Built %s %s\n", __DATE__, __TIME__);

步骤 6:修改 Visual Studio 项目以运行 WPP 预处理器并生成解决方案

WDK 为 WPP 预处理器提供支持,以便可以使用 Visual Studio 和 MSBuild 环境运行预处理器。

运行 WPP 预处理器

  1. 选择并按住解决方案资源管理器中的驱动程序项目,然后选择“ 属性”。
  2. 在项目属性页中,选择 “配置属性 ”,然后选择 “WPP 跟踪”。
  3. “常规”下,将 “运行 WPP ”选项设置为 “是”。
  4. 命令行下,添加任何其他选项以自定义跟踪行为。 有关可添加的内容的信息,请参阅 WPP 预处理器
  5. 为目标配置和平台生成项目或解决方案。 请参阅 使用 WDK 生成驱动程序

有关生成过程的信息,请参阅 TraceWPP 任务WDK 和 Visual Studio 生成环境

还可以使用 TraceWPP 工具(TraceWPP.exe)独立于生成环境运行预处理器。 此工具位于 WDK 的 bin/x86 和 bin/x64 子目录中。

步骤 7:启动跟踪会话以捕获和验证跟踪消息

若要验证是否已正确设置 WPP 跟踪,应在测试计算机上安装驱动程序或应用程序,然后创建跟踪会话来捕获跟踪消息。 可以使用任何跟踪控制器(如 Logman、 TracelogTraceView)为跟踪提供程序创建跟踪会话。 可以将消息写入日志文件或发送到内核调试器。 根据所使用的跟踪消息函数,需要确保指定将生成消息的跟踪标志和跟踪级别。

例如,如果使用 Evntrace.h 中定义的跟踪级别,并且想要捕获TRACE_LEVEL_INFORMATION(4)或更高版本,则需要将级别设置为 4。 将跟踪会话的级别设置为 4 时,还会捕获所有信息性(4)、警告(3)、错误(2)和关键(1)消息,假设还满足任何其他条件(如跟踪标志)。

若要验证是否生成了所有消息,可能只需将跟踪级别和跟踪标志设置为最大值,以便生成所有消息。 跟踪标志使用位掩码(ULONG),因此可以设置所有位(例如,0xFFFFFFFF)。 跟踪级别由字节值表示。 例如,如果您正在使用 Logman 工具,可以通过指定 0xFF 来覆盖所有级别。

(示例)使用 Logman 启动跟踪会话

logman create trace "myWPP_session" -p {11C3AAE4-0D88-41b3-43BD-AC38BF747E19} 0xffffffff 0xff -o c:\DriverTest\TraceFile.etl 

logman start "myWPP_session"

logman stop "myWPP_session"

(示例)使用 TraceLog 启动跟踪会话

tracelog -start MyTrace -guid  MyProvider.guid -f d:\traces\testtrace.etl -flag 2 -level 0xFFFF

Tracelog 命令包括 -f 参数,用于指定事件跟踪日志文件的名称和位置。 它包括用于指定标志集的 -flag 参数和用于指定级别设置的 -level 参数。 可以省略这些参数,但某些跟踪提供程序不会生成任何跟踪消息,除非设置了标志或级别。 跟踪级别在 Evntrace.h 文件中定义,跟踪级别提供了将跟踪消息分类为严重、错误、警告和信息性消息的便捷方法。