jab <projector> leaks the JS context on exit (LSan)Running a bareword projector through jab — e.g. jab grep:.js#emit — exits
under LeakSanitizer with a leak entirely inside libjavascriptcoregtk
(fastMalloc/fastRealloc): 640 B direct in 14 objects + 65035 B indirect in
3 objects (17 allocs, 65675 B). Native be grep:.js#emit is clean — the leak is
jab-specific: the JS global context (and its JSC heap) is not released on the
projector/loop exit path. Same family as JS-054 (error-exit paths leak the
whole context) and JS-007 (main script load). The JABC test suite masks this
class via the leak:libjavascriptcoregtk suppression; a bareword jab run does
not. Method Issues.
be/+beagle/ siblings, ASAN-built jab):
jab grep:.js#emit → ==ERROR: LeakSanitizer: detected memory leaks →
SUMMARY: AddressSanitizer: 65675 byte(s) leaked in 17 allocation(s).libjavascriptcoregtk-4.1.so
WTF::fastRealloc / malloc); no jab frame, so the JS context teardown is
the suspect, not a jab-side container.be grep:.js#emit runs clean (C path, no JSC).jab store.js bare exits rc=1 on
14 JSC-internal allocs (the singletons the suppression covers).jab <projector> (grep:/diff:/etc.) exits with NO LSan leak under ASAN —
the JS global context is released on EVERY exit path (success + error).jab run is leak-free.js/main.cpp (+ js/JABC.hpp); build WITH_JS + ASAN per
CLAUDE.md §0/§8. Repro-first (§17): a red→green ASAN check.JABCRunFile-style worker).JSClose→JSGlobalContextRelease
(main.cpp:291-298). The leak is benign JSC lazy-init VM singletons —
jab --eval 0 (same teardown) is clean; the leak tracks JS features used
(RegExp, iterators), does NOT scale with data (ls:. vs ls:beagle same
fixed ~12-18 KB), and JSGarbageCollect reclaims nothing. The "65 KB real
buffer" suspicion was wrong — process-lifetime VM state, all JSC frames.js/lsan.supp is applied only by the ctest ENV, so a bareword
end-user jab run has no suppression and reports the singletons. Fix =
embed the suppression in the ASAN binary, scoped to JSC frames only.jab ls:., faster proxy; grep: is verb-independent same class).__lsan_default_suppressions()→leak:libjavascriptcoregtk
(js/main.cpp:11-20, __has_feature(address_sanitizer)-guarded) + repro
js/test/run-064.sh + JABCleakLoop (js/CMakeLists.txt:112-113, NOT in
the suppression group). RED 18793 B/16 → GREEN exit 0, 16 suppressed.ctest -R JABC 30/30 incl. JABCleakLoop.leak:libjavascriptcoregtk masks ANY leak whose stack hits JSC
(incl. a hypothetical real JSValue-not-released) — but this only extends the
EXISTING js/lsan.supp policy (already used in ctest) to the standalone
binary, not a new risk. Flagged for the reviewer.c9395c2f — landed on beagle trunk: embed __lsan_default_suppressions
(leak:libjavascriptcoregtk, ASAN-only) in js/main.cpp + JABCleakLoop
repro (js/test/run-064.sh + js/CMakeLists.txt). Clean 3-way merge with
JS-063's js/CMakeLists.txt repoint. JABC 30/30; benign JSC singletons,
no real leak. Main tree needs be get to pull c9395c2f.