XRef
Available in v0.3.0 · not in v0.2.0 · Linux x86-64

Live Analysis: from a running process to the code that writes its memory.

One stripped program, examined from outside while it runs: a value we know, where it sits in memory, which static function owns it, how often that code runs and who calls it, which instruction writes the field, and the same field after its buffer moves. Every command below ran exactly as shown, and the output under it is what that run printed.

v0.3.0 xref live and the opt-in xref_live MCP tool are available starting with v0.3.0. Earlier published v0.2.0 binaries do not contain them. Linux x86-64 only.
  1. Start a stripped program and give it some state
  2. Confirm the process and the binary
  3. Find the structure in memory
  4. Translate the two pointers to static addresses
  5. Find the code that stores that string
  6. Read the deposit handler as pseudo-C
  7. Read the function stored in the structure
  8. Count calls and see who makes them
  9. Catch the instruction that writes a field
  10. Find a growable buffer
  11. Follow the buffer after it moves
Provenance.
  • xref: xref 0.2.0 built from main at d2085bb (release), sha256 7517fac97d742d8c82b574c10a36e941589029c44ad6127d6867f7d95d67d394
  • Toolchain: rustc 1.97.1 (8bab26f4f 2026-07-14)
  • Host: development Linux 5.15.0-191-generic x86_64 host, recorded 2026-11-03T19:03:16Z
  • Fixture: rustc --edition=2021 -O -C strip=symbols -o vault-daemon tests/fixtures/live_daemon_app.rs; source sha256 febf7570f2130801942216a8ec216c32dffe0f806f64b35431cc6157e891fdc3; binary sha256 83375cf10e8a3ef314c77146fe4dd8e5ea44793197d47168782e554edf132909
  • Run: daemon PID 2927467. PIDs and runtime addresses belong to this run; ASLR changes them on every start.
  • Output: stdout and stderr are copied unchanged except that spaces at line ends are trimmed; scripts/live_walkthrough/transcript.json keeps the raw capture.
Privileges. maps, resolve and memscan read /proc/<pid>/maps and /proc/<pid>/mem, so they need ptrace access to the target (same user; under Yama ptrace_scope=1 the target must allow it, which the fixture does with prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY)). probe and watch open perf events on another process and need privileged perf access (root, or capabilities and kernel.perf_event_paranoid settings that allow it). In this recording only those two commands ran with sudo -n, only against the fixture; host settings were not changed.
Reproduce from a checkout of main on Linux x86-64:
cargo build --release
python3 scripts/live_walkthrough/record.py --commit "$(git rev-parse --short HEAD)" --out /tmp/live-walkthrough.json
python3 scripts/live_walkthrough/render.py /tmp/live-walkthrough.json

1. Start a stripped program and give it some state

unprivileged

The target is our own fixture, tests/fixtures/live_daemon_app.rs, built with -C strip=symbols: no symbols, no debug info. It keeps a vault structure on the heap and changes it when it reads commands such as DEPOSIT, ROTATE and VEC_MOVE_WRITE0 on stdin. We act as if we knew only one thing about it: the 16-byte signature DAEMONV2 + 0x778899aabbccddee that it keeps at the start of the vault.

DAEMON SESSION
$ ./vault-daemon
DAEMON_READY pid=2927467
> DEPOSIT 777 500000
ACK op=DEPOSIT seq=1

2. Confirm the process and the binary

unprivileged

xref live maps reads /proc/<pid>/maps and smaps, checks that the file passed with -b is the executable that is running, and computes the PIE slide that links runtime addresses to static ones.

$./xref -b vault-daemon live maps --pid 2927467
RECORDED STDOUTexit 0
pid 2927467  starttime 342472486  match verified_build_id  pie_slide +0x5581807ca000  alive true  changed false
0x5581807ca000..0x5581807e3000  r--p  off 0x00000000  skipped_non_writable        target  /tmp/xref-walkthrough/vault-daemon
0x5581807e3000..0x55818082f000  r-xp  off 0x00018000  skipped_non_writable        target  /tmp/xref-walkthrough/vault-daemon
0x55818082f000..0x558180833000  r--p  off 0x00063000  skipped_non_writable        target  /tmp/xref-walkthrough/vault-daemon
0x558180833000..0x558180835000  rw-p  off 0x00066000  scannable_rwp               target  /tmp/xref-walkthrough/vault-daemon
0x55819217d000..0x55819219e000  rw-p  off 0x00000000  scannable_rwp               -       [heap]
0x7f7565bb0000..0x7f7565bb3000  rw-p  off 0x00000000  scannable_rwp               -       [anon]
0x7f7565bb3000..0x7f7565bdb000  r--p  off 0x00000000  skipped_non_writable        -       /usr/lib/x86_64-linux-gnu/libc.so.6
0x7f7565bdb000..0x7f7565d70000  r-xp  off 0x00028000  skipped_non_writable        -       /usr/lib/x86_64-linux-gnu/libc.so.6
0x7f7565d70000..0x7f7565dc8000  r--p  off 0x001bd000  skipped_non_writable        -       /usr/lib/x86_64-linux-gnu/libc.so.6
0x7f7565dc8000..0x7f7565dc9000  ---p  off 0x00215000  skipped_non_writable        -       /usr/lib/x86_64-linux-gnu/libc.so.6
0x7f7565dc9000..0x7f7565dcd000  r--p  off 0x00215000  skipped_non_writable        -       /usr/lib/x86_64-linux-gnu/libc.so.6
0x7f7565dcd000..0x7f7565dcf000  rw-p  off 0x00219000  skipped_unclassified_file   -       /usr/lib/x86_64-linux-gnu/libc.so.6
0x7f7565dcf000..0x7f7565ddc000  rw-p  off 0x00000000  scannable_rwp               -       [anon]
0x7f7565ddc000..0x7f7565ddf000  r--p  off 0x00000000  skipped_non_writable        -       /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
0x7f7565ddf000..0x7f7565df6000  r-xp  off 0x00003000  skipped_non_writable        -       /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
0x7f7565df6000..0x7f7565dfa000  r--p  off 0x0001a000  skipped_non_writable        -       /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
0x7f7565dfa000..0x7f7565dfb000  r--p  off 0x0001d000  skipped_non_writable        -       /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
0x7f7565dfb000..0x7f7565dfc000  rw-p  off 0x0001e000  skipped_unclassified_file   -       /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
0x7f7565e04000..0x7f7565e05000  ---p  off 0x00000000  skipped_non_writable        -       [anon]
0x7f7565e05000..0x7f7565e09000  rw-p  off 0x00000000  scannable_rwp               -       [anon]
0x7f7565e09000..0x7f7565e0b000  r--p  off 0x00000000  skipped_non_writable        -       /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7f7565e0b000..0x7f7565e35000  r-xp  off 0x00002000  skipped_non_writable        -       /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7f7565e35000..0x7f7565e40000  r--p  off 0x0002c000  skipped_non_writable        -       /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7f7565e41000..0x7f7565e43000  r--p  off 0x00037000  skipped_non_writable        -       /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7f7565e43000..0x7f7565e45000  rw-p  off 0x00039000  skipped_unclassified_file   -       /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7ffe75365000..0x7ffe75386000  rw-p  off 0x00000000  scannable_rwp               -       [stack]
0x7ffe753c0000..0x7ffe753c4000  r--p  off 0x00000000  skipped_device_or_special   -       [vvar]
0x7ffe753c4000..0x7ffe753c6000  r-xp  off 0x00000000  skipped_device_or_special   -       [vdso]
0xffffffffff600000..0xffffffffff601000  --xp  off 0x00000000  skipped_device_or_special   -       [vsyscall]
29 regions (6 scannable_rwp)

3. Find the structure in memory

unprivileged

xref live memscan searches the scannable regions for the two signature words and prints a window of 8-byte words around each hit. Every word is classified against the static image: code pointer, pointer to a string, heap pointer, vtable candidate or plain number.

$./xref -b vault-daemon live memscan --pid 2927467 --after-words 11 0x4441454d4f4e5632 0x778899aabbccddee
RECORDED STDOUTexit 0
pid 2927467  starttime 342472486  match verified_build_id  pie_slide +0x5581807ca000  alive true  changed false
needle 0x32564e4f4d454144eeddccbbaa998877  align 8  elapsed 0ms  regions 6/29  bytes 0x58000  unreadable 0  stop complete  hits 2
hit 0x558180834250  /tmp/xref-walkthrough/vault-daemon+0x1250
   -0x10  0x0000558180834240  0x000055818081ea70  code_ptr             fn 0x54a70+0x0  -
    -0x8  0x0000558180834248  0x0000000000000000  scalar
     0x0* 0x0000558180834250  0x4441454d4f4e5632  scalar
    +0x8* 0x0000558180834258  0x778899aabbccddee  scalar
   +0x10  0x0000558180834260  0x0000000000000001  scalar
   +0x18  0x0000558180834268  0x0000000000000309  scalar
   +0x20  0x0000558180834270  0x000000000007a120  scalar
   +0x28  0x0000558180834278  0x13579caa196801ee  scalar
   +0x30  0x0000558180834280  0x0000000000000000  scalar
   +0x38  0x0000558180834288  0x0000000000000000  scalar
   +0x40  0x0000558180834290  0x0000000000000000  scalar
   +0x48  0x0000558180834298  0x0000000000000000  scalar
   +0x50  0x00005581808342a0  0x0000000000000000  scalar
   +0x58  0x00005581808342a8  0x0000000000000000  scalar
   +0x60  0x00005581808342b0  0x0000000000000000  scalar
hit 0x55819217dda0  [heap]+0xda0
   -0x10  0x000055819217dd90  0x0000000000000000  scalar
    -0x8  0x000055819217dd98  0x0000000000000071  scalar
     0x0* 0x000055819217dda0  0x4441454d4f4e5632  scalar
    +0x8* 0x000055819217dda8  0x778899aabbccddee  scalar
   +0x10  0x000055819217ddb0  0x0000000000000001  scalar
   +0x18  0x000055819217ddb8  0x0000000000000309  scalar
   +0x20  0x000055819217ddc0  0x000000000007a120  scalar
   +0x28  0x000055819217ddc8  0x13579caa196801ee  scalar
   +0x30  0x000055819217ddd0  0x0000000000420042  scalar
   +0x38  0x000055819217ddd8  0x00005581807e99d0  code_ptr             fn 0x1f9d0+0x0  -
   +0x40  0x000055819217dde0  0x00005581807d44ef  static_data_ptr      "XREF_DAEMON_VAULT_ACTIVE_V2"
   +0x48  0x000055819217dde8  0x000055819217dd80  heap_ptr             [heap]+0xd80
   +0x50  0x000055819217ddf0  0x000055818082fb08  relro_ptr_candidate  candidates [0x1f800, 0x21630]
   +0x58  0x000055819217ddf8  0xe9992ca71d7036cd  scalar
   +0x60  0x000055819217de00  0x00005581807d55b7  static_data_ptr      "DAEMON_OP_DEPOSIT_V2ERR invalid DEPOSIT args"

4. Translate the two pointers to static addresses

unprivileged

xref live resolve turns runtime addresses into static addresses and file offsets of the verified binary. The static addresses are what every static xref command takes.

$./xref -b vault-daemon live resolve --pid 2927467 0x00005581807e99d0 0x00005581807d55b7
RECORDED STDOUTexit 0
pid 2927467  starttime 342472486  match verified_build_id  pie_slide +0x5581807ca000  alive true  changed false
0x5581807e99d0  runtime_to_static  static 0x1f9d0  runtime 0x5581807e99d0  file 0x1e9d0  sym -  /tmp/xref-walkthrough/vault-daemon+0x69d0
0x5581807d55b7  runtime_to_static  static 0xb5b7  runtime 0x5581807d55b7  file 0xb5b7  sym -  /tmp/xref-walkthrough/vault-daemon+0xb5b7

5. Find the code that stores that string

unprivileged

Static analysis of the same stripped file: which instructions reference the string address?

$./xref -b vault-daemon refs 0xb5b7
RECORDED STDOUTexit 0
0x1fa0e  in 0x1f9f0  lea rax, [0xb5b7]
1 hits
STDERR
xref: load 221.9µs, total 2.5ms

6. Read the deposit handler as pseudo-C

unprivileged

xref c decompiles the function directly from machine code.

$./xref -b vault-daemon c 0x1f9f0
RECORDED STDOUTexit 0
/*
 * fn_1f9f0 — 0x1f9f0..0x1faea (250 bytes, 1 direct caller; synthetic FDE entry)
 *   params:
 *     arg_0 (rdi): void * — writes +0x0 (8B), +0x8 (8B), +0x10 (8B), +0x18 (8B)
 *     arg_1 (rsi): unk64 — 64-bit register (signedness unconstrained)
 *     arg_2 (rdx): unk64 — 64-bit register (signedness unconstrained)
 *   return: unk64 in rax (consumed by 1/1 direct call site)
 */
unk64 fn_1f9f0(void *arg_0, unk64 arg_1, unk64 arg_2) {
  unk64 slot_0; /* [rsp+0x0], addr-taken */
  unk64 slot_8; /* [rsp+0x8] */
  unk64 slot_10; /* [rsp+0x10] */

  slot_8 = arg_2;
  slot_10 = arg_1;
  slot_0 = 0xb5b7;
  *(u64 *)(arg_0 + 96) = slot_0;
  slot_0 = 0x4441454d4f4e5632;
  unk64 v_1 = slot_0;
  *(u64 *)(arg_0) = v_1;
  slot_0 = 0x778899aabbccddee;
  unk64 v_2 = slot_0;
  *(u64 *)(arg_0 + 8) = v_2;
  unk64 v_3 = *(u64 *)(arg_0 + 48);
  unk64 v_4 = (*(u64 *)(arg_0 + 16) + 1);
  *(u64 *)(arg_0 + 16) = v_4;
  *(u64 *)(arg_0 + 24) = arg_1;
  unk64 v_5 = (*(u64 *)(arg_0 + 32) + arg_2);
  *(u64 *)(arg_0 + 32) = v_5;
  unk64 v_6 = *(u64 *)(arg_0 + 56)(v_5, v_3, arg_1);
  unk64 v_7 = v_6;
  *(u64 *)(arg_0 + 40) = v_6;
  unk64 v_20 = *(u64 *)(*(u64 *)(arg_0 + 80) + 24)(*(u64 *)(arg_0 + 72), v_4, v_7);
  *(u64 *)(arg_0 + 88) = v_20;
  unk64 v_8 = slot_10;
  fn_21650(v_8, slot_8, v_4);
  /* xchg [0x6a250], r14 */
  /* xchg [0x6a258], rbx */
  /* xchg [0x6a260], rax */
  /* xchg [0x6a268], r15 */
  /* xchg [0x6a270], r13 */
  /* xchg [0x6a278], rbp */
  return v_4;
}
STDERR
xref: load 270.4µs, total 3.2ms

7. Read the function stored in the structure

unprivileged

The code_ptr from offset +0x38 points to 0x1f9d0.

$./xref -b vault-daemon c 0x1f9d0
RECORDED STDOUTexit 0
/*
 * fn_1f9d0 — 0x1f9d0..0x1f9e8 (24 bytes, 0 direct callers; synthetic FDE entry)
 *   params:
 *     arg_0 (rdi): unk64 — 64-bit register (signedness unconstrained)
 *     arg_1 (rsi): usize — count/index (scaled by 201527)
 *   return: unk64 in rax
 */
unk64 fn_1f9d0(unk64 arg_0, usize arg_1) {
  return ((arg_1 * 0x31337) + (0x13579bdf2468ace0 ^ arg_0));
}
STDERR
xref: load 234.3µs, total 2.3ms

8. Count calls and see who makes them

recorded with sudo -n · fixture only

xref live probe places Linux uprobes on the two static addresses, only for this process (perf backend). While it is armed we send three commands to the daemon: a deposit, a key rotation and another deposit.

$sudo -n ./xref -b vault-daemon live probe --pid 2927467 --callers --regs --duration-ms 1500 0x1f9f0 0x1f9d0
SENT TO THE DAEMON WHILE THE OBSERVER WAS ARMED
> DEPOSIT 777 250000
ACK op=DEPOSIT seq=2
> ROTATE 0x99
ACK op=ROTATE seq=3
> DEPOSIT 777 125000
ACK op=DEPOSIT seq=4
RECORDED STDOUTexit 0
pid 2927467  starttime 342472486  match verified_build_id  pie_slide +0x5581807ca000  alive true  changed false
backend perf  pid_isolated_bp true  elapsed 1500ms/1500ms  stop duration_elapsed  seeded_tids 1  dyn_tids 0  excluded_tgid 0  lost 0
probe static 0x1f9f0  runtime 0x5581807e99f0  file 0x1e9f0  insn push    cfi entry_rsp+8_ra-8    fn 0x1f9f0 (-)  hits 2
  caller ra 0x5581807ea0ea (static 0x200ea)  fn 0x1fd50  call_site 0x200e5  verified true  hits 2  [unwind_evidence_only_tail_call_possible]
  regs tid 2927467  rdi 0x55819217dda0  rsi 0x309  rdx 0x3d090  rcx 0x55819217fe40  r8 0x0  r9 0x55819217fe32  rax 0x1  rsp 0x7ffe753848a8  rbp 0x309  [raw_register_bits_do_not_prove_source_types]
  regs tid 2927467  rdi 0x55819217dda0  rsi 0x309  rdx 0x1e848  rcx 0x55819217fe40  r8 0x0  r9 0x55819217fe32  rax 0x1  rsp 0x7ffe753848a8  rbp 0x309  [raw_register_bits_do_not_prove_source_types]
probe static 0x1f9d0  runtime 0x5581807e99d0  file 0x1e9d0  insn mov     cfi entry_rsp+8_ra-8    fn 0x1f9d0 (-)  hits 1
  caller ra 0x5581807e9a7a (static 0x1fa7a)  fn 0x1f9f0  call_site 0x1fa76  verified true  hits 1  [unwind_evidence_only_tail_call_possible]
  regs tid 2927467  rdi 0xb71b0  rsi 0x420042  rdx 0x3d090  rcx 0x309  r8 0x0  r9 0x55819217fe32  rax 0x7ffe75384860  rsp 0x7ffe75384858  rbp 0x309  [raw_register_bits_do_not_prove_source_types]
STDERR
xref: probe_ready {"backend":"perf","pid":2927467,"attached_tids":[2927467],"probes":["0x1f9f0","0x1f9d0"]}

9. Catch the instruction that writes a field

recorded with sudo -n · fixture only

xref live watch arms an x86 hardware write watchpoint (DR0–DR3) on the runtime address of the field at +0x28, then we make two deposits.

$sudo -n ./xref -b vault-daemon live watch --pid 2927467 --duration-ms 1200 0x000055819217ddc8
SENT TO THE DAEMON WHILE THE OBSERVER WAS ARMED
> DEPOSIT 777 1000
ACK op=DEPOSIT seq=5
> DEPOSIT 777 2000
ACK op=DEPOSIT seq=6
RECORDED STDOUTexit 0
pid 2927467  starttime 342472486  match verified_build_id  pie_slide +0x5581807ca000  alive true  changed false
backend perf_breakpoint  pid_isolated_wp true  elapsed 1200ms/1200ms  stop duration_elapsed  seeded_tids 1  dyn_tids 0  excluded_tgid 0  lost 0
watch runtime 0x55819217ddc8  static -  len 8B  access write  region [heap]+0xdc8 (rw-p)  init 0xfedcba99ddb00a59  latest 0xfedcba99db270a59  hits 2
  writer 0x1fa7d (trap 0x5581807e9a81 / static 0x1fa81)  fn 0x1f9f0 (-)  insn "mov [r15+0x28], rax"  conf candidate_linear_predecessor_store  hits 2  [candidate_linear_predecessor_store_operand_assumes_no_indirect_or_cross_fde_entry]
  sample tid 2927467  writer 0x1fa7d  trap 0x5581807e9a81  value candidate_reg:rax(8B)=0xfedcba99de2d0a59
  sample tid 2927467  writer 0x1fa7d  trap 0x5581807e9a81  value candidate_reg:rax(8B)=0xfedcba99db270a59
STDERR
xref: watch_ready {"backend":"perf_breakpoint","pid":2927467,"attached_tids":[2927467],"watches":["0x55819217ddc8"],"access":"write","len_bytes":8}

10. Find a growable buffer

unprivileged

A second structure has its own signature (XREFTYPE + 0x1122334455667788). It mirrors a Vec<u64>.

$./xref -b vault-daemon live memscan --pid 2927467 --after-words 12 0x5852454654595045 0x1122334455667788
RECORDED STDOUTexit 0
pid 2927467  starttime 342472486  match verified_build_id  pie_slide +0x5581807ca000  alive true  changed false
needle 0x45505954464552588877665544332211  align 8  elapsed 0ms  regions 6/30  bytes 0x58000  unreadable 0  stop complete  hits 1
hit 0x55819217d480  [heap]+0x480
   -0x10  0x000055819217d470  0x00007f7565dca0c0  mapped_ptr           /usr/lib/x86_64-linux-gnu/libc.so.6+0x10c0
    -0x8  0x000055819217d478  0x0000000000000081  scalar
     0x0* 0x000055819217d480  0x5852454654595045  scalar
    +0x8* 0x000055819217d488  0x1122334455667788  scalar
   +0x10  0x000055819217d490  0x0000000000000001  scalar
   +0x18  0x000055819217d498  0x0000000000000309  scalar
   +0x20  0x000055819217d4a0  0x00000000000007d0  scalar
   +0x28  0x000055819217d4a8  0x8000000100000019  scalar
   +0x30  0x000055819217d4b0  0xff011234ffffffff  scalar
   +0x38  0x000055819217d4b8  0xfffffff6389adc00  scalar
   +0x40  0x000055819217d4c0  0x000000003fc00000  scalar
   +0x48  0x000055819217d4c8  0x4009000000000000  scalar
   +0x50  0x000055819217d4d0  0x000055819217fe90  heap_ptr             [heap]+0x2e90
   +0x58  0x000055819217d4d8  0x0000000000000008  scalar
   +0x60  0x000055819217d4e0  0x0000000000000006  scalar
   +0x68  0x000055819217d4e8  0x0000558180833840  static_data_ptr      "XREF"

11. Follow the buffer after it moves

recorded with sudo -n · fixture only

--follow watches the pointer slot and the element it points to. len_slot/min_len and guard_slot/guard_val stop the watch if the length or the signature no longer match. We write element 0, move the buffer to a new allocation, and write element 0 again.

$sudo -n ./xref -b vault-daemon live watch --pid 2927467 --duration-ms 1600 --follow ptr_slot=0x000055819217d4d0,offset=0,len_slot=0x000055819217d4e0,min_len=1,guard_slot=0x000055819217d480,guard_val=0x5852454654595045
SENT TO THE DAEMON WHILE THE OBSERVER WAS ARMED
> VEC_WRITE0 0x1111222233334444
ACK op=VEC_WRITE0 len=6
> VEC_MOVE_WRITE0 0x5555666677778888
ACK op=VEC_MOVE_WRITE0 cap=256
> VEC_WRITE0 0x9999aaaabbbbcccc
ACK op=VEC_WRITE0 len=6
RECORDED STDOUTexit 0
pid 2927467  starttime 342472486  match verified_build_id  pie_slide +0x5581807ca000  alive true  changed false
backend perf_breakpoint  pid_isolated_wp true  elapsed 1600ms/1600ms  stop duration_elapsed  seeded_tids 1  dyn_tids 0  excluded_tgid 0  lost 0 (lower_bound)
follow ptr_slot 0x55819217d4d0+0  state bound  gen 2  leaf 0x55819217fee0  slots 2  root_hits 1  leaf_hits 2
  writer 0x20c41 (trap 0x5581807eac44 / static 0x20c44)  fn 0x1fd50 (-)  insn "mov [rdx], rcx"  conf ambiguous_branch_target  hits 2  [trap_ip_is_intra_function_branch_target_predecessor_not_unique]
  sample tid 2927467  writer 0x20c41  trap 0x5581807eac44  value unknown(ambiguous_branch_target_at_trap_ip)
  sample tid 2927467  writer 0x20c41  trap 0x5581807eac44  value unknown(ambiguous_branch_target_at_trap_ip)
STDERR
xref: watch_ready {"backend":"perf_breakpoint","pid":2927467,"attached_tids":[2927467],"watches":["0x55819217d4d0","0x55819217fe90"],"access":"write","len_bytes":8}

Use it from an agent

xref -b vault-daemon mcp --allow-live-pid <PID> exposes the same operations to an MCP client as the xref_live tool, pinned to that one verified process, next to the static xref_query tool. Without --allow-live-pid the server stays read-only and static. This session is not recorded here; see docs/mcp.md for requests and budgets, and docs/live.md for the full contract and limits.