fix(scheduler): a batch replay exits 0 under LeakSanitizer (bug-1884, part 6)

- kill_sched_resval() (every resource-value array's item killer) frees
  the value, not only a string's buffer: each replaced or torn-down value
  leaked its struct, including every WORKERS_PUSH value update.
- put_resvals() shares the value it creates with later entries for the
  same index in one call; it created a second one that replaced (and now
  freed) the first while still writing through it.
- JOB_UPDATE and the duplicate-JOBS_PUSH path kill_resreq() the old parsed
  resreq, and free the rejected job's schedobj (xce_core_free_schedobj(),
  exported from core.c), instead of freeing only the containers.
- The previous attempt's (or ALTER alternative's) pend reason is freed when
  a new one replaces it.
- kill_resreq_ctx() frees the parser context's error message, and the
  primary-resreq PEG action frees an earlier primary's message first.
- write_snapshot_entry() frees the snapshot it builds (config and resource
  objects detached, they are the core's); the save side strdup()s its
  strings so the generated free_SnapshotData() applies.

Test: test_cli_batch_replay_exits_clean_under_leak_detection
(test_sim_discrete_clock.c) runs the real binary on a two-session fixture
with detect_leaks=1 and requires exit 0: RED before (exit 1), GREEN now.
All nine HA-soak recordings replay with exit 0 and no LeakSanitizer report.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-09-29 09:44:43 +00:00
parent f6cab0ab87
commit 90b99d91e9
Signed by untrusted user: rshen
GPG key ID: 80533536B0EB651C
12 changed files with 107 additions and 14 deletions

View file

@ -1245,6 +1245,33 @@ static void test_cli_help_describes_sim_speed_as_deprecated(void)
free(text);
}
/* bug-1884: a batch replay frees what the simulator owns before exit, so an
* ASAN build with LeakSanitizer enabled exits 0. The test binary itself runs
* with detect_leaks=0 (meson.build), so the child re-enables it. Without
* ASAN the option is ignored and the test checks only the exit status. */
static void test_cli_batch_replay_exits_clean_under_leak_detection(void)
{
char fixture[PATH_MAX];
char out[PATH_MAX];
char log[PATH_MAX];
char cmd[4 * PATH_MAX];
write_two_session_fixture(fixture, sizeof(fixture));
make_tmp_file(out, PATH_MAX, "leakout");
make_tmp_file(log, PATH_MAX, "leaklog");
snprintf(cmd, sizeof(cmd),
"ASAN_OPTIONS=detect_leaks=1 " XCE_SCHEDULER_BIN
" --sim %s --sim-verify --sim-output %s --logfile %s "
"> /dev/null 2>&1",
fixture, out, log);
TEST_ASSERT_EQUAL_INT_MESSAGE(0, run_child(cmd),
"a clean batch replay must exit 0 with "
"leak detection enabled");
unlink(out);
unlink(log);
unlink(fixture);
}
int main(void)
{
UNITY_BEGIN();
@ -1265,5 +1292,6 @@ int main(void)
RUN_TEST(test_cli_trailing_sim_speed_without_value_fails);
RUN_TEST(test_cli_interactive_sim_speed_logs_one_warning);
RUN_TEST(test_cli_help_describes_sim_speed_as_deprecated);
RUN_TEST(test_cli_batch_replay_exits_clean_under_leak_detection);
return UNITY_END();
}