A thread exiting between fopen and read leaves the comm and status
buffers under-filled or uninitialized: zero-initialize them, treat a
short or empty read as unknown, and never scan the status when the read
returned nothing.
A task directory yielding no numeric entries (the target exiting
mid-enumeration) returned 0 with the freshly allocated array still
handed back through *out, and the caller's failure path returned without
freeing it.
SysTraceStart only failed when no event of any kind opened, but in
external mode the global sched/vsync tracepoints (pid -1) succeed
independently of the target: a target exiting after thread enumeration
left every per-target open failing while the startup still reported
success. s_ctxBufferIdx is the per-target ring count right after the
per-target setup, so in external mode require it to be non-zero as well.
The previous external shape - one per-task (cpu = -1) inherit event per
existing thread - cannot be mmap'd at all: perf_mmap() in
kernel/events/core.c refuses inherited per-task counters (-EINVAL, all
children would write the same ring), so no sample ring was ever created.
A per-CPU event filtered on the target's tgid (the self-profiling shape)
only covers the group leader; the kernel does not retro-inherit onto
pre-existing sibling threads.
Open one CPU-gated event per ring instead - perf_event_open(attr, pid,
cpu), one open per CPU and per target thread, the same shape as perf's
open loop (tools/perf/util/evsel.c:3031). The thread enumeration picks
the fan-out: at launch, per-CPU events on the target pid, inherited by
every later-spawned thread; on attach, per-thread per-CPU events for
every existing tid. Failing opens degrade gracefully: the affected
thread is simply not sampled.
Add PERF_SAMPLE_IP to the callstack sample: for code compiled without
frame pointers the kernel delivers no user stack, and such samples were
dropped entirely. When the callchain count is zero, synthesize a
one-frame trace holding just the leaf IP.
The seven sampling event setups repeated the same open/mmap/retry
sequence. On a refused open the retry now stays user-space only
(exclude_kernel and exclude_callchain_kernel both still require
perf_allow_kernel), and a failed open no longer breaks out of the whole
event loop.
SysTraceStart previously reported success even when no perf events
could be opened, leaving a worker thread running over no buffers
and an empty CPU section without explanation; it now fails in that
case. Also log when /proc/kallsyms cannot be read, which otherwise
silently results in ??? kernel stack frames.
perf_event_attr.use_clockid only exists since Linux 4.1 and
sample_max_stack since Linux 4.8; older kernels (e.g. the 3.18
kernels of 32-bit Android devices) reject the attributes with
EINVAL/E2BIG, which silently disabled all of system tracing.
Classify the running kernel from uname(2) and only send the fields
its perf_event_open ABI supports.
The function is about to dispatch between rpmalloc and a pluggable allocator hook, so the rpmalloc-specific name no longer fits. Pure rename plus a small consequence: the SymbolWorker call site no longer needs the TRACY_USE_RPMALLOC guard, since the no-op static-inline fallback in TracyAlloc.hpp makes InitAllocator() safe to call unconditionally.
After investigating (downloading and installing) all publicly available SDKs at https://learn.microsoft.com/en-us/windows/apps/windows-sdk/downloads-archive I concluded the `TRACEHANDLE` deprecation started in `10.0.26100`.
This defines `PROCESSTRACE_HANDLE` and `CONTROLTRACE_ID` as done by the SDK when using older versions. Using `WDK_NTDDI_VERSION` (and not `NTDDI_VERSION` which may change based on `_WIN32_WINNT` or user input seems to be the most reliable way to do it. While it says "WDK" it's been part of the SDK in `shared\sdkddkver.h`. Note it doesn't work for MinGW because it updates half of its sdk files for some reason.
Tested with both 10.0.26100 and 10.0.22621.0 which is the last one I found without the new types.
Also changes CONTROLTRACE_ID to ULONG64 on mingw which is correct (type used by `TRACEHANDLE` too in mingw fe2763863a/mingw-w64-headers/include/evntrace.h (L60) )
perf_event_open(pid>0, cpu>=0) binds to a single task, so the previous
setup only sampled the target's main thread. In monitor mode, enumerate
/proc/<pid>/task/ and open one per-task event per existing thread with
cpu=-1; inherit=1 then covers every descendant. Self-profiling behavior
is preserved byte-for-byte: the iter list becomes (currentPid, i) for
each CPU, exactly what the old code did inline.
This is to be consistent with what libtracefs does: 6fad6a14ba/src/tracefs-utils.c (L104)
In theory one may mount tracefs with another name, though unlikely.
This forces to (re)use frequency values as input, which may be changed by the platform code later on. This way we have a single "source of truth" for sample freq.
Also removed the Win32 `GetSamplingInterval` which was a wrapper above `GetSamplingPeriod` but its value would be divided again anyway.
Ideally I think we might want to have TRACY_HW_TIMER mean only TSC/CNTVCT, and define TRACY_TIMER_FALLBACK for platforms that don't have them or have a special case such as iOS.
But for now, keep the same behaviour.