Known gaps
A missing value in a recording has one of these causes, or is a loss counted in Recording health. Read the field’s capture status first.
Not recorded by design
Section titled “Not recorded by design”- Remote process memory. The memory of another process, such as the target of
ptraceorprocess_vm_readvandprocess_vm_writev, is never read. Antinomie records its address and length only (status ADDRESS_ONLY). - Kernel threads. They are not traced, even by Capture all.
- 32-bit and x32 calls. The schema covers the native x86-64 table only. i386 and x32 system calls are not decoded.
- Outputs of failed calls. Output buffers are captured only on success, with a few documented exceptions.
- Pages that are not loaded. The recorder never faults memory in. Since 0.7.1 (with a base built for 0.7.1 or later) an input that was not resident at the call’s entry is read again when the call returns, tagged at exit, so the largest gap of this kind is closed. Memory a call never reads stays NOT_RESIDENT.
Cannot be decoded
Section titled “Cannot be decoded”- Driver-specific
URING_CMD. Anio_uringcommand to a driver has a private layout. It is recorded as a gap with no decoder; its address is 0, never the kernel’s address. SocketURING_CMDoperations forsetsockoptandgetsockoptare decoded. - Unknown selectors and options. A
setsockopt,getsockopt,prctl,ptrace,keyctlor similar call with a selector the recorder does not know is recorded as raw bytes (for socket options up to 128 KiB) with a “no decoder” gap. - Some nested layouts. A few structures keep their top-level bytes only and name the nested pointer that was not followed, such as netfilter table replacements and multicast source lists.
- Kernel-managed deferred pointers. Values the kernel reads or writes much
later, such as a thread’s
clear_child_tidat exit or the robust futex list traversal, are marked not observed asynchronously.
Limits of async capture
Section titled “Limits of async capture”- Asynchronous payload capture is limited to contexts where the program’s memory can be read safely; see Async observations.
- More than 256 requests in flight, or more than 1,024 records waiting, are refused and counted as loss.
- AIO reap observations depend on a 64-entry table per boot.
- Vectored AIO reads that complete in an interrupt are captured when the program reaps them, up to 1,024 vector entries per request. A read whose reap entry was dropped keeps its gap and counts as loss.
- Triage does not read io_uring requests that touch no file, or
TEE. See Async observations. - The file identity of an io_uring rename, link or unlink is looked up just before the operation, so a name changed in between is identified as it was at the lookup.
Kernel records
Section titled “Kernel records”These need a base built for Antinomie 0.7.0 or later; see Records beside the system calls.
- Hashes have limits. A file over 16 MiB, on a filesystem other than ext4, tmpfs or ramfs, or queued when 16 jobs or 64 MiB are already waiting is not hashed; the record says why. A digest is the file’s bytes when the kernel read it, shortly after the call.
- Written files. A file written through an io_uring worker, or closed by a process outside the run, is not hashed. A file opened for writing and not written is hashed at its last close all the same.
- The launched program of a desktop run is the shell wrapper that starts it, so its hash is the wrapper’s.
- User names. Triage names a user from the
/etc/passwdof the base the VM’s disk came from, plus the account the app created. A user created in the guest after the base was built has no name and stays a number. - Shared file mappings (revision 18, a base built for 0.8.0). The pages of a
MAP_SHAREDmapping are seen when a call writes them back or drops them, each as it was at that moment, not every store before it. Not seen: a page the kernel’s background writeback cleaned while the mapping stayed and that was not stored to again, and mappings of the kernel’s internal files (shared anonymous memory, System V shared memory, memfd). Pages past the 4 MiB copy budget per call are listed as not captured, with the reason. - Earlier file positions. Without revision 18, a write at an
O_APPENDposition or through a descriptor another process shares is at an unknown offset, and in-kernel copies change a file without its bytes. - A run split across reconnects. Triage reads every recording segment of the run only while they are in the same recording folder as its newest one.
About process cores and memory
Section titled “About process cores and memory”- A process core stores at most its budget: 64 MiB to 1 GiB, and no more than the guest accepts (half its RAM less 128 MiB). A base made before 0.7.0 accepts 64 MiB only. Untouched memory is kept as holes and costs nothing. A core is not an atomic snapshot of the process; see Memory and core dumps.
- A memory dump is not decoded by Antinomie itself; Volatility 3 or MemNixFS does that.
What an absence means
Section titled “What an absence means”A missing call can come from loss, an unavailable capture or an unsupported construct. Absence alone does not prove that an action never happened.