tracy Documentation

C++ gamedev & gamedev-library repository by @wolfpld. Desktop release binaries & installers with 17k stars.

RAW Doc

Technical Documentation: wolfpld/tracy

โ„น๏ธ Provenance: Multi-Tier Ingestion ยท CodeWiki Reference

Overview (`README.md`)

A real time, nanosecond resolution, remote telemetry, hybrid frame and sampling profiler for games and other applications.

Tracy supports profiling CPU (Direct support is provided for C, C++, Lua, Python and Fortran integration. At the same time, third-party bindings to many other languages exist on the internet, such as Rust, Zig, C#, OCaml, Odin, etc.), GPU (All major graphics/compute APIs: OpenGL, Vulkan, Direct3D 11/12, Metal, OpenCL, CUDA, WebGPU.), memory allocations, locks, context switches, automatically attribute screenshots to captured frames, and much more.

An Introduction to Tracy Profiler in C++ - Marcos Slomp - CppCon 2023

Introduction to Tracy Profiler v0.2
New features in Tracy Profiler v0.3
New features in Tracy Profiler v0.4
New features in Tracy Profiler v0.5
New features in Tracy Profiler v0.6
New features in Tracy Profiler v0.7
New features in Tracy Profiler v0.8


Overview (`tests/cuda/repro/graph/README.md`)

Tracy CUDA Graph GPU Zone Repro

Demonstrates that unpatched Tracy fails to show GPU zones for kernels
launched via CUDA Graphs (cudaGraphLaunch).

Root cause

When kernels are launched through CUDA Graphs, CUPTI delivers
CONCURRENT_KERNEL and MEMCPY activity records but no corresponding
API callback fires for the individual kernel launches. Tracy's
matchActivityToAPICall() always fails, and matchError() silently
drops every GPU zone.

Build and run

bash
cmake -S . -B ./build
cmake --build ./build --parallel --config Release
ctest --test-dir ./build -C Release -R repro

What to expect

Tracy version GPU zones shown
Unpatched 0
Patched (cuda-graph-gpu-zones.patch) ~30 (10 launches x 3 ops)

The graph structure

Each graph launch contains:

  1. vector_add kernel (c = a + b)
  2. Device-to-device memcpy
  3. vector_add kernel (c = a + c)

The graph is launched 10 times, so 30 GPU operations total.


Overview (`tests/cuda/repro/on_demand/README.md`)

Tracy CUDA On-Demand Profiling Repro

Demonstrates that unpatched Tracy crashes when a profiler connects to a
CUDA application built with TRACY_ON_DEMAND.

Root cause

CUDACtx's constructor (TracyCUDA.hpp) writes a GpuNewContext queue
item but does not call DeferItem(), unlike every other GPU backend
(Vulkan, OpenGL, D3D11/12, Metal, WebGPU, Rocprof), which all defer it
under #ifdef TRACY_ON_DEMAND.

Under on-demand mode, a new connection clears the client's pending
serial queue (ClearQueues()) before replaying deferred items. Since
GpuNewContext is never deferred, it never survives that clear โ€” no
matter how early the connection happens, even immediately after the
context is created. The GpuContextName message that Name() sends
right after (already correctly deferred) is then replayed to a server
that has no record of the context, triggering:

text
Assertion `ctx' failed in Worker::ProcessGpuContextName

In release builds (assert compiled out) this is undefined behavior โ€”
a null-pointer dereference, typically a segfault.

This is the same bug already fixed for the Rocprof backend in #1336;
see also the closed issue #1171, which describes this exact crash.

Build and run

bash
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
./build/repro &
tracy-capture -o repro.tracy -s 5

The reproducer is also registered as a ctest target:

bash
ctest --test-dir build -R repro

Verifying the GPU zones

check_gpu_zones loads a .tracy file and prints, for each GPU
context, whether it is named and how many GPU zones it recorded. It
links the Tracy server library, so it is built only on request:

bash
cmake -B build -DBUILD_CHECK_TOOL=ON
cmake --build build --target check_gpu_zones
./build/check_gpu_zones repro.tracy
# Expected (patched): "GPU context 0: line_scan_processing_cuda, 200 zones"

Exit codes: 0 = at least one named context with recorded zones, 2 =
otherwise.

What to expect

Tracy version Result
Unpatched tracy-capture crashes: Assertion 'ctx' failed
Patched Capture succeeds, GPU context named and populated with zones

Overview (`tests/rocprof/repro/on_demand/README.md`)

Rocprofiler On-Demand Profiling Repro

Demonstrates that unpatched Tracy crashes when a profiler connects to a
HIP application built with TRACY_ON_DEMAND and TRACY_ROCPROF.

Root cause

Three bugs in TracyRocprof.cpp break on-demand profiling:

  1. GpuNewContext not deferred. gpu_context_allocate() writes a
    GpuNewContext queue item but does not call DeferItem(). When a
    Tracy client connects late, the context creation message is never
    replayed. The server then receives GpuZoneBegin events for a
    context it has never seen, triggering:

    text
    Assertion `ctx' failed in ProcessGpuZoneBeginImplCommon
  2. GpuContextName not deferred. Same function writes the context
    name ("rocprofv3") without calling DeferItem(). Even after fixing
    bug 1, a late-connecting client sees the GPU context but it appears
    unnamed in the profiler. Use check_gpu_ctx_name to verify.

  3. Kernel symbols dropped before init. The data->init guard at the
    top of tool_callback_tracing_callback() blocks all callbacks before
    the GPU context is allocated. Kernel symbol registrations
    (CODE_OBJECT_DEVICE_KERNEL_SYMBOL_REGISTER) happen at HIP init
    time โ€” before data->init is true โ€” so they are silently dropped.
    Even if the crash is worked around, kernel names would be missing.

Prerequisites

  • AMD GPU with working ROCm driver
  • librocprofiler-sdk.so available (typically at /opt/rocm/lib/)
  • /opt/rocm/bin/hipcc

Build and run

bash
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
./build/repro &
tracy-capture -o repro.tracy -s 5

If ROCm is not under /opt/rocm, pass -DROCM_PATH=/path/to/rocm.

The reproducer is also registered as a ctest target:

bash
ctest --test-dir build -R repro

Verifying the context name

check_gpu_ctx_name loads a .tracy file and prints the GPU context
names. It links the Tracy server library, so it is built only on request:

bash
cmake -B build -DBUILD_CHECK_TOOL=ON
cmake --build build --target check_gpu_ctx_name
./build/check_gpu_ctx_name repro.tracy
# Expected (patched):   "GPU context 0: rocprofv3"
# Expected (unpatched): "GPU context 0: (unnamed)"

Exit codes: 0 = all contexts named, 2 = unnamed context found.

What to expect

Tracy version Result
Unpatched tracy-capture crashes: Assertion 'ctx' failed
Patched (GpuNewContext only) Capture succeeds but GPU context is unnamed
Fully patched Capture succeeds with ~50 GPU zones and context named "rocprofv3"

--- METRICS ---