summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2025-11-12 13:31:50 +0100
committerladevieq <ladevie.quentin@gmail.com>2025-11-12 13:31:50 +0100
commitc260d74c460e4b8933fd42a2f60f7148d45d459d (patch)
treecb37f0f88ded4dc11f6463149001025a63997b9e
parent06b87e66c9b542cc4fc1093fe12651d7edd64dcb (diff)
-rw-r--r--compile_flags.txt9
-rw-r--r--include/events.h2
-rw-r--r--src/main.c432
3 files changed, 292 insertions, 151 deletions
diff --git a/compile_flags.txt b/compile_flags.txt
index 10f69c1..8e7c3ab 100644
--- a/compile_flags.txt
+++ b/compile_flags.txt
@@ -1,6 +1,3 @@
-/Zi
-/Od
-/Iinclude
-/Fd:%BUILD_DIR%\main.pdb
-/Fo:%BUILD_DIR%\main.obj
-/link /SUBSYSTEM:CONSOLE /OUT:%BUILD_DIR%\main.exe user32.lib advapi32.lib libucrtd.lib
+-O0
+-Iinclude
+-link /SUBSYSTEM:CONSOLE /OUT:%BUILD_DIR%\main.exe user32.lib advapi32.lib libucrtd.lib
diff --git a/include/events.h b/include/events.h
index 5ee2b6b..eaef927 100644
--- a/include/events.h
+++ b/include/events.h
@@ -50,7 +50,7 @@ CLASSIC_EVENT_ID EventThreadEnd = {
.Type = 2U,
.Reserved = { 0U },
};
-CLASSIC_EVENT_ID EventDataCollectionStart = {
+CLASSIC_EVENT_ID EventThreadDataCollectionStart = {
.EventGuid = THREAD_EVENTS_GUID,
.Type = 3U,
.Reserved = { 0U },
diff --git a/src/main.c b/src/main.c
index 66be1d7..03ddbcd 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,6 +2,7 @@
#include <stdio.h>
#include <assert.h>
#include <math.h>
+#include <string.h>
#include <Windows.h>
@@ -12,9 +13,55 @@
#include "events.h"
-typedef uint32_t u32;
+typedef uint64_t u64;
+typedef uint32_t u32;
+typedef uint8_t u8;
+typedef int8_t i8;
-// #define REAL_TIME_MODE
+DEFINE_GUID(PMC_TRACE_GUID, 0x7e5ac468, 0x6864, 0x4b43, 0xa0, 0xf4, 0xef, 0x4d, 0xa7, 0x6e, 0x07, 0x4a);
+DEFINE_GUID(PMC_TRACE_START_GUID, 0x7e5ac468, 0x6864, 0x4b43, 0xa0, 0xf4, 0xef, 0x4d, 0xa7, 0x6e, 0x07, 0x4b);
+
+enum PMC_CAPTURE_STATUS {
+ PMC_CAPTURE_STATUS_INACTIVE = 0U,
+ PMC_CAPTURE_STATUS_STARTED = 1U,
+ PMC_CAPTURE_STATUS_STOPPED = 2U,
+};
+
+struct PMC_marker_data {
+ u32 unique_id;
+ const char* name;
+ u32 thread_id;
+};
+struct begin_capture_event {
+ EVENT_TRACE_HEADER header;
+ struct PMC_marker_data data;
+};
+
+struct end_capture_event {
+ EVENT_TRACE_HEADER header;
+ struct PMC_marker_data data;
+};
+
+struct capture {
+ TRACEHANDLE trace_handle;
+ TRACEHANDLE logger_handle;
+ TRACEHANDLE event_provider_handle;
+};
+
+#define REAL_TIME_MODE
+
+#if !defined(REAL_TIME_MODE)
+#define LOGFILE_NAME "test_etw_log.etl"
+#endif
+
+struct trace_process_ctx {
+ u32 PMCs_count;
+ u32* PMCs;
+ u64* values;
+ u64* start_values;
+ u32 thread_id;
+ u8* started;
+};
#define SOURCE_TIMER "Timer"
#define SOURCE_TIMER_INDEX 0U
@@ -75,7 +122,7 @@ const char* PMC_SOURCES[] = {
"RetiredMmxInstructions",
"RetiredSseInstructions",
};
-const u32 PMC_SOURCES_COUNT = 49U;
+const u32 PMC_SOURCES_COUNT = sizeof(PMC_SOURCES) / sizeof(PMC_SOURCES[0U]);
void log_error(DWORD dw) {
// Retrieve the system error message for the last-error code
@@ -97,129 +144,196 @@ void log_error(DWORD dw) {
LocalFree(lpMsgBuf);
}
+#define TRACE_NAME "test_etw"
+
struct event_trace_property_data {
EVENT_TRACE_PROPERTIES_V2 props;
#if !defined(REAL_TIME_MODE)
- char log_file_name[128];
-#endif
- char logger_name[1024];
- char buffer[256 * 1024U];
-} data = {
- .props = {
- .Wnode = {
- .BufferSize = offsetof(struct event_trace_property_data, buffer),
- .Flags = WNODE_FLAG_TRACED_GUID | WNODE_FLAG_VERSIONED_PROPERTIES,
- },
- .BufferSize = sizeof(data.buffer),
- .MinimumBuffers = 4U,
- .MaximumBuffers = 4U,
- .EnableFlags = // EVENT_TRACE_FLAG_PROFILE |
- EVENT_TRACE_FLAG_INTERRUPT |
- EVENT_TRACE_FLAG_SYSTEMCALL |
- EVENT_TRACE_FLAG_DPC |
- EVENT_TRACE_FLAG_THREAD |
- EVENT_TRACE_FLAG_CSWITCH |
- EVENT_TRACE_FLAG_DISPATCHER |
- EVENT_TRACE_FLAG_PROCESS |
- EVENT_TRACE_FLAG_PROCESS_COUNTERS,
- .LogFileMode = EVENT_TRACE_SYSTEM_LOGGER_MODE,
-#if defined(REAL_TIME_MODE)
- .LogFileMode = EVENT_TRACE_REAL_TIME_MODE,
-#else
- .LogFileNameOffset = offsetof(struct event_trace_property_data, log_file_name),
-#endif
- .LoggerNameOffset = offsetof(struct event_trace_property_data, logger_name),
- },
-#if !defined(REAL_TIME_MODE)
- .log_file_name = "test_etw_log.etl",
+ char log_file_name[sizeof(LOGFILE_NAME)];
#endif
- .logger_name = KERNEL_LOGGER_NAMEA,
-};
+ char logger_name[sizeof(TRACE_NAME)];
+} data = { 0U };
-DWORD pid = 0U;
+ULONG WINAPI Wmidprequest(WMIDPREQUESTCODE RequestCode, PVOID RequestContext, ULONG *BufferSize, PVOID Buffer) {
+ return 0U;
+}
-void PeventRecordCallback(PEVENT_RECORD pEventRecord) {
- // if (pEventRecord->EventHeader.ProcessId != pid) {
- // return;
- // }
- EVENT_HEADER* header = &pEventRecord->EventHeader;
- u32* sources = (u32*)pEventRecord->UserContext;
+void PeventRecordCallback(PEVENT_RECORD event_record) {
+ struct trace_process_ctx* ctx = (struct trace_process_ctx*)event_record->UserContext;
+ GUID provider = event_record->EventHeader.ProviderId;
+
+ if (memcmp(&provider, &PMC_TRACE_GUID, sizeof(provider)) == 0) {
+ *ctx->started = PMC_CAPTURE_STATUS_STARTED;
+ return;
+ }
+
+ if (memcmp(&provider, &PMC_TRACE_GUID, sizeof(provider)) == 0) {
+ *ctx->started = PMC_CAPTURE_STATUS_STOPPED;
+ return;
+ }
+
+ u32 opcode = event_record->EventHeader.EventDescriptor.Opcode;
+ GUID thread_guid = THREAD_EVENTS_GUID;
+ GUID perf_info_guid = PERF_INFO_EVENTS_GUID;
+ if (memcmp(&provider, &thread_guid, sizeof(provider)) != 0 || opcode != EventThreadContextSwitch.Type) {
+ return;
+ }
+
+ if (memcmp(&provider, &perf_info_guid, sizeof(provider)) != 0 || (opcode != EventSysCallEnter.Type && opcode != EventSysCallExit.Type)) {
+ return;
+ }
- PEVENT_HEADER_EXTENDED_DATA_ITEM extended_data = pEventRecord->ExtendedData;
- PEVENT_HEADER_EXTENDED_DATA_ITEM cur_data = extended_data;
- for (u32 index = 0U; index < pEventRecord->ExtendedDataCount; index++, cur_data++) {
+ PEVENT_HEADER_EXTENDED_DATA_ITEM cur_data = event_record->ExtendedData;
+ for (u32 index = 0U; index < event_record->ExtendedDataCount; index++, cur_data++) {
if (cur_data->ExtType == EVENT_HEADER_EXT_TYPE_PMC_COUNTERS) {
- printf("PID: %lx, TID: %lx\n", header->ProcessId, header->ThreadId);
ULONG64* pmc = (ULONG64*)cur_data->DataPtr;
size_t pmc_count = cur_data->DataSize / sizeof(pmc[0U]);
- for (u32 pmc_index = 0U; pmc_index < pmc_count; pmc_index++, pmc++) {
- printf("%s: %llu\n", PMC_SOURCES[sources[pmc_index]], *pmc);
+
+ if (opcode == EventThreadContextSwitch.Type) {
+ u32 new_thread_id = *(u32*)event_record->UserData;
+ u32 old_thread_id = *((u32*)event_record->UserData + 1U);
+ if (new_thread_id == ctx->thread_id) {
+ for (u32 pmc_index = 0U; pmc_index < pmc_count; pmc_index++) {
+ ctx->start_values[pmc_index] = pmc[pmc_index];
+ }
+ } else if (old_thread_id == ctx->thread_id) {
+ for (u32 pmc_index = 0U; pmc_index < pmc_count; pmc_index++) {
+ if (ctx->start_values[pmc_index] != 0U) {
+ ctx->values[pmc_index] += pmc[pmc_index] - ctx->start_values[pmc_index];
+ }
+ }
+ }
+ } else if (opcode == EventSysCallExit.Type) {
+ for (u32 pmc_index = 0U; pmc_index < pmc_count; pmc_index++) {
+ if (ctx->start_values[pmc_index] == 0U) {
+ ctx->start_values[pmc_index] = pmc[pmc_index];
+ }
+ }
+ } else {
+ for (u32 pmc_index = 0U; pmc_index < pmc_count; pmc_index++) {
+ if (ctx->start_values[pmc_index] != 0U) {
+ ctx->values[pmc_index] += pmc[pmc_index] - ctx->start_values[pmc_index];
+ }
+ }
}
}
}
}
-EVENT_TRACE_LOGFILEA trace_log = {
-#if defined(REAL_TIME_MODE)
- .LoggerName = KERNEL_LOGGER_NAMEA,
- .ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD,
-#else
- .LogFileName = "test_etw_log.etl",
- .ProcessTraceMode = PROCESS_TRACE_MODE_EVENT_RECORD,
-#endif
- .EventRecordCallback = &PeventRecordCallback,
- // .LogFileMode = EVENT_TRACE_SYSTEM_LOGGER_MODE,
-};
-
-u32 end_trace(TRACEHANDLE handle) {
+u32 end_trace(struct capture* capture) {
ULONG res = 0U;
- if ((res = ControlTraceA(handle, KERNEL_LOGGER_NAMEA, (EVENT_TRACE_PROPERTIES*)&data.props, EVENT_TRACE_CONTROL_STOP)) != ERROR_SUCCESS) {
+
+ if ((res = UnregisterTraceGuids(capture->event_provider_handle)) != ERROR_SUCCESS) {
+ log_error(res);
+ }
+
+ if ((res = ControlTraceA(capture->trace_handle, TRACE_NAME, (EVENT_TRACE_PROPERTIES*)&data.props, EVENT_TRACE_CONTROL_STOP)) != ERROR_SUCCESS) {
log_error(res);
return 1U;
}
+
return 0U;
}
-u32 begin_trace(TRACEHANDLE* handle, u32* pmc_sources, u32 sources_size) {
+u32 begin_trace(struct capture* capture, u32* pmc_sources, u32 sources_size) {
ULONG res = 0U;
- data.props.Wnode.Guid = SystemTraceControlGuid;
- if ((res = StartTraceA(handle, KERNEL_LOGGER_NAMEA, (EVENT_TRACE_PROPERTIES*)&data.props)) != ERROR_SUCCESS) {
+ data.props.Wnode.BufferSize = sizeof(struct event_trace_property_data);
+ data.props.Wnode.Flags = WNODE_FLAG_TRACED_GUID | WNODE_FLAG_VERSIONED_PROPERTIES;
+
+ data.props.VersionNumber = 2UL;
+ data.props.BufferSize = 16384U;
+ data.props.MinimumBuffers = 4U;
+ data.props.MaximumBuffers = 4U;
+ data.props.MaximumFileSize = 0U;
+ data.props.VersionNumber = 2U;
+ data.props.EnableFlags = EVENT_TRACE_FLAG_NO_SYSCONFIG |
+ EVENT_TRACE_FLAG_CSWITCH |
+ EVENT_TRACE_FLAG_SYSTEMCALL;
+ data.props.LogFileMode = EVENT_TRACE_SYSTEM_LOGGER_MODE;
+ data.props.LoggerNameOffset = offsetof(struct event_trace_property_data, logger_name),
+
+#if defined(REAL_TIME_MODE)
+ data.props.LogFileMode |= EVENT_TRACE_REAL_TIME_MODE;
+#else
+ data.props.log_file_name = LOGFILE_NAME,
+ data.props.LogFileNameOffset= offsetof(struct event_trace_property_data, log_file_name),
+#endif
+
+ strcpy(TRACE_NAME, data.logger_name);
+
+ if ((res = StartTraceA(&capture->trace_handle, TRACE_NAME, (EVENT_TRACE_PROPERTIES*)&data.props)) != ERROR_SUCCESS) {
+ log_error(res);
+ return 1U;
+ }
+
+ TRACE_GUID_REGISTRATION trace_registration = {
+ .Guid = &PMC_TRACE_START_GUID,
+ .RegHandle = NULL,
+ };
+ if ((res = RegisterTraceGuidsA((WMIDPREQUEST)Wmidprequest, NULL, &PMC_TRACE_GUID, 1U, &trace_registration, NULL, NULL, &capture->event_provider_handle)) != ERROR_SUCCESS) {
+ log_error(res);
+ return 1U;
+ }
+
+ // if ((res = EnableTraceEx2(capture->trace_handle, &PMC_TRACE_GUID, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_VERBOSE, 0U, 0U, 0U, NULL) != ERROR_SUCCESS)) {
+ // log_error(res);
+ // return 1U;
+ // }
+
+ if ((res = TraceSetInformation(capture->trace_handle, TracePmcCounterListInfo, pmc_sources, sources_size)) != ERROR_SUCCESS) { // PMCs to collect
log_error(res);
return 1U;
}
- if ((res = TraceSetInformation(*handle, TracePmcCounterListInfo, pmc_sources, sources_size)) != ERROR_SUCCESS) { // PMCs to collect
+ CLASSIC_EVENT_ID events[] = {
+ EventThreadContextSwitch,
+ EventSysCallExit,
+ EventSysCallEnter,
+ };
+ if ((res = TraceSetInformation(capture->trace_handle, TracePmcEventListInfo, &events, sizeof(events))) != ERROR_SUCCESS) { // Events on which we collect PMCs
log_error(res);
- end_trace(*handle);
return 1U;
}
return 0U;
}
-u32 begin_PMCs_capture(TRACEHANDLE handle) {
- CLASSIC_EVENT_ID events[] = {
- EventProcessPMC,
- EventProcessPMCRundown,
+u32 begin_PMCs_capture(struct capture* capture) {
+ struct begin_capture_event event = {
+ .header = {
+ .Size = sizeof(event),
+ .Guid = PMC_TRACE_START_GUID,
+ .Flags = WNODE_FLAG_TRACED_GUID,
+ },
+ .data = {
+ .thread_id = GetThreadId(GetCurrentThread()),
+ },
};
- ULONG res = 0U;
- if ((res = TraceSetInformation(handle, TracePmcEventListInfo, &events, sizeof(events))) != ERROR_SUCCESS) { // Events on which we collect PMCs
+ ULONG res = TraceEvent(capture->trace_handle, &event.header);
+ if (res != ERROR_SUCCESS) {
log_error(res);
- end_trace(handle);
return 1U;
}
return 0U;
}
-u32 end_PMCs_capture(TRACEHANDLE handle) {
- ULONG res = 0U;
- // TODO: Make it stop
- // if ((res = TraceSetInformation(handle, TracePmcEventListInfo, NULL, 0U)) != ERROR_SUCCESS) {
- // log_error(res);
- // end_trace(handle);
- // return 1U;
- // }
+u32 end_PMCs_capture(struct capture* capture) {
+ struct end_capture_event event = {
+ .header = {
+ .Size = sizeof(event),
+ .Guid = PMC_TRACE_GUID,
+ .Flags = WNODE_FLAG_TRACED_GUID,
+ },
+ .data = {
+ .thread_id = GetThreadId(GetCurrentThread()),
+ },
+ };
+ ULONG res = TraceEvent(capture->trace_handle, &event.header);
+ if (res != ERROR_SUCCESS) {
+ log_error(res);
+ return 1U;
+ }
return 0U;
}
@@ -259,105 +373,135 @@ u32 list_sources() {
return 0U;
}
-int main() {
- pid = GetProcessId(GetCurrentProcess());
+u32 PMCs[] = {
+ SOURCE_TOTAL_ISSUES_INDEX,
+ SOURCE_BRANCH_INSTRUCTIONS_INDEX,
+};
+u64 PMCs_values[sizeof(PMCs) / sizeof(PMCs[0U])] = {
+ 0U,
+};
+u64 PMCs_start_values[sizeof(PMCs) / sizeof(PMCs[0U])] = {
+ 0U,
+};
- TRACEHANDLE handle;
- u32 PMCs[] = {
- SOURCE_TOTAL_ISSUES_INDEX,
- SOURCE_BRANCH_INSTRUCTIONS_INDEX,
+u8 started = 0U;
+u32 open_trace(struct capture* capture) {
+ ULONG res = 0U;
+ struct trace_process_ctx ctx = {
+ .PMCs_count = sizeof(PMCs) / sizeof(PMCs[0U]),
+ .PMCs = PMCs,
+ .values = PMCs_values,
+ .start_values = PMCs_start_values,
+ .thread_id = GetThreadId(GetCurrentThread()),
+ .started = &started
};
- static_assert(sizeof(PMCs) / sizeof(PMCs[0U]) <= 4U, "Too much PMCs");
- if (begin_trace(&handle, PMCs, sizeof(PMCs))) {
- end_trace(handle);
- return 1;
+
+ EVENT_TRACE_LOGFILEA trace_log = { 0U };
+
+ trace_log.EventRecordCallback = PeventRecordCallback;
+ trace_log.Context = &ctx;
+#if defined(REAL_TIME_MODE)
+ trace_log.LoggerName = TRACE_NAME;
+ trace_log.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD | PROCESS_TRACE_MODE_RAW_TIMESTAMP;
+#else
+ trace_log.LogFileName = "test_etw_log.etl";
+ trace_log.ProcessTraceMode = PROCESS_TRACE_MODE_EVENT_RECORD;
+#endif
+
+ if ((capture->logger_handle = OpenTraceA(&trace_log)) == INVALID_PROCESSTRACE_HANDLE) {
+ log_error(GetLastError());
+ return 1U;
}
+ return 0U;
+}
- ULONG res = 0U;
#ifdef REAL_TIME_MODE
- TRACEHANDLE pt_handle = OpenTraceA(&trace_log);
- if (pt_handle == INVALID_PROCESSTRACE_HANDLE) {
- log_error(GetLastError());
- end_trace(handle);
+DWORD WINAPI process_event_routine(LPVOID params) {
+ ULONG res = 0U;
+ struct capture* capture = params;
+
+ if (open_trace(capture)) {
+ ExitThread(1U);
+ return 1U;
}
- if ((res = ProcessTrace(&pt_handle, 1U, NULL, NULL)) != ERROR_SUCCESS) {
+ if ((res = ProcessTrace(&capture->logger_handle, 1U, NULL, NULL)) != ERROR_SUCCESS) {
log_error(res);
- end_trace(handle);
+ ExitThread(1U);
+ return 1U;
}
+
+ if ((res = CloseTrace(capture->logger_handle)) != ERROR_SUCCESS) {
+ log_error(res);
+ ExitThread(1U);
+ return 1U;
+ }
+
+ ExitThread(0U);
+ return 0U;
+}
#endif
- // ULONG masks[8U] = {
- // // EVENT_TRACE_FLAG_PROFILE |
- // EVENT_TRACE_FLAG_INTERRUPT |
- // EVENT_TRACE_FLAG_SYSTEMCALL |
- // EVENT_TRACE_FLAG_DPC |
- // EVENT_TRACE_FLAG_THREAD |
- // EVENT_TRACE_FLAG_CSWITCH |
- // EVENT_TRACE_FLAG_DISPATCHER |
- // EVENT_TRACE_FLAG_PROCESS |
- // EVENT_TRACE_FLAG_PROCESS_COUNTERS,
- // // 0x20000400, // PERF_PERF_PMC
- // 0U,
- // 0U,
- // 0U,
- // 0U,
- // 0U,
- // 0U,
- // };
- // if ((res = TraceSetInformation(trace_handle, TraceSystemTraceEnableFlagsInfo, &masks, sizeof(masks))) != ERROR_SUCCESS) {
- // log_error(res);
- // end_trace(handle);
- // }
+int main() {
+ struct capture capture;
+ static_assert(sizeof(PMCs) / sizeof(PMCs[0U]) <= 4U, "Too much PMCs");
+ if (begin_trace(&capture, PMCs, sizeof(PMCs))) {
+ end_trace(&capture);
+ return 1;
+ }
- // if ((res = EnableTraceEx2(trace_handle, &SystemProcessProviderGuid, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_VERBOSE, ~0U, 0U, 0U, NULL)) != ERROR_SUCCESS) {
- // log_error(res);
- // end_trace(handle);
- // }
+ ULONG res = 0U;
+#ifdef REAL_TIME_MODE
+ DWORD process_event_thread_id = 0U;
+ HANDLE handle_process_event_thread = CreateThread(NULL, 64U * 1024U, process_event_routine, (LPVOID)&capture, 0U, &process_event_thread_id);
+#endif
- if (begin_PMCs_capture(handle)) {
- end_trace(handle);
+ int j = 0;
+ while (j < 4) {
+ Sleep(1000U);
+ j++;
+ }
+
+ if (begin_PMCs_capture(&capture)) {
+ end_trace(&capture);
return 1;
}
int i = 0;
float f = 0.5f;
while (i < 4) {
- Sleep(1000U);
f = sinf(f);
i++;
}
- if (end_PMCs_capture(handle)) {
- end_trace(handle);
+ if (end_PMCs_capture(&capture)) {
+ end_trace(&capture);
return 1;
}
- // if ((res = EnableTraceEx2(trace_handle, &SystemProcessProviderGuid, EVENT_CONTROL_CODE_DISABLE_PROVIDER, TRACE_LEVEL_VERBOSE, ~0U, 0U, 0U, NULL)) != ERROR_SUCCESS) {
- // log_error(res);
- // end_trace(handle);
- // }
+#if defined(REAL_TIME_MODE)
+ WaitForSingleObject(handle_process_event_thread, INFINITE);
+ CloseHandle(handle_process_event_thread);
+#endif
- if (end_trace(handle)) {
+ if (end_trace(&capture)) {
return 1;
}
#if !defined(REAL_TIME_MODE)
- trace_log.Context = PMCs;
- TRACEHANDLE pt_handle = OpenTraceA(&trace_log);
- if (pt_handle == INVALID_PROCESSTRACE_HANDLE) {
- log_error(GetLastError());
+ if (open_trace(&capture)) {
+ return 1;
}
- if ((res = ProcessTrace(&pt_handle, 1U, NULL, NULL)) != ERROR_SUCCESS) {
+ if ((res = ProcessTrace(&capture.logger_handle, 1U, NULL, NULL)) != ERROR_SUCCESS) {
log_error(res);
}
-#endif
- if ((res = CloseTrace(pt_handle)) != ERROR_SUCCESS) {
+ if ((res = CloseTrace(capture.logger_handle)) != ERROR_SUCCESS) {
log_error(res);
return 1;
}
+#endif
return 0;
}