fix: close bug-1401 ctrlstatus leak, bug-1400 jobsub leak; harden bug-1396 harness

bug-1401: xce_free_ctrlstatus(s) was defined as free_CtrlStatus(s), which
only frees the fields inside xce_ctrlstatus_t. The real client reply path
(decode_CtrlStatus_ptr) calloc's the struct itself, so every ctrlstatus call
leaked sizeof(xce_ctrlstatus_t) (120 bytes). Existing unit tests never caught
it because they built/freed the struct via the raw stack-decode + bare
free_CtrlStatus() helpers, never exercising the actual client macro. Fixed
by switching the macro to free_CtrlStatus_ptr(&(s)) and added a regression
test that exercises the real heap-decode path; RED confirmed the exact
120-byte/1-alloc LeakSanitizer signature before the fix.

bug-1400: the originally reported SEGV in cmd_jobsub on malformed positional
input is stale — NULLSTR guards added 2025-11-05 already reject it cleanly.
The real residual defect was submit.start_info leaking on all 4 early-return
validation paths; fixed by routing them through a shared `goto cleanup`
(matches the existing goto-clean idiom in queue_ctrl).

bug-1396 (job-count anomaly after cold-restart-all, not yet root-caused):
instrumented test-commit-durability.sh's assert_job_count() to dump the live
joblist and ACKED_FILE ledger on any count mismatch instead of only the
count, per the bug's own recorded next step.

Verified: controller ASAN build + full controller_unit_test green; lib
xcelib_test 285/285 green, 0 ASAN leaks.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDWVNQLKxqTVHh42cH7rV3
This commit is contained in:
Rongsong Shen 2026-07-03 02:40:52 +00:00
parent 5cb36794d2
commit 9318f9977e
4 changed files with 82 additions and 8 deletions

View file

@ -1816,7 +1816,8 @@ int cmd_jobsub(int argc, char* argv[])
default:
printf(
"jobsub -u <user> -q <queue> -R <resreq> -c <command line>\n");
return -EINVAL;
rc = -EINVAL;
goto cleanup;
}
}
@ -1827,17 +1828,20 @@ int cmd_jobsub(int argc, char* argv[])
if (NULLSTR(submit.user)) {
printf("you need to specify job user with -u\n");
return -EINVAL;
rc = -EINVAL;
goto cleanup;
}
if (NULLSTR(submit.queue)) {
printf("you need to specify job queue with -q\n");
return -EINVAL;
rc = -EINVAL;
goto cleanup;
}
if (NULLSTR(submit.start_info->cmdline)) {
printf("you need to specify job command with -c\n");
return -EINVAL;
rc = -EINVAL;
goto cleanup;
}
if (NULLSTR(submit.resreq)) {
@ -1866,6 +1870,7 @@ int cmd_jobsub(int argc, char* argv[])
jobsubmit.array_size = arsize;
rc = xcecli_jobsubmit(active_ctx->ctx, &jobsubmit, &jobid);
cleanup:
FREEUP(submit.user);
FREEUP(submit.queue);
FREEUP(submit.resreq);