Search This Blog

Wednesday, February 10, 2016

WPP trace sample - USEPREFIX and USESUFFIX

Just recently I had to add some WPP traces and found that macro preprocessing makes it somewhat difficult to use it. I know that it has certain advantages but I did not find much information nor good samples for my own needs so I would like to share some of my findings.

Essentially, what I wanted to do is that I want to call some function to extract certain information from the arguments that I passed to WPP macro. The issue is that WPP preprocesses its own macros and produces another set of code before the build kicks in so and the other thing is that existing code already used debugoutput API so I wanted to minimize the code churn as much as possible. While working on this, I learned that I can use PREFIX and SUFFIX but I did not find any good samples.

Following code basically helps me to call foo() function with EXP parameter and SUFFIX will output whatever the information that I obtained from foo.
There is one thing to keep in mind.
When creating PRE and POST macros, you need to put parameter names as part of the names in the middle. Essentially, you can put a lot of code in PRE macro but let us remember that this is macro so your code size will grow pretty quickly and if you happen to use this in kernel driver, you will also need to be careful of APIs that you use in PRE to make sure that you follow IRQ level.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
//MACRO: MYTRACE
//
//begin_wpp config
//USEPREFIX (MYTRACE, "%!STDPREFIX!");
//FUNC MYTRACE(LEVEL, EXP, ...);
//USESUFFIX (MYTRACE, "Result=%!HRESULT! %s",EXP, pszId);
//end_wpp

#define MYTRACE(level, exp, ...)                    \
    do {                                            \
        TraceEvents(level, VA_ARGS(__VA_ARGS__));   \
    } while (0)

#define WPP_LEVEL_EXP_PRE(level, exp)   \
    {                                   \
        PSTR pszId = foo(exp);          \
#define WPP_LEVEL_EXP_POST(level, exp) ;}

#define WPP_LEVEL_EXP_ENABLED(LEVEL, HR) WPP_FLAG_ENABLED(LEVEL)
#define WPP_LEVEL_EXP_LOGGER(LEVEL, HR) WPP_FLAG_LOGGER(LEVEL)

Once you have the above defined, you can then start to call your WPP macro as follows.


1
MYTRACE(TRACE_LEVEL_ERROR, hr, "hello, world");

This way, we can be more flexible using WPP traces. Hope this helps someone.

1 comment: