Skip to lesson
Game Hacking Academy
Preparing lesson text…
Exit reader mode
Voice and speed

Preparing read-aloud controls…

Lesson 5.10 Listening edition

Event Tracing for Windows

Understand how ETW records time-stamped events around a running game and how to read a short performance trace.

About 28 minutes

Section: Observation without a breakpoint.

A debugger stops or single-steps a thread. That is perfect when you need the exact instruction and registers, but stopping changes timing. A game may stutter, a network timeout may expire, or another thread may continue while the selected thread is paused.

Event Tracing for Windows, shortened to E T W, Event Tracing for Windows,, records structured events with much less disturbance. Windows and applications can report process, thread, image-load, C P U, central processing unit,-sampling, disk, networking, and other activity. The exact events depend on which providers and keywords a trace enables.

E T W is for questions such as:

Which thread used most of the C P U during a slow frame?

Which DLLs loaded while the game started?

Did a long pause line up with disk activity?

Was work happening on one thread or many?

E T W does not tell you the meaning of an arbitrary gold field. Use the tool that matches the question.

E T W is a producer–buffer–consumer system. Providers describe events, a session controls which streams are active, and consumers turn the ordered records into a model:

Lesson diagram

Buffers separate fast event production from slower analysis, but they are finite. A trace can lose records when production outruns collection, so “missing from this capture” does not automatically mean “never happened.”

A full session buffer cannot take the fourth record.

Section: Four roles make one trace.

The names sound formal, but the jobs are simple:

A provider creates events. Windows, a driver, or an application can be a provider.

A session receives selected events into buffers and possibly an .etl file.

A controller starts and stops the session and selects providers.

A consumer reads the events live or from the saved file.

Windows Performance Recorder, or WPR, is a controller. Windows Performance Analyzer, or WPA, is a graphical consumer.

Alternative: Think of a recording chain: providers produce observations, a controller starts the session, buffers carry events, and a consumer interprets the saved result.

Code example. The surrounding prose explains this example; the full lesson contains the exact code.

An event normally includes a timestamp, provider identity, event identity, process/thread context, and provider-defined fields. A keyword is a bitmask used to select groups of related events from a provider.

Section: Keep the lab short and isolated.

A general performance profile can include activity from the whole machine, not just the game. That may reveal filenames, process names, or timing from unrelated applications.

Use a clean disposable Windows V M, virtual machine,, close unrelated programs, record only long enough to reproduce the game action, and do not publish the .etl file without reviewing it. The course helper refuses to overwrite an existing trace.

Section: Keep the controller narrow.

The helper launches wpr.exe directly with std::process::Command. It does not build a command string for PowerShell or cmd.exe, so the output path is passed as one argument rather than interpreted as shell code.

Lesson diagram

Additional detail: Complete lab source: etw_capture.rs.

Code example. The surrounding prose explains this example; the full lesson contains the exact code.

Section: Why the cleanup path matters.

Starting a trace creates system state that outlives the first wpr.exe process. If reading from the terminal fails or stopping the session fails, the helper asks WPR to cancel.

Narration: Closing the helper does not necessarily stop the recording it started. Error paths therefore need to cancel the remaining session.

The original helper starts WPR, waits for Enter, then stops the recording. If the terminal read fails? returns early and the recording session remains active. run_wpr is the command wrapper from the complete helper above.

Before: return early without cancelling a trace

Code example. The surrounding prose explains this example; the full lesson contains the exact code.

Handle that early-return boundary explicitly and request best-effort cleanup before returning the original input error. The same cleanup request is made if stopping fails. Cancellation itself can fail, so the returned error says that it was requested rather than claiming it succeeded.

Improved code

Code example. The surrounding prose explains this example; the full lesson contains the exact code.

Show the diff

Code example. The surrounding prose explains this example; the full lesson contains the exact code.

Takeaway: every operation that starts persistent state needs a cleanup path for later failures.

Section: Why this version?.

An error should not leave a forgotten recorder running. Cleanup is part of correctness, just like restoring a breakpoint byte or closing a process handle.

The ignored result on -cancel is deliberate: the original error remains the most useful explanation, and cancellation is a best-effort recovery after something already went wrong.

Section: Record one repeatable action.

Build the helper:

Terminal window

Code example. The surrounding prose explains this example; the full lesson contains the exact code.

In a clean V M, start the capture from an administrator terminal if WPR requests it:

Terminal window

Code example. The surrounding prose explains this example; the full lesson contains the exact code.

Then:

start Wesnoth 1.14.9;

load a small local scenario;

end exactly one turn;

return to the terminal and press Enter;

open wesnoth-turn.etl in WPA.

Use the same short procedure for AssaultCube startup or one Urban Terror map load. Repeatability makes two traces comparable.

Section: Read the result in layers.

Start with broad questions before zooming into thousands of events:

In Process Lifetimes, confirm the expected executable and P I D, process identifier.

In C P U Usage (Sampled), filter to that process and find busy threads.

In Image Load, inspect DLLs loaded during startup.

In Disk Usage, look for long file reads that overlap a pause.

In the timeline, select only the few seconds around your action.

Lesson diagram

A stack may show system DLLs, game functions, or unresolved addresses. Symbols translate addresses into names. Without matching symbols, the timing is still real, but the function label may remain a module plus offset.

Section: Missing events are data too.

E T W writes through buffers. If a provider produces events faster than the session can deliver them, events can be lost. A controller can report buffer and event-loss statistics.

Lesson diagram

That means “I did not see an event” is weaker than “the event could not have happened.” Check whether the chosen profile included the relevant provider and whether the session lost data.

In brief: Absence from a trace is meaningful only after checking what was recorded and whether any events were lost.

Section: Keep tracing separate from evasion.

This chapter starts, stops, and consumes an ordinary diagnostic session. It does not disable providers, patch tracing APIs, alter another process’s telemetry, or hide module loads. Those actions would corrupt the very trace this lab is trying to read.

The complete helper is etw_capture.rs.

We now have three distinct observations: the scanner locates candidate data, the debugger pauses at exact instructions, and E T W summarizes timed system activity. The optional next lesson asks how to scan several captured regions without letting concurrency change the result. Chapter 6 then uses verified sites while building a small library inside an explicitly supported game process.

References: Microsoft: About Event Tracing, Windows Performance Recorder, and Windows Performance Analyzer.