Menu

Cppcheck and WPP macros

pmisik
2017-10-30
2017-10-30
  • pmisik

    pmisik - 2017-10-30

    Hi,

    We use WPP in our codebase
    https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/adding-wpp-macros-to-a-trace-provider
    It is cheap way to add tracing info into your code.
    Basically code look like this

    #define WPP_CONTROL_GUIDS \
        WPP_DEFINE_CONTROL_GUID(SampleLogecmdLogGuid,(9180A91D, A224, 4f3b, 8566, 98A5BE0C3212),  \
        WPP_DEFINE_BIT(Global) )
    
    #define WPP_LEVEL_FLAGS_LOGGER(level,flags) WPP_LEVEL_LOGGER(flags)
    #define WPP_LEVEL_FLAGS_ENABLED(level, flags) (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= level)
    
    #include <sample.tmh>
    
    int main(int argc, char** argv)
    {
        if (argc < 2)
        {
            DoTraceLevelMessage(TRACE_LEVEL_ERROR, Global, "Missing argument");
            return 1;
        }
    
        return 0;
    }
    

    sample.tmh is generated before compilation based on content of cpp and it is in include path.
    After running cppcheck on such code I receive error:

    error:cppcheckError: Analysis failed. If the code is valid then please report this failure.

    So I preprocessed code with c preprocessor and I got this code:

    typedef unsigned __int64 ULONG64, *PULONG64;
    typedef unsigned __int64 ULONGLONG;
    typedef unsigned long ULONG;
    typedef void *PVOID;
    typedef unsigned char UCHAR;
    typedef unsigned short USHORT;
    typedef ULONG64 TRACEHANDLE, *PTRACEHANDLE;
    
    typedef struct _GUID {
        unsigned long  Data1;
        unsigned short Data2;
        unsigned short Data3;
        unsigned char  Data4[ 8 ];
    } GUID;
    typedef GUID *LPGUID;
    typedef const GUID *LPCGUID;
    
    extern "C"
    ULONG __cdecl TraceMessage (
          TRACEHANDLE LoggerHandle,
          ULONG MessageFlags,
          LPCGUID MessageGuid,
          USHORT MessageNumber,
        ...
    );
    
    .....
    
    extern "C" {
    typedef struct _WPP_WIN2K_CONTROL_BLOCK {
        TRACEHANDLE Logger;
        ULONG Flags;
        ULONG Level;
    } WPP_WIN2K_CONTROL_BLOCK, *PWPP_WIN2K_CONTROL_BLOCK;
    #pragma warning(push)
    #pragma warning(disable:4201) 
    typedef struct _WPP_TRACE_CONTROL_BLOCK
    {
        struct _WPP_TRACE_CONTROL_BLOCK *Next;
        TRACEHANDLE     UmRegistrationHandle;
        union {
            TRACEHANDLE              Logger;
            PWPP_WIN2K_CONTROL_BLOCK Win2kCb;
            PVOID                    Ptr;
            struct _WPP_TRACE_CONTROL_BLOCK *Cb;
        };
        UCHAR           FlagsLen; 
        UCHAR           Level; 
        USHORT          Options;
        ULONG           Flags[1];
    } WPP_TRACE_CONTROL_BLOCK, *PWPP_TRACE_CONTROL_BLOCK;
    #pragma warning(pop)
    enum {
        WPP_VER_WIN2K_CB_FORWARD_PTR    = 0x01,
        WPP_VER_WHISTLER_CB_FORWARD_PTR = 0x02,
        WPP_VER_LH_CB_FORWARD_PTR = 0x03
    };
    void WppCleanupUm( void );
    };
    
    extern "C" {
    enum WPP_CTL_NAMES { WPP_CTL_SampleLogGuid, WPP_LAST_CTL};
    extern __declspec(selectany) const GUID WPP_ThisDir_CTLGUID_SampleLogGuid = {0x9180A91D, 0xA224, 0x4f3b, {(((ULONGLONG)(0x8566) >> (8 * 1)) & 0xFF), (((ULONGLONG)(0x8566) >> (8 * 0)) & 0xFF), (((ULONGLONG)(0x98A5BE0C3212) >> (8 * 5)) & 0xFF), (((ULONGLONG)(0x98A5BE0C3212) >> (8 * 4)) & 0xFF), (((ULONGLONG)(0x98A5BE0C3212) >> (8 * 3)) & 0xFF), (((ULONGLONG)(0x98A5BE0C3212) >> (8 * 2)) & 0xFF), (((ULONGLONG)(0x98A5BE0C3212) >> (8 * 1)) & 0xFF), (((ULONGLONG)(0x98A5BE0C3212) >> (8 * 0)) & 0xFF)} };
    enum WPP_DEFINE_BIT_NAMES { WPP_BLOCK_START_SampleLogGuid = WPP_CTL_SampleLogGuid * 0x10000, WPP_BIT_Global, WPP_BLOCK_END_SampleLogGuid, };
    enum _WPP_FLAG_LEN_ENUM { WPP_FLAG_LEN = 1 | ((0 | WPP_BLOCK_END_SampleLogGuid) & 0xFFFF) / 32 };
    typedef union {
        WPP_TRACE_CONTROL_BLOCK Control;
        UCHAR ReserveSpace[ sizeof(WPP_TRACE_CONTROL_BLOCK) + sizeof(ULONG) * (WPP_FLAG_LEN - 1) ];
    } WPP_PROJECT_CONTROL_BLOCK ;
    
    extern __declspec(selectany) WPP_PROJECT_CONTROL_BLOCK *WPP_GLOBAL_Control = (WPP_PROJECT_CONTROL_BLOCK*)&WPP_GLOBAL_Control;
    };
    extern "C" {
    static const GUID WPP_Sample_cpp_Traceguids[] = { {0xe3fea65e,0x6a49,0xf25b,{0x80,0x1e,0x58,0x29,0x13,0xaa,0x3c,0x98}}, };
    enum {WPP_TRACE_OPTIONS = 1   | 2
                            | 32 | 8 };
    __declspec(noinline) __inline void WPP_SF_(TRACEHANDLE Logger, unsigned short id, LPCGUID TraceGuid)
       { TraceMessage(Logger, WPP_TRACE_OPTIONS, (LPGUID)TraceGuid, id,  0); }
    };
    int main(int argc, char** argv)
    {
        if (argc < 2) {
             __annotation(L"TMF:", L"e3fea65e-6a49-f25b-801e-582913aa3c98 Sample // SRC=Sample.cpp MJ= MN=", L"#typev  Sample_cpp13 10 \"%0Missing argument\" //   LEVEL=TRACE_LEVEL_ERROR FLAGS=Global", L"{", L"}"), ( ( (WPP_GLOBAL_Control != (WPP_PROJECT_CONTROL_BLOCK*)&WPP_GLOBAL_Control) && (((WPP_GLOBAL_Control[((WPP_BIT_Global) >> 16)].Control).Flags[( (0xFFFF & ((WPP_BIT_Global)-1) ) / 32)] & (1 << ( ((WPP_BIT_Global)-1) & 31 ))) && (WPP_GLOBAL_Control[((WPP_BIT_Global) >> 16)].Control).Level >= 2) ? WPP_SF_(((WPP_GLOBAL_Control[((WPP_BIT_Global) >> 16)].Control).Logger), 10, WPP_Sample_cpp_Traceguids+0), 1:0 ) ) ;
            return 1;
        }
        return 0;
    }
    

    First of all it seems MSVC has hidden intrinsic function

    void __cdecl __annotation(const unsigned short *, ...);
    

    Is there a way add it to windows.cfg
    Any idea how to handle code like this?

    Thank you

    Palo

     

    Last edit: pmisik 2017-10-31
  • Daniel Marjamäki

    I am not good at WPP.

    What happens if you don't include the tmh files in the analysis? For instance, delete sample.tmh before running cppcheck.

    Then if you want you could add a windows_wpp.cfg that provides configuration for DoTraceLevelMessage() etc. I would be happy to add such cfg file in our repo.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.