fix(ci): separate non-sanitized binary for valgrind and fix parse-error leaks - #202
fix(ci): separate non-sanitized binary for valgrind and fix parse-error leaks#202timsurrealedu wants to merge 5 commits into
Conversation
|
Thanks for your contribution. I'll provide a review. |
| @@ -1,5 +1,7 @@ | |||
| #!/bin/bash | |||
|
|
|||
| TARGET="${1:-./brainrot}" | |||
There was a problem hiding this comment.
must-fix: Default is still the ASan ./brainrot. CI (.github/workflows/ci.yml test job) and CONTRIBUTING.md invoke this with no args, so #186 stays broken there — ./run_valgrind_tests.sh still SIGSEGVs on startup and exits 0.
Default to ./brainrot-valgrind, and have CI build/upload that artifact (or run make valgrind).
|
|
||
| # Output files | ||
| TARGET := brainrot | ||
| VALGRIND_TARGET := brainrot-valgrind |
There was a problem hiding this comment.
should-fix: .gitignore only lists brainrot, so this binary is untracked. Add brainrot-valgrind next to it.
|
Thanks for the review @leo-aa88! I have addressed both comments:
|
|
There are some linter errors in the CI. Can you please address then? |
|
Please rebase. I pushed some fixes to our CI. |
…structor Fix ASan + Valgrind incompatibility by introducing a non-sanitized build target 'brainrot-valgrind' for 'make valgrind'. Update 'run_valgrind_tests.sh' to accept the binary target path as an argument. Also add Bison %destructor directives in lang.y for <strval> and <declarator> to free allocated strings when Bison discards symbols during parse error recovery (e.g. syntax errors in included files).
fe7013d to
a5cddc9
Compare
|
Done
Thanks @leo-aa88! |
There was a problem hiding this comment.
The ASan/Valgrind split is the right fix for #186, and it actually runs. CI invokes ./brainrot-valgrind, cooked_syntax_error / cooked_bad_include now free every heap block, make valgrind is green, pytest is 135/135. The %destructor for <strval> / <declarator> is the correct tool for lexer safe_malloc strings that never get reduced.
That is not the same as finishing the contract this PR claims.
make valgrind used to report success while doing nothing. After this patch, ./run_valgrind_tests.sh — the path CONTRIBUTING now documents as equivalent — can still report success while doing nothing. And in the same lang.y this PR edits, a comment still asserts that the grammar has no destructors.
See inline comments. Fix the script to fail closed. Rewrite the struct_field comment. Drop graphify-out/. Then this is mergeable.
| @@ -1,23 +1,29 @@ | |||
| #!/bin/bash | |||
|
|
|||
| TARGET="${1:-./brainrot-valgrind}" | |||
There was a problem hiding this comment.
MAJOR. Default is a binary make does not build. Only make valgrind / make brainrot-valgrind produces it.
CONTRIBUTING now documents ./run_valgrind_tests.sh with no args as equivalent to make valgrind. After a normal make, that path hits a missing file. Combined with the -eq 100 check below, the script still exits 0.
make valgrind passes the path explicitly, so that target is fine. CI is green only because the build job happens to upload the artifact first. That is job ordering, not a script invariant.
Fail closed here: [[ -x "$TARGET" ]] and command -v valgrind, or this default is a silent-success footgun.
| valgrind --leak-check=full --error-exitcode=100 "$TARGET" "$f" | ||
| fi | ||
|
|
||
| valgrind_exit_code=$? # Capture only valgrind’s exit code |
There was a problem hiding this comment.
MAJOR. This is the same success policy that made #186 silent.
The next lines only fail on valgrind exit code 100. Missing binary is 127. Valgrind not installed is 127. The ASan SIGSEGV that #186 caught was also not 100. That check is unchanged.
Verified: missing binary → valgrind exit 127 → loop continues → script exit 0.
--error-exitcode=100 only fires when valgrind itself classifies a client error. "Could not run the client" is not that. After 135 files of No such file or directory, this still reports a clean leak run.
Treat 127, and any failure to start the target, as a hard error. Do not make "not 100" mean "no leaks."
#186 was not "wrong binary." It was "the job can succeed without testing leaks." The sanitizer split removed one trigger. This check is the mechanism.
| ``` | ||
|
|
||
| Run: | ||
| Alternatively, make `run_valgrind_tests.sh` executable and run it directly (defaults to `./brainrot-valgrind`): |
There was a problem hiding this comment.
This documents the broken path as a supported workflow. After make, ./brainrot-valgrind does not exist, and run_valgrind_tests.sh will still "pass" because it only treats exit code 100 as failure.
Either delete this alternative or make the script refuse to run without an executable target. Do not tell people to invoke a checker that fail-opens.
|
Thanks for the detailed review, @leo-aa88! I’ve addressed the remaining comments:
I also ran the full test suite and Valgrind checks locally. All 135 tests passed, and The fixes are in commit |
Fixes #186.
Summary of Changes
Separate Valgrind Target (
brainrot-valgrind):VALGRIND_TARGET := brainrot-valgrindandVALGRIND_CFLAGS(without-fsanitize=address,undefined) toMakefile.make valgrindto build and run againstbrainrot-valgrind, eliminating the ASan + Valgrind startup crash.brainrot-valgrindtomake clean.Parameterize
run_valgrind_tests.sh:run_valgrind_tests.shto accept a target binary argument (TARGET="${1:-./brainrot}").Fix Parse-Error Memory Leaks (
lang.y):%destructorrules for<strval>and<declarator>to free allocated strings when Bison discards symbols during parse error handling.cooked_syntax_error.brainrotandcooked_bad_include.brainrot).