Commit Graph
1044 Commits
Author SHA1 Message Date
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 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 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 42fc8d8d8f Add getter for section category name. 2026-07-14 19:12:59 +02:00
Bartosz Taudul a8d5f12f16 Properly process section categories.
Section selection UI disabled for now.
2026-07-14 19:12:59 +02:00
Bartosz Taudul aacc82df3d Hook up server-side no-op section setup. 2026-07-14 19:12:59 +02:00
Bartosz Taudul 50c3c89c16 Rename parents / baseParents maps to wasExecuting / wasExecutingBase.
The current "parents" mode of operation is "was this symbol executing".
The new name for the maps reflects that.

There should also be "was this symbol reached" (both recursive and non-
reentrant) modes.
2026-07-12 16:38:42 +02:00
Bartosz Taudul 60ce6fb25e Rename parent call stacks to synthetic call stacks. 2026-07-12 16:30:16 +02:00
Bartosz Taudul 9ec0535e03 Extract parent frame interning function. 2026-07-12 16:19:08 +02:00
Bartosz Taudul 81ccf5149a Increase code legibility. 2026-07-12 16:02:28 +02:00
Bartosz Taudul 4cd6c38932 Include exclusive sample count in inclusive sample count. 2026-06-27 16:44:26 +02:00
Bartosz Taudul 331881ca36 Fix counting of "with children" sample counts in recursive cases. 2026-06-27 15:00:42 +02:00
Bartosz Taudul 3a6a23ca98 Save and load sections data. 2026-06-21 00:56:32 +02:00
Bartosz Taudul 1706ac57ac Separate id field is not needed. 2026-06-19 20:37:49 +02:00
Bartosz Taudul 274e453bb6 Process section enter / leave events. 2026-06-17 22:37:31 +02:00
Bartosz Taudul 801a34ea66 Add trigger parameter. 2026-06-17 22:37:31 +02:00
Bartosz Taudul 0cdb6d365e Initial section enter / leave instrumentation. 2026-06-17 22:37:31 +02:00
Bartosz Taudul 62560a6429 Add 8-bit length string transfers to the protocol. 2026-06-15 20:43:55 +02:00
Bartosz Taudul f0f579172b Force inline fast check. 2026-05-17 16:06:56 +02:00
Bartosz Taudul 4c6157d249 Remember last retrieved external check result. 2026-05-17 15:43:26 +02:00
Bartosz Taudul 6ae6fb741e Check if image is external once, before checking subframe filenames.
Cache is shared between image names and source file names, because the
underlying StringIdx storage makes indices unique. Both name sets should
be completely separate, but if you have conflicts here, you have much
more pressing problems to solve.
2026-05-17 15:30:03 +02:00
Bartosz Taudul 4ab7ef301e Split IsFrameExternalImpl into image + filename parts. 2026-05-17 15:30:03 +02:00
Bartosz Taudul 41f1172774 Change order of IsFrameExternal checks.
Check image first, then perform the expensive filename check.
2026-05-17 14:30:45 +02:00
Bartosz Taudul 4e0259148f Change IsFrameExternal interface to work with external cache.
Locks are dominating the execution time, making the global cache non-viable.
2026-05-14 22:29:51 +02:00
Bartosz Taudul 0dfd7fb20b Cache IsFrameExternal() queries. 2026-05-14 19:51:41 +02:00
Bartosz Taudul 744bd21423 Change IsFrameExternal() interface to operate on StringIdx, move to Worker. 2026-05-14 19:01:04 +02:00
Bartosz Taudul f7ab78893c Don't query inline-symbol frames as native addresses.
Frames whose symbol data is shipped inline with the callstack payload
(sel=1, e.g. Lua-side stack entries) were being passed to
GetCanonicalPointer() in the AddCallstackAllocPayload() query loop,
tripping its sel==0 assertion. They have no native pointer to query
and were already registered in callstackFrameMap earlier in the same
function, so just skip them.

Regression from c704f909, which hoisted the per-call-site dedup into
QueryCallstackFrame(). Three of the four updated call sites were
equivalent before and after, because the old guard and the new one
keyed on the same value. The fourth, this one, was not: the old guard
tested the frame as-is and matched the entry inserted a few lines above,
short-circuiting before GetCanonicalPointer() ran. The new guard keys on
PackPointer(addr), so GetCanonicalPointer() must run first to compute
addr, and the assert fires.
2026-05-09 12:13:45 +02:00
Bartosz Taudul 305382453d Add callstack sample events with 32 and 16 bit timestamps. 2026-05-07 02:16:53 +02:00
Bartosz Taudul ccaef5ba0b ZoneBegin / ZoneBeginCallstack with 32 and 16 bit time data. 2026-05-07 02:16:53 +02:00
Bartosz Taudul 4d094c108d Add zone end messages with 32 and 16 byte time deltas.
Change in test application:
    compressed data: 130 Mpbps -> 105 Mbps
    uncompressed: 830 Mbps -> 740 Mbps
2026-05-06 19:09:19 +02:00
Bartosz Taudul d6e77b3f40 Remove server query fast path.
The profiler will typically want to send bursts of queries (e.g. 3 queries
to retrieve source location strings, or multiple queries to get all the call
stack frames, etc.).

Each of these queries will be sent immediately, if available space in the
network buffer permits. Each of these sends is a separate syscall.

Remove this and instead batch all queries with the already existing network
buffer overflow handling functionality.
2026-05-06 00:42:24 +02:00
Bartosz Taudul e300d56f68 Force resort of possibly broken plots. 2026-03-27 20:16:27 +01:00
Bartosz Taudul d0222ef7d9 Worker::GetZoneEnd() can be const. 2026-03-19 19:53:58 +01:00
Bartosz Taudul 9442517f30 Remove trailing whitespace. 2026-03-02 19:40:41 +01:00
Bartosz Taudul 2b201e6f59 RetrieveThread() uses a cache that cannot be shared between threads.
Note: IsThreadFiber() uses the same functionality, but is only called from
the main thread.
2026-02-01 18:01:39 +01:00
Bartosz Taudul 73694c7a24 Cleanup enums. 2026-01-24 01:50:11 +01:00
Clément Grégoire 5ef64841cc Remove MessageMetadata type and replace by uint8_t everywhere 2025-12-28 15:04:18 +01:00
Clément Grégoire 1e61dc88de Add source and severity to the server's MessageData + bump minor version for serialization
Note this does not change `sizeof(MessageData)` as there were 5 bytes left due to alignment. (now 3)
2025-12-28 14:50:38 +01:00
Clément Grégoire f981330f66 Replace all messages text addr by TaggedUserlandAddress and send metadata over the network
There are two changes to the protocol:

- `QueueMessageLiteral*` were changed and what used to be addresses are now addresses+metadata
- Other messages now send `QueueMessage*Metadata` with added metadata.

This will later be used to store and transmit message sources, level, etc.
2025-12-28 14:44:40 +01:00
Trevor L. McDonell d1b0406801 Add option to ignore memory free faults
This replaces the IsApple flag, which was previously only used for this purpose.
2025-12-02 16:16:50 +01:00
Clément Grégoire 255f465a8f Fix uninitialized Worker::m_pending* loaded traces.
This was causing issues in the Infos -> Trace Statistics window as `GetCallstackFrameCount` uses `m_pendingCallstackFrames`. Just in case, init those all those variables where declared instead of constructor.
2025-10-08 07:47:51 +02:00
Antoine Mura 80126ed1e0 Add lock struct with condition variable to main thread 2025-07-27 11:05:45 +02:00
Bartosz Taudul 3c1c444a15 Unbreak loading traces from previous versions. 2025-07-22 20:18:55 +02:00
Bartosz Taudul c03fdaec1e Merge pull request #1097 from erieaton-amd/rocprofv3-2
Collect dispatches and counter values with Rocprofv3
2025-07-22 13:33:15 +02:00
Eric Eaton 1639598d62 Update documentation
This provides some instructions and tips for the manual. Also:
* Made the calibration feature a CMake option
* Cleaned up some minor code issues
* Fixed an issue with the calibration
* Incremented patch number
2025-07-21 15:30:42 -07:00
Bartosz TaudulandMarcos Slomp 2f17e33851 Prevent duplicate callstack frame queries.
Callstack frames will now have nullptr as the value in the callstackFrameMap
map, as a way to signal that a query for given key is already pending.
Duplicate queries should no longer happen.

@slomp provided alternative implementation, which produced the following
results:

Queries made: 195,778
Duplicate queries skipped: 9,518,910

Co-authored-by: Marcos Slomp <slomp@adobe.com>
2025-07-18 01:16:46 +02:00
Bartosz Taudul c704f909be Move duplication check into QueryCallstackFrame() to make things clear. 2025-07-18 01:15:16 +02:00
Bartosz Taudul c4a6cf3456 Use contains() to check if map contains element. 2025-07-18 00:45:26 +02:00