--- id: "bug-1437" status: "fixed" status_updated: "2026-10-02" status_note: "" component: "lib" severity: "crash" timestamp: "2026-07-13T00:55:00Z" last_seen: "2026-09-19T09:00:00Z" occurrences: 2 files: ["src/lib/testsuite/test_jobj_hardening.c"] tags: ["jobj", "test_jobj_hardening", "leak", "asan", "lsan", "datakiller", "dereference", "hard_build_accounts", "test_job_destroy_does_not_leak_accounts", "unverified-fix", "kvmgr", "job-array-single-wal-record", "mechanical-validation", "reconfirmed"] related: [] fix_commits: ["8c7d26a9", "e540902b"] legacy: true --- # bug-1437: LeakSanitizer leaks in test_jobj_hardening (makeInstance 240 B on init failure, 7 B strdup) ## Description Verification run of lib build + xcelib_test --run test_jobj_hardening (ASAN_OPTIONS=detect_leaks=1) after user changed 4x .datakiller=destroy -> .datakiller=dereference in src/lib/testsuite/test_jobj_hardening.c (to fix a leak in the kvmgr-of-job_t test fixture, since job_t.destroy is NULL in RTTI typeinfo and teardown only runs via job_dereference): Unity reports 5/5 PASS, 0 Failures, 0 Ignored, but LeakSanitizer STILL reports two leaks totaling 247 bytes and the process exits 1 (no halt_on_error/abort_on_error set, so no SIGABRT with plain detect_leaks=1 -- differs from the meson full-suite run which sets abort_on_error=1 and gets killed by signal 6). ## Environment _Not recorded (migrated from buglog.json)._ ## Reproduction _Not recorded (migrated from buglog.json)._ ## Root cause TWO leaks detected, only one already known. (1) Direct leak of 240 bytes via calloc -> makeInstance -> makeJob_ (../lib/jobj.c:768) -> makeJob (../lib/jobj.c:789) -> test_job_init_propagates_makeJobsub_failure (test_jobj_hardening.c:133) -- this IS the already-diagnosed, out-of-repo makeInstance-does-not-free-on-negative-init-rc characteristic (vendored rtti library), unrelated to the datakiller fix. (2) Direct leak of 7 bytes via strdup -> hard_build_accounts (test_jobj_hardening.c:269) -> test_job_destroy_does_not_leak_accounts (test_jobj_hardening.c:328) -- this is a SEPARATE, NEW leak signature not previously logged, and it is attributed to the exact test (test_job_destroy_does_not_leak_accounts) that the datakiller=dereference fix was meant to make leak-free. NOT YET DIAGNOSED WHY: could be an unrelated small leak in the hard_build_accounts helper itself (e.g. a strdup()d account string never freed regardless of datakiller correctness), or could indicate the datakiller fix is incomplete. Not investigated further per explicit user instruction to build/run/report only, no fixing. ## Fix Fixed 2026-07-17 by 8c7d26a9 (record not updated at the time): librtti re-pinned master 7212ba1 -> 53cf11e, where `makeInstance()` frees its calloc'd instance when the type's `.init()` returns negative. That was the 240-byte `makeInstance -> makeJob_` leak on every `job_init()` failure path (`test_job_init_propagates_makeJobsub_failure`). The commit's own verification already ran `test_jobj_hardening` clean under `detect_leaks=1:abort_on_error=1`, i.e. without the 7-byte `hard_build_accounts` leak either; e540902b (2026-07-27) re-pinned librtti again for a further package leak. No repository code change was needed. ## Verification - Test: `xcelib_test --run test_jobj_hardening` with `ASAN_OPTIONS=detect_leaks=1` (2026-10-01, asan build `src/build.jai`): 5/5 PASS, both formerly leaking tests included, no LeakSanitizer report, exit 0; LSan confirmed active in this toolchain (a deliberate 7-byte leak in a scratch program is reported) - Suites: full `xcelib_test` with `detect_leaks=1`: 715/715, no leak report, exit 0; `meson test "libxce test"` (meson's default `abort_on_error=1`): OK, 0 `leak of` lines in the test log - Live: n/a (test-binary leak) ## References _Not recorded (migrated from buglog.json)._