Write down that nothing has ever run under a sanitizer
This commit is contained in:
parent
afec482722
commit
c05edef985
34
NEXT.md
34
NEXT.md
@ -63,6 +63,40 @@ merged; 3 and 4 are still running.
|
||||
`Emit.redefinition` already takes and is already tested for. The second also unblocks source interleaving in the
|
||||
disassembly buffer.
|
||||
|
||||
### Queued — the runtime under a sanitizer
|
||||
|
||||
Nothing has ever run under ASan or UBSan on the test path. `grep -i 'sanitize\|asan\|valgrind'` over `lib/ bin/ test/
|
||||
runtime/ vendor/` returns nothing at all. This is not a big project — the whole C surface is about 1,260 lines
|
||||
(`flan_rt.c` 394, `flan_dev.c` 219, `flan_agent.c` 647) plus what `shim.ml` generates.
|
||||
|
||||
**The bugs are not in allocation.** There are four `malloc`/`calloc`/`strdup` sites in the entire runtime and every one
|
||||
is allocate-once-never-free by design — `rt_args` says so in its own comment — so LeakSanitizer would mostly produce
|
||||
suppressions. The risk is **fixed static buffers with bounds arithmetic**, and the ones with no coverage are already
|
||||
written down: `scratch[SCRATCH]` and `escaped[ESCAPE_MAX]` in `flan_rt.c`, the 4K result cap, the registry overflow
|
||||
guard, and `SNAP_MAX`/`SNAP_NAMES` from the restart snapshot.
|
||||
|
||||
There is evidence the sweep pays. Checking `flan_escape_bytes` by hand against lengths 0–1300 under ASan with a red
|
||||
zone found the guard correct but its comment understating its own reserve by four bytes — worst output 1021 into 1024.
|
||||
That was one buffer, found by looking.
|
||||
|
||||
The shape:
|
||||
|
||||
1. A `--sanitize` flag beside `--debug` in `lib/build.ml`, reaching both the clang run over the `.ll` and the runtime's
|
||||
own C.
|
||||
2. Run the existing corpus under it. `test/programs/` is about forty programs with pinned output — a second pass over
|
||||
them is the cheapest coverage available here, and needs no new test written.
|
||||
3. **UBSan is worth more than ASan**, with one exclusion that is not optional: arithmetic wraps by design, so
|
||||
`-fno-sanitize=signed-integer-overflow` or every program trips on the first `+`. What is left is real — shift UB
|
||||
(`(<< 1 32)` compiled to a bare `retq` at -O2, see Sharp edges), alignment, and the f32→i32 cast on NaN or an
|
||||
infinity that `floor-f32` guards by hand and nothing else does.
|
||||
4. The variant worth its own run: **ASan with `--no-bounds-checks`**. That asks whether the bounds checks are the only
|
||||
thing between the language and corruption, which the checked build cannot ask.
|
||||
|
||||
Two limits, so nobody is surprised. raylib and libm are not instrumented, so the windowed examples are noise and the
|
||||
headless corpus is the target — `sand-headless`, `values`, `machine`, `virtual-controls-headless`. And ASan does not
|
||||
see uninitialised reads, which is where `zeroed` and struct padding live; that wants Valgrind as a slower second pass,
|
||||
because MSan needs every dependency instrumented and raylib settles that.
|
||||
|
||||
### Queued — the `print-*` family goes
|
||||
|
||||
`print` and `println` are the whole printing surface. `print-str`, `print-i64`, `print-f64`, `print-bytes`,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user