fix(harness): reset getopt_long via optind=0 to stop cross-command corruption

Every cmd_* REPL handler in test.c/join_worker_args.c reset flag parsing
with `optind = 1;` only. glibc's getopt_long only fully reinitializes its
internal scan state (nextchar/first_nonopt/last_nonopt) when optind==0, or
on the process's very first getopt_long() call ever -- optind=1 alone
leaves that state stale for every call after the first. Since xce_test's
REPL dispatches many independent cmd_*() calls per process, a command
whose parse ends on a short no-argument flag (`qctrl -a`, `hostctrl -o`)
left state that corrupted the NEXT unrelated command's parse badly enough
to misread its own name as an unrecognized flag. This was the actual
cause of harness_unit_test's 4 deterministic (not flaky -- 20/20 identical
repeat runs) test_test_cli.c failures, each burning its full 5s
confirmation-prompt timeout. Fixed by using optind=0 at all 21 reset
sites; confirmed via 3 isolated pty repros plus 10 consecutive clean
harness_unit_test runs (132/132, was 4 failures/run every time).

Also fixes a resource leak found while investigating: test_test_cli.c's
spawned xce_test sessions were only torn down by inline
clitest_kill_and_reap()/clitest_close() calls at the bottom of each test
function, which Unity's longjmp-based TEST_ASSERT abort skips entirely on
failure, leaking the child process and its pty/pipe fds. Added a static
session mirror (safe across the longjmp, unlike a stack pointer) reaped
from harness_test.c's tearDown(), which Unity guarantees runs after every
test regardless of outcome.

Logged as bug-1807/bug-1808 in .wolf/buglog.json, with the underlying
getopt/longjmp gotchas recorded in .wolf/cerebrum.md. Full ASAN
/xce-build harness also passes 5/5 with no sanitizer findings.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RLSNJhNoULvVcUhXEFafQC
This commit is contained in:
Rongsong Shen 2026-09-14 23:16:11 +00:00
parent cbf822fc53
commit 868c6427c8
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
9 changed files with 672 additions and 74 deletions

View file

@ -4549,3 +4549,161 @@
|------|--------|---------|---------|--------|
| 02:32 | Created reports/sep06-sep12-2026.md | — | ~3109 |
| 02:37 | Edited CHANGES.md | modified docs() | ~2946 |
| 19:16 | Session end: 2 writes across 2 files (sep06-sep12-2026.md, CHANGES.md) | 6 reads | ~16580 tok |
## Session: 2026-09-14 19:16
| Time | Action | File(s) | Outcome | ~Tokens |
|------|--------|---------|---------|--------|
| 19:30 | Created .kiro/specs/xce-harness-component/brief.md | — | ~2810 |
| 19:39 | Edited .kiro/steering/roadmap.md | 3→4 lines | ~372 |
| 19:46 | Created .kiro/specs/xce-harness-component/spec.json | — | ~130 |
| 19:46 | Created .kiro/specs/xce-harness-component/requirements.md | — | ~567 |
| 19:50 | Created .kiro/specs/xce-harness-component/requirements.md | — | ~2592 |
| 19:50 | Edited .kiro/specs/xce-harness-component/spec.json | 9→9 lines | ~66 |
| 20:01 | Edited .kiro/specs/xce-harness-component/spec.json | 4→4 lines | ~22 |
| 20:06 | Created .kiro/specs/xce-harness-component/research.md | — | ~3858 |
| 20:08 | Created .kiro/specs/xce-harness-component/design.md | — | ~6724 |
| 20:09 | Edited .kiro/specs/xce-harness-component/design.md | 4→7 lines | ~314 |
| 20:09 | Edited .kiro/specs/xce-harness-component/spec.json | 13→13 lines | ~85 |
| 20:25 | Edited .kiro/specs/xce-harness-component/design.md | inline fix | ~59 |
| 20:25 | Edited .kiro/specs/xce-harness-component/design.md | "src/include/ctrlstatus_fm" → "src/include/xce/ctrlstatu" | ~126 |
| 20:25 | Edited .kiro/specs/xce-harness-component/design.md | inline fix | ~61 |
| 20:25 | Edited .kiro/specs/xce-harness-component/design.md | 3→3 lines | ~446 |
| 20:26 | Edited .kiro/specs/xce-harness-component/design.md | expanded (+12 lines) | ~659 |
| 20:26 | Edited .kiro/specs/xce-harness-component/design.md | 3→4 lines | ~204 |
| 20:26 | Edited .kiro/specs/xce-harness-component/design.md | 2→2 lines | ~123 |
| 20:26 | Edited .kiro/specs/xce-harness-component/design.md | 28→29 lines | ~889 |
| 20:27 | Edited .kiro/specs/xce-harness-component/design.md | 4→4 lines | ~75 |
| 20:27 | Edited .kiro/specs/xce-harness-component/design.md | controller_unit_test() → suite() | ~80 |
| 20:27 | Edited .kiro/specs/xce-harness-component/design.md | "harness_unit_test" → "s five " | ~151 |
| 20:27 | Edited .kiro/specs/xce-harness-component/research.md | 2→3 lines | ~487 |
| 20:27 | Edited .kiro/specs/xce-harness-component/research.md | expanded (+8 lines) | ~907 |
| 20:28 | Edited .kiro/specs/xce-harness-component/research.md | inline fix | ~207 |
| 20:28 | Edited .kiro/specs/xce-harness-component/design.md | inline fix | ~373 |
| 20:31 | Edited .kiro/specs/xce-harness-component/design.md | inline fix | ~130 |
| 20:31 | Edited .kiro/specs/xce-harness-component/design.md | inline fix | ~62 |
| 20:31 | Edited .kiro/specs/xce-harness-component/design.md | inline fix | ~26 |
| 20:35 | Edited .kiro/specs/xce-harness-component/spec.json | 4→4 lines | ~20 |
| 20:38 | Created .kiro/specs/xce-harness-component/tasks.md | — | ~2635 |
| 20:45 | Created .kiro/specs/xce-harness-component/tasks.md | — | ~2676 |
| 20:51 | Edited .kiro/specs/xce-harness-component/tasks.md | 6→8 lines | ~649 |
| 20:52 | Edited .kiro/specs/xce-harness-component/tasks.md | 9→11 lines | ~673 |
| 20:52 | Edited .kiro/specs/xce-harness-component/spec.json | 18→18 lines | ~105 |
| 20:54 | Edited .kiro/specs/xce-harness-component/spec.json | 6→6 lines | ~31 |
| 21:01 | Created src/harness/meson.build | — | ~387 |
| 21:02 | Edited src/meson.build | 2→3 lines | ~16 |
| 21:03 | Edited src/controller/meson.build | removed 30 lines | ~21 |
| 21:03 | Edited src/controller/meson.build | removed 23 lines | ~20 |
| 21:03 | Edited src/controller/meson.build | removed 27 lines | ~20 |
| 21:04 | Edited src/controller/meson.build | — | ~0 |
| 21:04 | Edited src/controller/meson.build | 7→8 lines | ~146 |
| 21:04 | Edited src/controller/testsuite/controller_test.c | removed 12 lines | ~12 |
| 21:04 | Edited src/controller/testsuite/controller_test.c | removed 12 lines | ~10 |
| 21:06 | Edited src/controller/meson.build | 8→7 lines | ~122 |
| 21:08 | Edited src/harness/meson.build | modified TEMPORARY() | ~174 |
| 21:13 | Edited src/controller/meson.build | 2→2 lines | ~32 |
| 21:13 | Edited src/controller/meson.build | expanded (+18 lines) | ~311 |
| 21:29 | Edited src/controller/meson.build | modified TEMPORARY() | ~471 |
| 21:48 | Edited src/controller/meson.build | inline fix | ~17 |
| 22:05 | Edited .kiro/specs/xce-harness-component/design.md | inline fix | ~311 |
| 22:05 | Edited .kiro/specs/xce-harness-component/design.md | 1→2 lines | ~271 |
| 22:06 | Edited .kiro/specs/xce-harness-component/tasks.md | inline fix | ~37 |
| 22:06 | Edited .kiro/specs/xce-harness-component/tasks.md | expanded (+7 lines) | ~518 |
| 22:10 | Edited src/harness/test.c | "ctrlstatus_fmt.h" → "xce/ctrlstatus_fmt.h" | ~20 |
| 22:10 | Edited src/harness/joblist_display.c | "ctrlstatus_fmt.h" → "xce/ctrlstatus_fmt.h" | ~17 |
| 22:10 | Edited src/controller/testsuite/test_ctrlstatus.c | "ctrlstatus_fmt.h" → "xce/ctrlstatus_fmt.h" | ~20 |
| 22:10 | Edited src/harness/meson.build | removed 10 lines | ~19 |
| 22:19 | Edited .kiro/specs/xce-harness-component/tasks.md | inline fix | ~23 |
| 22:23 | Created src/harness/CLAUDE.md | — | ~1224 |
| 22:28 | Edited .kiro/specs/xce-harness-component/tasks.md | inline fix | ~12 |
| 22:33 | Created src/harness/testsuite/harness_test.c | — | ~719 |
| 22:33 | Edited src/harness/meson.build | modified suite() | ~936 |
| 22:34 | Edited src/harness/meson.build | 5→5 lines | ~54 |
| 22:34 | Edited src/controller/meson.build | 7→5 lines | ~43 |
| 22:34 | Edited src/controller/meson.build | removed 26 lines | ~36 |
| 22:34 | Edited src/controller/testsuite/controller_test.c | 4→2 lines | ~23 |
| 22:34 | Edited src/controller/testsuite/controller_test.c | 4→2 lines | ~19 |
| 22:48 | Edited .kiro/specs/xce-harness-component/tasks.md | inline fix | ~38 |
| 22:49 | Edited .kiro/specs/xce-harness-component/tasks.md | 1→2 lines | ~214 |
| 22:53 | Edited src/harness/testsuite/test_joblist_display.c | "ctrlstatus_fmt.h" → "xce/ctrlstatus_fmt.h" | ~21 |
| 22:54 | Edited src/harness/meson.build | expanded (+111 lines) | ~1490 |
| 23:08 | Edited .kiro/specs/xce-harness-component/tasks.md | inline fix | ~19 |
| 23:08 | Edited .kiro/specs/xce-harness-component/tasks.md | 1→2 lines | ~160 |
| 23:12 | Edited src/tools/xce-build.sh | "Components: all (default)" → "Components: all (default)" | ~30 |
| 23:12 | Edited src/tools/xce-build.sh | expanded (+9 lines) | ~247 |
| 23:44 | Edited .kiro/specs/xce-harness-component/design.md | inline fix | ~82 |
| 23:44 | Edited .kiro/specs/xce-harness-component/tasks.md | inline fix | ~22 |
| 23:47 | Edited .claude/skills/xce-test-ha/run-ha-soak.sh | 2→7 lines | ~122 |
| 23:47 | Edited .claude/skills/xce-test-ha/run-ha-soak.sh | expanded (+6 lines) | ~175 |
| 23:47 | Edited .claude/skills/xce-test-ha/SKILL.md | 3→3 lines | ~50 |
| 23:47 | Edited .claude/skills/xce-test-ha/SKILL.md | modified skill() | ~229 |
| 23:48 | Edited .claude/skills/xce-test-ha/SKILL.md | 12→15 lines | ~189 |
| 23:48 | Edited .claude/skills/xce-test-ha/SKILL.md | inline fix | ~21 |
| 23:48 | Edited .claude/skills/xce-test-ha/SKILL.md | 2→3 lines | ~158 |
| 23:49 | Edited .claude/skills/xce-test-ha/SKILL.md | 4→7 lines | ~99 |
| 23:56 | Edited .kiro/specs/xce-harness-component/tasks.md | inline fix | ~18 |
| 00:01 | Edited .claude/skills/xce-deploy-ha/SKILL.md | expanded (+11 lines) | ~274 |
| 00:01 | Edited .claude/skills/xce-deploy-ha/SKILL.md | 1→2 lines | ~210 |
| 00:08 | Edited .kiro/specs/xce-harness-component/tasks.md | inline fix | ~23 |
| 00:10 | Edited .claude/skills/xce-test-multihost/run-multihost-verify.sh | 4→9 lines | ~157 |
| 00:10 | Edited .claude/skills/xce-test-multihost/run-multihost-verify.sh | expanded (+8 lines) | ~176 |
| 00:10 | Edited .claude/skills/xce-test-multihost/run-multihost-verify.sh | modified 4() | ~243 |
| 00:11 | Edited .claude/skills/xce-test-multihost/SKILL.md | expanded (+12 lines) | ~357 |
| 00:11 | Edited .claude/skills/xce-test-multihost/SKILL.md | 2→4 lines | ~68 |
| 00:11 | Edited .claude/skills/xce-test-multihost/SKILL.md | 2→2 lines | ~32 |
| 00:21 | Edited .kiro/specs/xce-harness-component/tasks.md | inline fix | ~22 |
| 00:23 | Edited .claude/skills/xce-test-resources/run-resource-verify.sh | 4→9 lines | ~170 |
| 00:23 | Edited .claude/skills/xce-test-resources/run-resource-verify.sh | expanded (+7 lines) | ~168 |
| 00:23 | Edited .claude/skills/xce-test-resources/SKILL.md | modified vars() | ~487 |
| 00:24 | Edited .claude/skills/xce-test-resources/SKILL.md | 10→14 lines | ~208 |
| 00:29 | Edited .kiro/specs/xce-harness-component/tasks.md | inline fix | ~23 |
| 00:34 | Edited CLAUDE.md | inline fix | ~60 |
| 00:34 | Edited CLAUDE.md | 6→7 lines | ~83 |
| 00:34 | Edited .kiro/steering/build-deployment.md | 3→4 lines | ~64 |
| 00:34 | Edited .kiro/steering/build-deployment.md | "controller" → "harness" | ~80 |
| 00:34 | Edited .kiro/steering/build-deployment.md | 2→3 lines | ~63 |
| 00:34 | Edited .kiro/steering/build-deployment.md | inline fix | ~96 |
| 00:34 | Edited .kiro/steering/build-deployment.md | "lib → {controller, worker" → "lib → {controller, harnes" | ~22 |
| 00:42 | Edited .kiro/steering/build-deployment.md | inline fix | ~76 |
| 00:45 | Edited .kiro/specs/xce-harness-component/tasks.md | inline fix | ~24 |
| 00:47 | Edited .kiro/steering/structure.md | 2→3 lines | ~57 |
| 00:47 | Edited .kiro/steering/structure.md | inline fix | ~41 |
| 00:48 | Edited .kiro/steering/structure.md | inline fix | ~39 |
| 00:55 | Edited .kiro/specs/xce-harness-component/tasks.md | inline fix | ~19 |
| 00:56 | Edited .kiro/specs/xce-harness-component/tasks.md | 1→2 lines | ~216 |
| 01:10 | Edited .kiro/specs/xce-harness-component/tasks.md | inline fix | ~17 |
| 01:10 | Edited .kiro/specs/xce-harness-component/tasks.md | modified found() | ~263 |
| 01:35 | Edited .kiro/specs/xce-harness-component/tasks.md | inline fix | ~21 |
| 02:18 | Edited .kiro/specs/xce-harness-component/requirements.md | "xce_test" → "s explicit compile step s" | ~37 |
| 02:18 | Edited .kiro/specs/xce-harness-component/requirements.md | 1→2 lines | ~450 |
| 02:19 | Edited .kiro/specs/xce-harness-component/design.md | inline fix | ~50 |
| 02:19 | Edited .kiro/specs/xce-harness-component/design.md | 4→5 lines | ~415 |
| 02:19 | Edited .kiro/specs/xce-harness-component/tasks.md | 5→5 lines | ~210 |
| 02:20 | Edited .kiro/specs/xce-harness-component/tasks.md | 1→2 lines | ~368 |
| 03:36 | Edited .kiro/specs/xce-harness-component/tasks.md | inline fix | ~18 |
| 03:36 | Edited .kiro/specs/xce-harness-component/tasks.md | 1→2 lines | ~216 |
| 04:26 | Edited src/harness/CLAUDE.md | point() → tests() | ~444 |
| 04:27 | Edited .kiro/specs/xce-harness-component/tasks.md | 1→2 lines | ~339 |
| 04:27 | Edited .kiro/specs/xce-harness-component/spec.json | 3→3 lines | ~28 |
| 04:47 | Edited .claude/skills/xce-build/SKILL.md | "Build XCE components with" → "Build XCE components with" | ~106 |
| 04:47 | Edited .claude/skills/xce-build/SKILL.md | inline fix | ~38 |
| 04:48 | Edited .claude/skills/xce-build/SKILL.md | "controller" → "xce_test" | ~314 |
| 04:48 | Edited src/controller/testsuite/test_rcfile_integration.sh | "${XCE_TEST_BIN:-$REPO_ROO" → "${XCE_TEST_BIN:-$REPO_ROO" | ~19 |
| 04:48 | Edited src/controller/testsuite/test_rcfile_integration.sh | "FAIL: xce_test not found/" → "FAIL: xce_test not found/" | ~27 |
| 04:48 | Edited src/controller/testsuite/clean_failover_preservation.sh | "${XCE_TEST_BIN:-$REPO_ROO" → "${XCE_TEST_BIN:-$REPO_ROO" | ~19 |
| 04:48 | Edited src/controller/testsuite/clean_failover_preservation.sh | inline fix | ~26 |
| 04:48 | Edited src/tools/test-commit-durability.sh | inline fix | ~23 |
| 04:48 | Edited src/tools/test-commit-durability.sh | "$WORKTREE/src/xce.build/c" → "$WORKTREE/src/xce.build/h" | ~14 |
| 04:55 | Session end: 140 writes across 25 files (brief.md, roadmap.md, spec.json, requirements.md, research.md) | 67 reads | ~167315 tok |
## Session: 2026-09-14 04:55
| Time | Action | File(s) | Outcome | ~Tokens |
|------|--------|---------|---------|--------|
| 05:16 | Edited .claude/skills/xce-build/SKILL.md | modified heaviest() | ~619 |
| 08:06 | Edited src/harness/testsuite/test_test_cli.c | 10→11 lines | ~76 |
| 08:06 | Edited src/harness/testsuite/test_test_cli.c | added 4 condition(s) | ~608 |
| 08:07 | Edited src/harness/testsuite/test_test_cli.c | added 1 condition(s) | ~86 |
| 08:07 | Edited src/harness/testsuite/test_test_cli.c | added 1 condition(s) | ~95 |
| 08:07 | Edited src/harness/testsuite/harness_test.c | modified that() | ~184 |