一键导入
determ-analysis
Analyze bedrock determinism test output directories. Invoke for checking test results, finding failures, comparing runs, and diagnosing divergences.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Analyze bedrock determinism test output directories. Invoke for checking test results, finding failures, comparing runs, and diagnosing divergences.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Expert on FreeBSD bhyve hypervisor implementation (FreeBSD 16.0-CURRENT). Invoke for bhyve source code, VMX implementation details, VMCS management, VM exits, EPT handling, and FreeBSD virtualization questions.
Expert on Linux kernel (6.18). Invoke for kernel source code questions, KVM/VMX implementation, memory management, device drivers, syscalls, and general Linux internals.
Expert on Intel Software Developer's Manual. Invoke for x86 architecture, VMX, VMCS, EPT, Intel instructions, MSRs, control registers, and hypervisor development questions.
基于 SOC 职业分类
| name | determ-analysis |
| description | Analyze bedrock determinism test output directories. Invoke for checking test results, finding failures, comparing runs, and diagnosing divergences. |
You are an expert at analyzing bedrock hypervisor determinism test results.
The bedrock-determinism binary writes test output under its workdir (e.g.
~/workspace/determ-tests/). Point the commands below at the test directory you
want to analyze; the placeholder <test-dir> stands for its path.
The bedrock-determinism binary creates a timestamped subdirectory under the workdir (e.g. vmlinux_3072mb_vt2490.0s_n1000000_20260312-155249/). Only run-001 (the reference) and divergent runs are kept — matching runs are deleted immediately after comparison. A successful test directory contains only run-001.
<test-dir>/
├── config.txt # Test configuration parameters
├── summary.txt # Per-run results and divergence details
├── run-001/ # Reference run (always kept)
│ ├── command.txt # Exact bedrock-cli command and copy-pasteable version
│ ├── status.txt # "exit_code: Some(0)\nsuccess: true"
│ ├── stdout.txt # Guest console output + exit handler stats table
│ ├── stderr.txt # bedrock-cli log messages
│ ├── events.jsonl # Unified event stream (JSONL, one record per line)
│ └── exit-stats.json # Exit type counts (ExitStats JSON)
├── run-NNNNNN/ # Divergent runs only (moved from temp dir)
│ └── (same structure as run-001)
Important: Matching (non-divergent) runs are deleted after comparison. Only run-001 and divergent runs remain in the test directory. The run numbering is zero-padded to 3 digits (run-001 through run-999), then plain (run-1000, etc.).
events.jsonl)bedrock-cli writes one JSONL file, events.jsonl, via --events-jsonl <path>. It is the
unified event stream: a time-ordered log of every record whose kind is captured.
--event-categories selects the non-exit kinds; Exit records are gated by
--exit-capture <mode> (and --single-step). The determinism binary captures only Exit
records (it passes --exit-capture all / at-shutdown / checkpoints:N), so for
determinism analysis every line is an exit record — but the same file can also carry
serial, inject, randomness, and io_channel records when those categories are enabled.
Each line is a flat JSON object: a small envelope plus the kind-specific body under data.
{"seq": 1234, "tsc": 987654321, "real_tsc": 140737488355328, "deterministic": true,
"kind": "exit", "data": { ... }}
Envelope fields (present on every record):
seq (u64) — monotonic sequence number; total order tie-breaker for records sharing a tsctsc (u64) — emulated (deterministic) TSC at emit time; the comparison time axisreal_tsc (u64) — host RDTSC at emit time; non-deterministic, for wall-clock correlation only, never compareddeterministic (bool) — whether the record participates in run-vs-run comparisonkind (string) — exit, serial, inject, randomness, io_channel, or unknowndata — the kind-specific body (shape depends on kind)There is no separate non-determ file: deterministic and non-deterministic exits are
interleaved in events.jsonl and distinguished by the top-level deterministic flag.
contrib/determ-divergence.py does the split itself (keep kind == "exit", partition the
data bodies on deterministic).
data fieldsFor kind: "exit", data holds the exit snapshot (the ExitRecord body):
Exit info:
tsc (u64) - Emulated TSC value at exitexit_reason (u32) - VM exit reason codeflags (u32) - Bit 0 = deterministic exit (mirrors the envelope deterministic flag)exit_qualification (u64) - Context-dependent qualification valueGuest registers:
rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi (u64)r8 through r15 (u64)rip (u64) - Instruction pointerrflags (u64)Device state hashes:
memory_hash (u64) - Hash of guest physical memory (0 if --no-memory-hash)apic_hash (u64) - Local APIC stateserial_hash (u64) - Serial port stateioapic_hash (u64) - I/O APIC statertc_hash (u64) - Real-time clock statemtrr_hash (u64) - MTRR staterdrand_hash (u64) - RDRAND/RDSEED state| Code | Name | Deterministic | Notes |
|---|---|---|---|
| 0 | EXCEPTION_NMI | no | |
| 1 | EXTERNAL_INTERRUPT | no | Host timer ticks, IPIs |
| 10 | CPUID | yes | |
| 12 | HLT | yes | |
| 16 | RDTSC | yes | Common in tight loops |
| 28 | CR_ACCESS | yes | |
| 30 | IO_INSTRUCTION | yes | |
| 31 | MSR_READ | yes | |
| 32 | MSR_WRITE | yes | |
| 36 | MWAIT | yes | Guest idle (expected) |
| 39 | MONITOR | yes | |
| 48 | EPT_VIOLATION | no | CoW faults, memory access |
| 51 | RDTSCP | yes | |
| 55 | XSETBV | yes | |
| 57 | RDRAND | yes | |
| 61 | RDSEED | yes | |
| 258 | VMCALL_SHUTDOWN | yes | Guest initiated shutdown |
| 260 | VMCALL_SNAPSHOT | yes |
Exit records are part of the event stream; the determinism test binary chooses which
exits become records via these flags (it lowers them to bedrock-cli's --exit-capture /
--single-step):
--checkpoint-interval INTERVAL — periodic snapshots every INTERVAL emulated-TSC ticks--all-exits — every exit is captured (large event streams)Additional modifiers:
--no-memory-hash — skip memory hashing (memory_hash will be 0)--capture-exits-after-tsc TSC — only start capturing exits after this TSC value--single-step START-END — MTF single-stepping in a TSC range (TscRange capture)--intercept-pf — trap guest #PF exceptionsThe determinism binary compares runs in two ways:
A run is marked DIVERGENT if either comparison finds a difference.
cat <test-dir>/config.txt
Note the key parameters: runs, parallel, stop_at_tsc/stop_at_vt, checkpoint_interval, all_exits, parent_id, no_memory_hash, intercept_pf.
cat <test-dir>/summary.txt
WARNING: The summary.txt may be stale (from an older test run that reused the same directory). Always verify by cross-referencing the number of runs in the summary against the actual run directories.
The summary format is:
Run 001: REFERENCE
Run 002: OK
Run 003: DIVERGENT
...
RESULT: DIVERGENCE DETECTED (or ALL RUNS IDENTICAL)
Since matching runs are deleted, the remaining run directories (besides run-001) are the divergent ones:
# List all run directories (these are run-001 + divergent runs only)
find <test-dir> -maxdepth 1 -type d -name "run-*" | sort
For each divergent run, examine artifacts:
# Status
cat <test-dir>/run-NNNNNN/status.txt
# Diff guest console output (shows crash messages, extra output, etc.)
diff <test-dir>/run-001/stdout.txt <test-dir>/run-NNNNNN/stdout.txt
# Full guest console output if diff is large or you need more context
cat <test-dir>/run-NNNNNN/stdout.txt
# Hypervisor logs
cat <test-dir>/run-NNNNNN/stderr.txt
# Event stream sizes (total records; exit records dominate in determinism runs)
wc -l <test-dir>/run-NNNNNN/events.jsonl <test-dir>/run-001/events.jsonl
Use the contrib/determ-divergence.py script to analyze divergent runs:
# Run divergence analysis
python3 contrib/determ-divergence.py <test-dir> run-NNNNNN
# With more context exits before divergence
python3 contrib/determ-divergence.py <test-dir> run-NNNNNN --context 20
# Widen the non-determ exit search window beyond the divergence point
python3 contrib/determ-divergence.py <test-dir> run-NNNNNN --nondeterm-window 50000
The script outputs:
The first divergent deterministic exit tells you that something between it and the prior exit caused the guest to execute differently. The non-determ exits in that TSC window are the key suspects:
If one run has a non-determ exit in the window that the other doesn't, that's likely the trigger. The TSC delta in the divergent exit shows the magnitude of the instruction count shift.
When reporting results, always include: