Repository navigation
Fix the weekly fuzz runs and the BESL leaks they found - #58
Merged
Merged
Conversation
install-action installs a prebuilt musl cargo-fuzz, which then builds the fuzz targets for x86_64-unknown-linux-musl. AddressSanitizer rejects the statically linked musl libc, so every fuzz job failed before fuzzing. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BYDnECscGCTZr5M5upFEMs
Each fuzz job now caches the Cargo registry and its fuzz target directory, keyed on the fuzz workspace lockfile, the same way rust.yml caches the engine build. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BYDnECscGCTZr5M5upFEMs
A type annotation such as `-> root` resolved to the program's root scope, because type lookup accepted any named node. The function then held a strong reference to its own ancestor, and the Rc cycle leaked the whole tree. The BESL compile fuzz target reported this as a leak. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BYDnECscGCTZr5M5upFEMs
A FunctionCall held a strong reference to the function it calls. A recursive call sits inside the function's own statements, so the tree formed an Rc cycle and was never freed. The BESL compile fuzz target reported these leaks. FunctionCall now stores a CallTarget: a weak reference for Function nodes, and a strong one for type constructors and on-demand array types that the call may be the only owner of. Read it with CallTarget::get. The program tree now owns every function, so callers keep the program alive while they use its main function. Functions used as values, such as `vec3f(main)` inside main, are now a lexer error, since they formed the same cycle. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BYDnECscGCTZr5M5upFEMs
Both workflows ran the same steps on the same schedule and differed only in crate and target list. One matrix over crate and target keeps a single place to change cargo-fuzz setup, caching, and artifacts, and job names still show which crate and target failed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BYDnECscGCTZr5M5upFEMs
facundo-villa
marked this pull request as ready for review
September 27, 2026 19:26
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Facundo · project thread
Before: every job in the first scheduled
Fuzz BESLandFuzz BETPruns failed in about 2 seconds withsanitizer is incompatible with statically linked libc, before any fuzzing happened. The fuzz workflows rebuilt every dependency each run. Once fuzzing ran, the BESLcompiletarget reported memory leaks formain: fn () -> root {}, recursive functions, andvec3f(main)insidemain.After: the fuzz targets build for
x86_64-unknown-linux-gnuand fuzz normally, with a cached build. All three leaking inputs compile without leaking. Recursion still links. A type name that isn't a type, and a function used as a value, are now lexer errors.How:
taiki-e/install-actionfalls back to cargo-binstall, which installs the prebuilt musl cargo-fuzz. cargo-fuzz defaults--targetto its own triple, and AddressSanitizer can't link static musl libc. Both workflows pass--target x86_64-unknown-linux-gnu.targetdirectory withactions/cache(backed by Blacksmith), keyed on the fuzz workspace'sCargo.lock, likerust.yml.resolve_typeaccepted any named node, so-> rootmademainhold its own ancestor. It now accepts onlyStructdeclarations.Expressions::FunctionCall::functionis now aCallTarget. It holds aWeakreference toFunctionnodes and a strong one to anything else, such as type constructors and on-demand array types the call may solely own. Read it withCallTarget::get(). The program tree now owns every function, so keep the program alive while you use itsmain. The test fixtures that returnedmainand dropped the program now return the program.LexError::Undefined, because it formed the same cycle.Validation:
byte-engine-beslhas 219 lib tests, andbyte-engine-resource-managementhas 628 lib and 12 integration tests; all pass. New lexer tests cover non-type names, functions as values, and recursive calls.cargo fmt --checkreports no new diffs. Each saved leak input runs clean under ASan.Known remaining: a 5-minute local
compilefuzz run found a parser timeout, not a leak. A 269-byte input of deeply nested unbalanced calls takes about 6 seconds to parse under ASan. It is in the parser, which this PR doesn't touch.🤖 Generated with Claude Code
https://claude.ai/code/session_01BYDnECscGCTZr5M5upFEMs