0

Error: Unable to Start ETW Trace Session in C++ (Error Code 87)

I'm developing a C++ application to consume and print real-time events using Event Tracing for Windows (ETW). However, I'm encountering issues when trying to start the trace and register the provider. The errors are as follows:

unable to start trace 87 unable to register provider 87

These errors indicate ERROR_INVALID_PARAMETER, but I can't identify which parameters are incorrect. Below is my code snippet:

#pragma once
#include <windows.h>
#include <evntrace.h>
#include <evntcons.h>
#include <iostream>
#include <thread>



class EventProvider
{
private:
    TRACEHANDLE sessionhandle;
    TRACEHANDLE consumertrace;
    GUID eventprovider;
    LPCWSTR sessionname;
    PEVENT_TRACE_PROPERTIES properties;
    bool running;
public:
    EventProvider(LPCWSTR, GUID);
    void initProperty();
    void startTrace();
    void consumer();
    static void run(PTRACEHANDLE);
    static VOID WINAPI eventcallback(PEVENT_RECORD);
    ~EventProvider();
};

EventProvider::EventProvider(LPCWSTR sessionname, GUID provider)
    : sessionhandle(0), consumertrace(0), eventprovider(provider), sessionname(sessionname), properties(nullptr), running(false)
{
    this->initProperty();
    this->startTrace();
    this->consumer();
}

void EventProvider::initProperty() {
    ULONG buffsize = sizeof(EVENT_TRACE_PROPERTIES) + 2 * sizeof(WCHAR) * 1024;
    this->properties = (EVENT_TRACE_PROPERTIES*)malloc(buffsize);
    if (this->properties == NULL) {
        std::cout << "Unable to allocate bytes for properties" << std::endl;
    }
    ZeroMemory(this->properties, buffsize);
    this->properties->Wnode.BufferSize = buffsize;
    this->properties->Wnode.Guid = this->eventprovider;
    this->properties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
    this->properties->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
    this->properties->Wnode.ClientContext = 1;
    this->properties->LogFileNameOffset = 0;
    this->properties->EnableFlags = EVENT_TRACE_FLAG_PROCESS;
    this->properties->BufferSize = 64;        // Size of each tracing buffer in KB
    this->properties->MinimumBuffers = 1;
    this->properties->MaximumBuffers = 5;
    this->properties->MaximumFileSize = 0;

}
VOID WINAPI EventProvider::eventcallback(PEVENT_RECORD pevent) {
    std::cout << "i have bbencalled" << std::endl;
}
void EventProvider::startTrace() {
    DWORD status = StartTraceW((PTRACEHANDLE)sessionhandle, sessionname, properties);
    if (status != ERROR_SUCCESS) {
        std::cout << "unable to start trace " << GetLastError() << std::endl;
    }

    DWORD status2 = EnableTraceEx2(this->sessionhandle, &this->eventprovider, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_INFORMATION, 0, 0, 0, NULL);
    if (status != ERROR_SUCCESS) {
        std::cout << "unable to register provider " << GetLastError() << std::endl;
    }
}
void EventProvider::run(PTRACEHANDLE handel) {
    if (ProcessTrace(handel, 1, 0, 0) != ERROR_SUCCESS) {
        exit(0);
    }
}
void EventProvider::consumer() {
    EVENT_TRACE_LOGFILEW trace;
    TRACE_LOGFILE_HEADER* pheader = &trace.LogfileHeader;
    ZeroMemory(&trace, sizeof(EVENT_TRACE_LOGFILEW));
    trace.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD;
    trace.EventRecordCallback = (PEVENT_RECORD_CALLBACK)(EventProvider::eventcallback);
    trace.LoggerName = (LPWSTR)R"(ANTI TRACER)";
    TRACEHANDLE handle = OpenTraceW((PEVENT_TRACE_LOGFILEW)&trace);
    if (handle == INVALID_PROCESSTRACE_HANDLE) {
        std::cout << "Unable start trace session : " << GetLastError() << std::endl;
    }
    consumertrace = (TRACEHANDLE)handle;
    std::thread thread(run, (PTRACEHANDLE)consumertrace);

}

I need help identifying and fixing the issue. My goal is to consume events in real-time and print each event's output to the terminal. Any guidance or suggestions would be greatly appreciated.

1
  • I think FlushTimer should be set to 1 or a higher value, also you could need EVENT_TRACE_INDEPENDENT_SESSION_MODE. See github.com/microsoft/perfview/blob/… for a working example although it is in C#. Commented Jul 25, 2024 at 15:01

1 Answer 1

0

I think before you start your trace, make sure if previous traces are running you need to stop them. So just call ControlTrace(0, SessionName, sessionProperties, EVENT_TRACE_CONTROL_STOP);

I hope this should clear your errors. Also in this->properties->Wnode.Guid = this->eventprovider; I think this is not event provider, this is the GUID for session.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.