Commit Graph

10743 Commits

Author SHA1 Message Date
Bartosz Taudul
46c70fcbb8 Do not mark sorted vectors as unsorted on equal elements.
SortedVector considered an appended element equal to the last one to
break the ordering, marking the vector as unsorted. A non-decreasing
sequence is sorted, so only a strictly smaller element has to trigger
the marker. Equal keys are common: child sample vectors receive
identical timestamps whenever a recursive call stack contains the same
call site twice, which flipped the vectors to unsorted on virtually
every recursive workload and caused the lazy sort in GetChildSamples to
run over and over again while holding the data lock.

The lazy sort machinery handles duplicate keys correctly, as both the
prefix and tail merge windows are computed with lower bounds.
2026-07-25 23:02:13 +02:00
Bartosz Taudul
97d6b5f9fa Guard sampling percentage denominators against underflow.
The denominator subtracts context switch sample counts from total
sample counts, both for the whole trace and within the range filter.
The subtraction could underflow: on traces with inconsistent sample
ordering the binary searches over the unsorted sample vectors can
return too few samples, and a sample which arrives with a duplicated
timestamp is merged into the existing entry while its context switch
classification is still recorded, so the context switch samples are not
a strict subset of the samples. An underflow made every percentage in
the table display as zero.

Clamp the subtraction, per thread in range mode, so that one thread
with bad data does not affect the counts of the others.
2026-07-25 23:02:13 +02:00
Bartosz Taudul
b68fe43335 Keep context switch sample vectors sorted.
Context switch samples were appended in arrival order. Samples which
were postponed due to missing context switch data are replayed after
newer samples were already classified, so the vector could become
unordered. Everything that reads it assumes time order: the wait stacks
range filter, the sampling statistics percentage denominator, and the
context switch sample filters in the trace load jobs. In the load jobs
an unordered vector could silently disable the filtering for the rest
of a thread, reintroducing the context switch samples into the symbol
and child sample maps.

Use a SortedVector and restore the ordering at the points where it can
break: after the postponed sample replay and when saving a trace. The
save file version is bumped, so that the sort order check on load is
only performed for traces saved by previous versions.
2026-07-25 23:02:13 +02:00
Bartosz Taudul
5563461201 Extend the symbol parents LLM tool with the reached modes.
The tool only reported "was executing" entry stacks, while the sample
entry stacks window now defaults to showing the stacks through which a
symbol was reached. The model was told there is no data for symbols
which never executed directly, even when the window right next to it
displayed their entry stacks.

Add an optional "mode" parameter with the "reached" (non-reentrant),
"reached_recursive" and "executing" values. The default matches the UI
default. Inline symbols are now accepted, as the reached maps cover
them directly, and the executing mode can use their exact statistics.
The reported mode is included in the tool output, and the chat view
shows it in the tool call label.

The tool description keeps the mode summaries short. The detailed
guidance on choosing a mode is in the optimization skill, so it only
occupies context when the skill is loaded.
2026-07-25 23:02:13 +02:00
Bartosz Taudul
851b1f80f1 Take the data lock in LLM tools which access worker state.
LLM tool calls execute on the LLM worker thread, while the render
thread holds the worker data lock for the duration of each frame and
the network thread mutates worker data under the same lock during live
capture. The tools accessed worker data with no synchronization at all.
Some of the accessors also lazily modify worker state, such as the
postponed symbol list sorting or the lazy sorting of child sample
vectors, so this raced even in a fully loaded trace.

Take the data lock in the five tools which access worker state. No LLM
locks are held while tools execute, so no lock ordering cycle with the
render thread is possible. Tools which perform network requests do not
touch worker data and remain lockless, as holding the lock across a
network transfer would stall the profiler.

The background jobs which compute sampling statistics during trace load
do not hold the data lock. The readiness flags are the synchronization
mechanism there, so gate the sampling tools on them. This also matches
the readiness asserts in the worker accessors these tools call.
2026-07-25 23:02:10 +02:00
Bartosz Taudul
507f2ae8b5 Update NEWS. 2026-07-25 19:46:02 +02:00
Bartosz Taudul
941669c1c6 Base sampling statistics percentages on real sample counts.
With an active range filter, the percentage denominator was a
theoretical capacity estimate: the number of samples a single thread
would produce if it ran continuously through the range at the nominal
sampling rate. Actual sample volume scales with total CPU occupancy
across all threads, so the estimate was off in either direction: on
multi-core workloads percentages were inflated several times over and
could exceed 100%, while on mostly idle workloads they were deflated.
Toggling the range filter also silently changed what the percentages
meant, as the whole-trace mode divides by the collected sample count.

Count the samples actually present in the range instead, and exclude
context switch samples from both denominators, as they cannot be
attributed to any displayed symbol. Percentages now mean the same thing
with and without a range filter: the share of attributable samples.

Time percentages are intentionally unchanged. They are normalized by
wall clock time in both modes, where exceeding 100% legitimately means
more than one core was busy.
2026-07-25 19:46:01 +02:00
Bartosz Taudul
c880163f96 Sort child sample vectors lazily.
During live capture, child samples were appended to their per-address
vectors in arrival order. Samples postponed due to missing context
switch data are replayed after newer samples were already processed, so
the vectors could become unordered. All range-limited queries binary
search these vectors by time and would silently return wrong results.
Inserting in sorted order at collection time would require a mid-vector
insertion for every stack frame of every replayed sample, so instead
the vectors are now SortedVector and are sorted lazily when accessed,
following what the inline symbol list already does. This also restores
proper query results for traces with inconsistent sample order.
2026-07-25 19:46:01 +02:00
Bartosz Taudul
3293e263c6 Exclude context switch samples from symbol and child sample maps.
Context switch samples are excluded from sampling statistics, as they
are not produced by the statistical profiling timer and their stacks
are always parked at the scheduler. During live capture this exclusion
is structural, as such samples never enter the statistics processing
path. On trace load, however, only the job which computes symbol
statistics and the instruction pointer map filtered them out. The job
which builds the per-symbol sample lists and the child sample map did
not, so on a loaded trace these two structures included tens of
thousands of context switch samples that a live session would not
count.

This made range-limited statistics counts exceed the whole-trace
counts, inflated child sample costs in the symbol view, and caused the
same trace to show different numbers live and after a save and reload.
On the test trace, __schedule reported 56 exclusive samples but 32747
entries in its sample list.

Apply the same context switch sample filter when building the symbol
samples and child samples maps.
2026-07-25 19:46:01 +02:00
Bartosz Taudul
6063e22bc7 Fix inclusive counts of symbols with inlined functions.
When inline functions are aggregated into their base symbols in the
sampling statistics, the inclusive counts were summed up, the same as
the exclusive counts. This is wrong. Exclusive counts partition the
samples, as each sample is attributed to exactly one symbol. Inclusive
counts overlap: an inline function can only ever be on the stack within
a frame group whose base is its parent symbol, so every sample counted
for an inline function is also counted for the base symbol. Summing
therefore counted the same sample multiple times, inflating the counts,
the sort order and the displayed percentages, in the worst observed
case by a factor of 7.

The base symbol's own inclusive count is exactly the correct value for
the aggregated entry, so use it directly.
2026-07-25 19:46:01 +02:00
Bartosz Taudul
8711f87cb5 Disable entry stacks menu item when there is no data to show.
The statistics window can display rows for which the sample entry
stacks window cannot show anything: symbols with no symbol data,
symbols that only have range-mode sample counts without callstack
statistics, or any row while the statistics are still being computed
in the background. Grey out the menu item in such cases, following
what the "View symbol" item already does.
2026-07-25 19:46:01 +02:00
Bartosz Taudul
34587e6b4c Only show entry stacks button in symbol view when data is available.
The button was displayed unconditionally, allowing the sample entry
stacks window to be opened for symbols without any sample data. Gate it
on the availability of callstack sample statistics and a non-empty
reached map, following what the call stack window does. Checking for
statistics readiness also prevents asserting when the button is used
while a trace is still being loaded in the background.
2026-07-25 19:46:01 +02:00
Bartosz Taudul
d5760a05ae Do not crash on missing symbol data in sample entry stacks window.
The window can be opened for a symbol which has no symbol stats or no
symbol data. For example, the statistics window can produce clickable
rows for symbols that are not present in the symbol map. Close the
window instead of dereferencing null pointers.
2026-07-25 19:46:01 +02:00
Bartosz Taudul
bacfbccb97 Use reached stats for entry stacks access in assembly view.
The instruction tooltip advertised the number of "was executing" entry
call stacks, but middle-clicking opens the sample entry stacks window,
which now defaults to the "was reached" mode. Count the non-reentrant
reached stacks instead, so the tooltip matches what the window shows.

Gating on the reached map also makes entry stacks accessible for
symbols which only ever appear deeper in the call stack. This can
happen when inspecting instructions whose cost consists purely of
child samples.
2026-07-25 19:45:58 +02:00
Bartosz Taudul
2e9e0e2643 Update NEWS. 2026-07-25 17:33:00 +02:00
Bartosz Taudul
fc26cc0f79 Update manual. 2026-07-25 17:30:32 +02:00
Bartosz Taudul
849bc3ae8c Allow entry stacks for symbols that were only reached. 2026-07-25 17:28:07 +02:00
Bartosz Taudul
67ae7d849f Add "was reached" modes to sample entry stacks window. 2026-07-25 17:25:17 +02:00
Bartosz Taudul
1dfcacd802 Collect entry stacks for "was this symbol reached" statistics.
SymbolStats now has two additional entry stack maps, which record the
call stacks below every occurrence of a symbol in a sample, not only
when the symbol was at the top of the stack:

- wasReached counts each occurrence separately. If a symbol re-enters
  itself through recursion, every re-entry adds an entry stack, which
  will itself contain the symbol somewhere below.
- wasReachedNonReentrant counts only the outermost occurrence, so each
  sample contributes exactly once and recursion is ignored. The sum of
  counts in this map equals the symbol's inclusive sample count.

To achieve this, the call stack is walked bottom-up, which makes the
first encountered occurrence of a symbol the outermost one. Symbols at
inline positions get the remaining inline frames of their frame group
as a synthetic frame, mirroring what was already done for the top of
the stack.

The wasExecuting and wasExecutingBase maps are now filled by the same
walk, as its topmost-frame special case. The keys they receive are
identical to what the previous code produced.

Note that there is no "base" variant of the reached maps. A base symbol
is present as the last frame of every frame group that contains its
inline functions, so its wasReached map already covers the whole symbol
at base granularity. Merging in the inline symbols' maps, as done for
wasExecutingBase, would only multi-count the same samples.
2026-07-25 17:02:42 +02:00
Bartosz Taudul
2e23c112bd Extract synthetic call stack interning into a helper. 2026-07-25 16:57:57 +02:00
Bartosz Taudul
d74d77226c Guard against empty synthetic call stacks in parents frame trees.
A sample with a single-frame call stack already produces a zero-length parent
stack, and GetParentsCallstackFrameTree{BottomUp,TopDown} call cs.back() /
cs.front() on it, resulting in UB.
2026-07-25 16:43:43 +02:00
Bartosz Taudul
8f52e0e5f5 Enable clipboard on macOS. 2026-07-25 14:34:24 +02:00
Bartosz Taudul
9db60de03b Do not embed default ImGui font. 2026-07-25 14:30:13 +02:00
Bartosz Taudul
e53c2849fa Bump ImGui to 1.92.9-docking. 2026-07-25 14:29:12 +02:00
Bartosz Taudul
7c30fedaaa Rebuild markdown manual. 2026-07-25 00:19:47 +02:00
Bartosz Taudul
9314b8cbce Update manual. 2026-07-25 00:17:42 +02:00
Bartosz Taudul
ff3e31f564 Update desktop file. 2026-07-24 23:14:09 +02:00
Bartosz Taudul
ac159d6127 Fix RUNPATH in tracy-profiler AppImage
patchelf the stripped binary to /../lib, collapsing the RUNPATH
to the single intended entry. The wayland .pc files baked an absolute
build-host path and a trailing empty component into RUNPATH; the former
leaks the build environment and could shadow bundled libs on the target,
the latter can cause cwd library searches on older glibc.

Add patchelf to the appimage workflow's apt install list.
2026-07-24 20:34:10 +02:00
Bartosz Taudul
bcddc1d9f1 Cache wayland checkout. 2026-07-24 20:34:08 +02:00
Bartosz Taudul
d231c2e95f Correct way to link with wayland libraries. 2026-07-24 18:25:05 +02:00
Bartosz Taudul
b94a1e22c1 Update git ignore list. 2026-07-24 18:25:05 +02:00
Bartosz Taudul
cf82fb9bb0 Disable unused stuff if building libcurl. 2026-07-24 18:25:05 +02:00
Bartosz Taudul
f30d32a908 Add AppImage build script and workflow. 2026-07-24 18:25:05 +02:00
Bartosz Taudul
b7eda34332 Add a warning about minimum supported wayland-client version. 2026-07-24 18:11:42 +02:00
Bartosz Taudul
5036ec9128 Merge pull request #1434 from damcclos/damcclos/thread-lock-time
Add function to calculate thread lock wait time in TracyTimelineItemThread
2026-07-23 22:14:46 +02:00
David McCloskey
59a8ae2d7d Adding documentation 2026-07-23 14:38:56 -05:00
David McCloskey
ea3d0b4d8d Add function to calculate thread lock wait time in TracyTimelineItemThread
This update introduces a new function, GetThreadLockWaitTime, which computes the total wait time for locks held by a specific thread. The function aggregates wait times across all locks and updates the tooltip to display lock wait time and count, enhancing the profiling capabilities of the timeline item.
2026-07-23 14:21:54 -05:00
Bartosz Taudul
917c4baffb GLFW from brew should no longer be needed on macOS. 2026-07-23 21:11:07 +02:00
Bartosz Taudul
faab64018a Update NEWS. 2026-07-23 21:03:07 +02:00
Bartosz Taudul
fb296ba1a4 Update manual. 2026-07-23 21:03:06 +02:00
Bartosz Taudul
877efe4eda Track current personality and warn when the selected one is not active. 2026-07-23 20:34:59 +02:00
Bartosz Taudul
90c6ad80e1 Clamp personality index to personality table size. 2026-07-23 20:29:26 +02:00
Bartosz Taudul
67c4102bf3 Restore disabling fast model selection during replies. 2026-07-23 20:26:41 +02:00
Bartosz Taudul
c1fa33a875 Link with system libcurl to avoid libssh deps. 2026-07-23 15:43:59 +02:00
Bartosz Taudul
1d6f43d92f Disable external libraries used by freetype.
Not needed for the current set of fonts.
2026-07-23 15:30:39 +02:00
Bartosz Taudul
c2b489a0ff Do not link macOS bundle with homebrew libraries.
Do not want dependency on something being installed via brew.
2026-07-23 14:57:45 +02:00
Bartosz Taudul
7986dc18d0 Add yalter's guadec presentation to list of videos. 2026-07-23 01:53:54 +02:00
Bartosz Taudul
f9413c268d Bump usearch to 2.26.0. 2026-07-22 22:35:42 +02:00
Bartosz Taudul
6e23d220d7 Bump capstone to 6.0.0-Alpha10. 2026-07-22 22:33:29 +02:00
Bartosz Taudul
158ab87bee Rebuild markdown manual. 2026-07-22 22:04:04 +02:00