-1

I am using Event Tracing for Windows to monitor disk io and network usage of processes. I have used ETW with KERNEL_LOGGER_NAME , EVENT_TRACE_FLAG_PROCESS , EVENT_TRACE_FLAG_DISK_IO, EVENT_TRACE_FLAG_NETWORK_TCPIP:

static const GUID GUID_DISK_IO = { 0x3d6fa8d4, 0xfe05, 0x11d0, { 0x9d, 0xda, 0x00, 0xc0, 0x4f, 0xd7, 0xba, 0x7c } };
static const GUID GUID_TCPIP = { 0x9a280ac0, 0xc8e0, 0x11d1, { 0x84, 0xe2, 0x00, 0xc0, 0x4f, 0xb9, 0x98, 0xa2 } };

VOID WINAPI ProcessMonitor::EventRecordCallback(PEVENT_RECORD pEventRecord) {
  bool isIo = false, isNet = false;
  if (pEventRecord->EventHeader.ProviderId == GUID_DISK_IO) isIo = true;
  if (pEventRecord->EventHeader.ProviderId == GUID_TCPIP) isNet = true;
  if (!isIo && !isNet) return;
  if (pEventRecord->EventHeader.EventDescriptor.Opcode != 10 && pEventRecord->EventHeader.EventDescriptor.Opcode != 11) return;

  DWORD pid = pEventRecord->EventHeader.ProcessId;
  ULONG dataSize = 0;
  //std::cout << "Event appeared\n";

  PROPERTY_DATA_DESCRIPTOR desc;
  ZeroMemory(&desc, sizeof(desc));
  desc.PropertyName = (ULONGLONG)L"Size";
  desc.ArrayIndex = ULONG_MAX;
  TDHSTATUS status = TdhGetProperty(pEventRecord, 0, nullptr, 1, &desc, sizeof(dataSize), (PBYTE)&dataSize);
  if (status != ERROR_SUCCESS) {
    ZeroMemory(&desc, sizeof(desc));
    desc.PropertyName = (ULONGLONG)L"size";
    desc.ArrayIndex = ULONG_MAX;
    status = TdhGetProperty(pEventRecord, 0, nullptr, 1, &desc, sizeof(dataSize), (PBYTE)&dataSize);
    if (status != ERROR_SUCCESS) {
      ZeroMemory(&desc, sizeof(desc));
      desc.PropertyName = (ULONGLONG)L"length";
      desc.ArrayIndex = ULONG_MAX;
      status = TdhGetProperty(pEventRecord, 0, nullptr, 1, &desc, sizeof(dataSize), (PBYTE)&dataSize);
      if (status != ERROR_SUCCESS) {
        ZeroMemory(&desc, sizeof(desc));
        desc.PropertyName = (ULONGLONG)L"TransferSize";
        desc.ArrayIndex = ULONG_MAX;
        status = TdhGetProperty(pEventRecord, 0, nullptr, 1, &desc, sizeof(dataSize), (PBYTE)&dataSize);
        if (status != ERROR_SUCCESS) return;
      }
    }
  }

  std::cout << "PID: " << pid << " Trace data: " << dataSize << "\n";
  auto* self = (ProcessMonitor*)(pEventRecord->UserContext);
  if (isIo) self->addIoCount(dataSize, pid);
  if (isNet) self->addNetCount(dataSize, pid);
}

void ProcessMonitor::run() {
  //...............................ETW............................
  TRACEHANDLE hSession = 0;

  ULONG bufferSize = sizeof(EVENT_TRACE_PROPERTIES) + 1024;
  EVENT_TRACE_PROPERTIES* pSessionProperties = (EVENT_TRACE_PROPERTIES*)malloc(bufferSize);
  ZeroMemory(pSessionProperties, bufferSize);
  pSessionProperties->Wnode.BufferSize = bufferSize;
  pSessionProperties->Wnode.ClientContext = 1;
  pSessionProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
  wcscpy_s((wchar_t*)(pSessionProperties + 1), 1024, KERNEL_LOGGER_NAME);
  pSessionProperties->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
  pSessionProperties->EnableFlags = EVENT_TRACE_FLAG_PROCESS |
    EVENT_TRACE_FLAG_IMAGE_LOAD |
    EVENT_TRACE_FLAG_DISK_IO |
    EVENT_TRACE_FLAG_DISK_IO_INIT |
    EVENT_TRACE_FLAG_FILE_IO |
    EVENT_TRACE_FLAG_NETWORK_TCPIP;

  ULONG status = StartTrace(&hSession, KERNEL_LOGGER_NAME, pSessionProperties);
  if (status != ERROR_SUCCESS) {
    std::cout << "StartTrace failed: " << status << "\n";
    return;
  }

  EVENT_TRACE_LOGFILE logFile = {};
  logFile.LoggerName = (LPWSTR)KERNEL_LOGGER_NAME;
  logFile.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD;
  logFile.EventRecordCallback = EventRecordCallback;
  logFile.Context = this;

  TRACEHANDLE hTrace = OpenTrace(&logFile);
  if (hTrace == INVALID_PROCESSTRACE_HANDLE) {
    std::cout << "OpenTrace failed\n";
    return;
  }

  std::cout << "Start tracing...\n";
  std::thread traceThread([&]() {
    ProcessTrace(&hTrace, 1, nullptr, nullptr);
  });

  while (1) {
      if (_kbhit()) {
        char c = _getch();
        if (c == 'q') break;
      }
      scan();
      sample();
      std::this_thread::sleep_for(std::chrono::seconds(monitorInterval));
    }
  CloseTrace(hTrace);
  ControlTrace(hSession, KERNEL_LOGGER_NAME, pSessionProperties, EVENT_TRACE_CONTROL_STOP);
  traceThread.join();
  free(pSessionProperties);
}

...but all I got is a bunch of events with PID: 4294967295 (Trace data is the size of data of the events) when running a browser with about 10 tabs:

PID: 4294967295 Trace data: 24576
PID: 4294967295 Trace data: 24576
PID: 4294967295 Trace data: 8192
PID: 4294967295 Trace data: 106496
PID: 4294967295 Trace data: 4096
PID: 4294967295 Trace data: 24576
PID: 4294967295 Trace data: 4096
PID: 4294967295 Trace data: 4096

Help me find out where I have wrong.

8
  • 4
    4294967295 is 0xFFFFFFFF so I expect it to mean some type of error like INVALID_HANDLE_VALUE Commented Nov 13 at 16:39
  • I have checked for error in each steps. Beside I was run a browser with many tabs (youtube, google, and others) to check, it got dataSize and printed so I think the tracing process worked but have some problems with the process id. Commented Nov 13 at 16:51
  • 1
    What code are you using to receive the EVENT_RECORD? Please provide a minimal reproducible example that demonstrates the problem in action. Commented Nov 13 at 16:56
  • It was provided by a call back set in logFile.EventRecordCallback = EventRecordCallback;. After OpenTrace(), ETW will call this function if events appeared. Commented Nov 13 at 17:02
  • 6
    Take this with a grain of salt, as I don't find documentation on this, but Google says: "The value ffffffff (or 0xFFFFFFFF) for an ETW (Event Tracing for Windows) process ID often signifies that the event is associated with a system-level operation not tied to a specific user-mode process at that exact moment. This typically occurs in events generated by the Windows kernel or system providers." Also per this comment: "The kernel does not always handle user-mode requests in user-mode process' context." Commented Nov 13 at 17:19

0

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.