Commit Graph

10953 Commits

Author SHA1 Message Date
Bartosz Taudul
fdff78584a Raise the fd limit for the sample events.
External sampling opens one event per CPU for each existing thread
(attach) or per CPU (launch) per event type, so a multithreaded target
needs many fds.
2026-08-31 01:12:41 +02:00
Bartosz Taudul
893439772f Reject client configurations that cannot work.
TRACY_NO_CALLSTACK, TRACY_NO_SYSTEM_TRACING, TRACY_NO_SAMPLING and
TRACY_SAMPLING_PROFILER_MANUAL_START either fail to build (the external
target API lives in the callstack code) or silently produce an empty
capture (no sampling event fails, so IsSystemTracingFailed stays false).
The first three are #error'd at compile time; the TRACY_NO_SYS_TRACE /
TRACY_NO_SAMPLING environment variables are refused at startup.
2026-08-31 01:12:41 +02:00
Bartosz Taudul
6d794801c6 Verify the exec stop in launch mode.
A caught signal (the handlers are inherited by the child) delivered
between PTRACE_TRACEME and exec first produces a signal-delivery stop;
without handling it, the setup would run on the still pre-exec child and
capture the monitor's own image as the target's. Re-inject the caught
signal and wait again until the exec stop is reached. Job-control stops
are the exception - re-injecting SIGSTOP/SIGTSTP re-stops the child, and
PTRACE_CONT rejects a stop carrying the 0x80 job-control bit - so resume
those without a signal instead.
2026-08-31 01:12:41 +02:00
Bartosz Taudul
b36c8f2fc5 Refuse to start without tracefs.
The client's system tracing cannot start without a tracefs (or debugfs)
mount - the tracepoint ids live under it - so starting anyway would
capture no samples.
2026-08-31 01:12:41 +02:00
Bartosz Taudul
2f2d8a7ba9 Fail when system tracing fails to start.
IsSystemTracingFailed reports a SysTraceStart that the preflight could
not predict (the target exiting between the checks, the kernel rejecting
the event setup); starting anyway would capture no samples.
2026-08-31 01:12:41 +02:00
Bartosz Taudul
d498829518 Verify the client is listening after startup.
Polling IsDataPortListening is the only reliable check: probing the port
itself cannot distinguish the client's listener from another process
holding it.
2026-08-31 01:12:40 +02:00
Bartosz Taudul
e87b7c873e Reserve the client listen port.
When TRACY_PORT is not pinned the client probes 8086..8105 at startup.
Reserve the first free port up front and hand the already-bound socket
to the client via SetReservedListenSocket, so the reservation is atomic
and the reported port matches what the client listens on. A pinned
TRACY_PORT is validated like --port, since the client pins to any
nonzero value with no fallback.
2026-08-31 01:12:40 +02:00
Bartosz Taudul
6109ab27b5 Add sample rate and port options. 2026-08-31 01:12:40 +02:00
Bartosz Taudul
7357b9fa52 Attach by process name.
The name is matched against /proc/<pid>/comm, which the kernel truncates
to 15 characters. Several matches are listed so the user can pick one
with -p; a match is only accepted if /proc/<pid>/exe is readable, which
excludes zombies (they keep a comm but have no executable to map) and
inaccessible processes.
2026-08-31 01:12:40 +02:00
Bartosz Taudul
46f2489f92 Report the active data sources at startup. 2026-08-31 01:12:40 +02:00
Bartosz Taudul
ac970771ee Preflight the exact sample event.
The old preflight opened one generic event, which said little about
whether the client's actual setup would work. PreflightSamplingEvent now
opens the client's exact external event shape (the per-CPU pid-filtered
CPU_CLOCK callstack event of SysTraceStart), verifies the ring mmap
works, and probes the hardware PMU counters informationally. On
EACCES/EPERM retry user-space only - both event and callchain, since the
callchain part still requires perf_allow_kernel - and report kernel
frames as unavailable; any other error is fatal, as the client's
identical shape would fail the same way.
2026-08-31 01:12:40 +02:00
Bartosz Taudul
d87cbed7eb Probe system-wide tracepoints and RAPL. 2026-08-31 01:12:40 +02:00
Bartosz Taudul
252a3dae43 Treat zombie targets as dead.
kill(pid, 0) succeeds for zombies, so a SIGKILLed attach target whose
parent had not reaped it yet kept the monitor polling indefinitely - in
attach mode the monitor cannot reap it. Liveness now also reads the
/proc state and treats Z as dead.
2026-08-31 01:12:40 +02:00
Bartosz Taudul
c9d3ec0088 Harden external thread name lookups against dead threads.
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.
2026-08-31 01:12:39 +02:00
Bartosz Taudul
e5d20e1377 Free the tid buffer when thread enumeration yields 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.
2026-08-31 01:12:39 +02:00
Bartosz Taudul
da0d2328f5 Require per-target events for external sampling success.
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.
2026-08-31 01:12:39 +02:00
Bartosz Taudul
8db1a298c4 Open external sampling as CPU-gated per-CPU events.
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.
2026-08-31 01:12:39 +02:00
Bartosz Taudul
37410933db Always deliver the sample IP.
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.
2026-08-31 01:12:39 +02:00
Bartosz Taudul
afe1ec5faf Factor the sample event open into OpenSampleEvent.
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.
2026-08-31 01:12:39 +02:00
Bartosz Taudul
d440f5e055 Report whether the data port is listening. 2026-08-31 01:12:39 +02:00
Bartosz Taudul
ae70255b4e Adopt a pre-bound listen socket. 2026-08-31 01:12:39 +02:00
Bartosz Taudul
b887def929 Record and expose system tracing startup failure. 2026-08-31 01:12:38 +02:00
Bartosz Taudul
7aee673792 Use the target executable time for external captures.
The worker must key source and symbol transfers on the target's
executable, not the monitor's own binary; the exe mtime was read
straight from /proc/<pid>/exe by InitExternalTarget (the readlink'd path
is namespace-dependent and carries a " (deleted)" suffix). For an
external target the time may be unavailable, so drop the assert on a
nonzero exectime.
2026-08-31 01:12:38 +02:00
Bartosz Taudul
81f3c71ef3 Transfer machine code for external targets.
For an external target the symbol code query addresses are VMAs in the
target's address space, not pointers in the monitor's, so read them out
with ReadExternalTargetMemory. Kernel code (the top bit marks it) is
shared by the monitor and its target alike, so the kernel path applies
in both modes.
2026-08-31 01:12:38 +02:00
Bartosz Taudul
d8a011630d Add an API to read external target memory.
ReadExternalTargetMemory reads bytes out of the target's address space:
process_vm_readv for live bytes (gated like ptrace access), falling back
to the target's on-disk image located by scanning /proc/<pid>/maps
directly - the caller runs while the symbol thread may be rebuilding the
shared image cache on refresh.
2026-08-31 01:12:38 +02:00
Bartosz Taudul
1f1d3ab856 Resolve external callstacks to the full inline chain.
The resolver previously captured only the first pcinfo result, so inline
frames were lost, and reported ELF virtual addresses the server could
never re-map to the target. Mirror the in-process pcinfo+syminfo flow,
and report symAddr as the target VMA (loadBias + ELF vaddr) so the
server's re-queries can resolve it.
2026-08-31 01:12:38 +02:00
Bartosz Taudul
2e566513dd Create external backtrace states from openable paths only.
backtrace_create_state_for_file opens the file lazily on first use and,
on a failed open, silently falls back to /proc/self/exe - so a state
created from a path the monitor cannot open would symbolize the target's
addresses against the monitor's own binary. Probe the target's root path
(and, for unlinked images, the mapping's map_files entry), and only
create a state for a path that actually opens.
2026-08-31 01:12:38 +02:00
Bartosz Taudul
2a40f6f990 Converge the external image list on refresh.
The list only ever added entries, so a mapping the target re-mapped or
unloaded stayed in the list and could shadow the new mapping or keep
serving an already-unloaded library. Rebuild it from the target's
current maps on each refresh, carrying over the cached backtrace state
for unchanged mappings and dropping entries the current maps no longer
confirm. The dropped entries' paths are abandoned rather than freed:
queued callstack items still carry the path pointer, which the worker
thread reads at its own pace. Strip the kernel's " (deleted)" suffix so
unlinked images converge to their canonical path.
2026-08-31 01:12:38 +02:00
Bartosz Taudul
0e7040d73b Derive the external load base from the mapping's own segment.
The minVaddr heuristic assumes the mapping's file offset is measured
against the lowest PT_LOAD vaddr of the image. The kernel maps each
PT_LOAD independently, at load_bias + ELF_PAGESTART(p_vaddr) from
p_offset - ELF_PAGEOFFSET(p_vaddr) (fs/binfmt_elf.c, elf_map), so the
assumption only holds for the segment carrying the minimum vaddr. Match
the mapping to its PT_LOAD through the exact offset relation the kernel
used, and take the base from that segment's own vaddr; the minVaddr
heuristic remains as the fallback. The header must be ELF64
(e_ident[4]): the fixed-size elf_ehdr/elf_phdr structs misparse other
classes, and a false segment match on misparsed headers would return a
silently wrong base.
2026-08-31 01:12:38 +02:00
Bartosz Taudul
bd1d783017 Resolve external images through the target mount namespace.
The image paths from /proc/<pid>/maps are only valid in the target's
mount namespace, so resolve them through /proc/<pid>/root (proc(5)). For
unlinked images the kernel keeps the bytes alive in the mapping's
map_files entry, which is opened directly instead.
2026-08-31 01:12:38 +02:00
Bartosz Taudul
d352907e5d Drop the magic monitor globals. 2026-08-31 01:12:37 +02:00
Bartosz Taudul
4e520cfc18 Add the external target API. 2026-08-31 01:12:34 +02:00
Bartosz Taudul
ac9ea9dde7 Stop fetching vendor dependencies for the monitor build. 2026-08-30 21:25:08 +02:00
Bartosz Taudul
38b19d2be6 Constrain the monitor build to Linux x86_64 and aarch64. 2026-08-30 21:25:07 +02:00
Bartosz Taudul
601d57de35 Copy the filename in backtrace_create_state_for_file.
The state opens the file lazily on first use (fileline_initialize), so
it must own the filename: the caller's buffer may be freed as soon as
this returns. Pass a copy into backtrace_create_state.
2026-08-30 21:25:05 +02:00
Bartosz Taudul
8b41c38ed9 Merge pull request #1464 from jorisv/topic/fix-git-ref-windows
Fix GitRef.hpp generation on Windows
2026-08-28 11:52:15 +02:00
Joris Vaillant
d6ef0f0fa4 Fix GitRef.hpp generation on Windows 2026-08-28 10:50:48 +02:00
Bartosz Taudul
031ef02614 Use MSVC for the meson build in windows CI. 2026-08-27 18:51:53 +02:00
Bartosz Taudul
0f65035ef3 Link ws2_32, dbghelp and secur32 for MinGW in meson. 2026-08-27 18:43:10 +02:00
Bartosz Taudul
253b68dcb6 Notify after queue can be done out of the lock. 2026-08-27 17:23:20 +02:00
Bartosz Taudul
32aa7ee1f5 Derive meson version via python3, not sh. 2026-08-27 17:23:20 +02:00
Bartosz Taudul
5ed42cfc6d Add meson build to windows CI. 2026-08-27 17:23:18 +02:00
Bartosz Taudul
f207007548 Merge pull request #1460 from ofoure/master
Fixed buffer overflow after using VkCtx cmdbuf ctor.
2026-08-25 17:52:29 +02:00
Olivier Fouré
94e58d4e24 Fixed buffer overflow after using VkCtx cmdbuf ctor. 2026-08-25 14:40:54 +02:00
Bartosz Taudul
30997d5ca6 Release 0.14.1. v0.14.1 2026-08-22 19:06:43 +02:00
Bartosz Taudul
aa53e377e7 Use xdg-foreign v2 protocol for Wayland file dialog parent window. 2026-08-22 18:31:26 +02:00
Bartosz Taudul
cae9bf0bef Decrease rate of event production in test application. 2026-08-22 14:31:58 +02:00
Bartosz Taudul
4d3a84a97e Refine GUI verify skill name and description. 2026-08-22 13:07:05 +02:00
Bartosz Taudul
10926caed4 Add tooltip stating statistics limit also affects source view. 2026-08-22 12:57:34 +02:00
Bartosz Taudul
073152a10a Support time range limit entries tooltips. 2026-08-22 12:57:34 +02:00