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.
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.
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.
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.
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.
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.
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.
`pip install mcp` now installs 2.x by default (v1 is
maintenance-only going forward), and nothing in this repo pinned a
version, so a fresh install already broke: v2 removed
mcp.server.fastmcp entirely, no compat shim.
- Import/class: mcp.server.fastmcp.FastMCP ->
mcp.server.mcpserver.MCPServer.
- Transport options (host, port, sse_path, streamable_http_path)
moved off the constructor and the settings object onto run();
mutating mcp_server.settings.port now raises ValueError.
- _http_ping and the startup message read _SSE_PATH/
_STREAMABLE_HTTP_PATH constants instead of settings.sse_path/
settings.streamable_http_path -- v2 no longer exposes them to
read back. Values match the SDK's own defaults in both versions
("/sse", "/mcp"), so served paths are unchanged.
- Adds extra/mcp/requirements.txt (mcp>=2.0.0,<3) -- there was no
dependency manifest at all before this.
Decorator API is unchanged; every tool/resource here was already
async def, so the "sync handlers now run on worker threads" change
doesn't apply.
Verified in an isolated venv (mcp 2.0.0): module imports cleanly
with all 10 tools and 2 resources registered, the server starts
and serves streamable-http on the expected path, and _http_ping
correctly reports a running instance as alive.
The CMake option only controlled whether NFD is built and linked, but
the file selector code is guarded by the TRACY_NO_FILESELECTOR macro,
which the build never defined - configuring with -DNO_FILESELECTOR=ON
failed to compile (nfd.h not found in TracyFileselector.cpp,
BackendWayland.cpp and BackendGlfw.cpp). Define the macro for the
profiler target when the option is set.
When the native dialog failed, the popup said "File selector cannot
be displayed. Check nfd library implementation for details." but never
showed any details: NFD_GetError() was never read, so the actual
failure reason (e.g. the xdg-desktop-portal lacking a FileChooser
implementation on the session) was invisible and the user was stuck
without a way to open or save traces.
Capture NFD_GetError() into a static string when
NFD_OpenDialogU8_With()/NFD_SaveDialogU8_With() return NFD_ERROR and
display it in the popup. The copy is required: the returned pointer
references NFD-internal storage (the D-Bus error message or a static
buffer) that is overwritten by the next NFD call or cleared on
shutdown. In TRACY_NO_FILESELECTOR builds no NFD exists, so the
previous fallback line is kept there.
The error is shown as a single line (TextUnformatted) rather than
wrapped: in an AlwaysAutoResize window the wrap width is derived from
the previous frame's window size, which feeds back into the auto-size
and oscillates, converging to a narrow multi-line column for a ~110
character D-Bus message.
When a child group was expanded, the member rows were not visibly
indented under the group name: each row starts at the tree indent
(column 0 is IndentEnable by default, and TableBeginRow() latches the
open group's TreePush indent), so a single Indent() put the label two
IndentSpacing from the cell origin. The group header, however, leads
with the source location color box plus item spacing before its tree
arrow, so its name starts four IndentSpacing further right than the
member labels - the child list read as a continuation of the header
row instead of a subtree.
Add a second Indent() (and the balancing Unindent()) so the member
labels land clearly to the right of the group name. The full-row
Selectable behavior is unchanged. GPU zones are unaffected: their
rows carry no color box, so the member labels were already one level
right of the group name.
The imgui 1.92.9b ini writer omits 'Column N' lines for columns without
saved data (e.g. the unsized, unsorted 'Zone' column of the child zones
table, which only persists the default Time sort). On restore, the
missing entry keeps Index == -1, the sequential fallback in
TableLoadSettingsForColumns() assigns it to the remaining column, and
TableFixDisplayOrder() sorts DisplayOrder -1 to the end - flipping the
column order (Time | Zone in the zone info child list) for the session.
Guard the non-reorderable load path against phantom entries.
Upstream: https://github.com/ocornut/imgui/issues/9519
The group name-sort key was always the source location name, but
single-member groups display the zone-level name, which prefers the
runtime ZoneName() string. Such groups sorted by a name the user could
not see. The key now mirrors the display: zone name for single-member
groups, source location name for the rest. GPU zones are unaffected
(their names always resolve from the source location).
The child zone list was always sorted by time. It is now a sortable
table with Zone and Time columns, like the statistics view and the
time distribution table in the same window: Time is the default sort
(descending, as before), Zone sorts by name with time as the
tiebreak, and groups plus their members follow the same selection.
The sort choice persists across zones and the group toggle. Group
and child names are looked up once per draw only when name-sorting.
Otherwise on unmap you can get the validation layer error:
"ID3D12Resource3::ID3D12Resource::Unmap: pWrittenRange does not point to an empty D3D12_RANGE and
the heap type is D3D12_HEAP_TYPE_READBACK. Readback resources can be written by the CPU but there's
not much utility. The rationale is that readback heaps are stuck in COPY_DEST state such that the
GPU can never use what the CPU is writing. The range [0, 524288) should be empty (Begin >= End)."
Check also https://learn.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12resource-unmap
"This indicates the region the CPU might have modified" -> tracy essentially declares the entire range as written, but it's not even a cpu->gpu write buffer -> bug.
TracyConfig.cmake now sets TRACY_VERSION_STRING and a
TracyConfigVersion.cmake is generated and installed, so
find_package(Tracy X.Y CONFIG) works against installed trees.
Compatibility mode is SameMinorVersion: for a 0.x project the minor
version is the compatibility unit, and consumers who need to pin the
exact version can use find_package(... EXACT). SamePatchVersion is
not an option - it requires CMake 4.4 while the project minimum is
3.13.
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.