8.7 KiB
| id | status | status_updated | status_note | component | severity | timestamp | last_seen | occurrences | files | tags | related | fix_commits | gitea_issue | gitea_synced_status | gitea_synced_hash | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| bug-1929 | fixed | 2026-10-09 | scheduler | wrong-result | 2026-10-09T03:21:26Z | 2026-10-09T03:21:26Z | 1 |
|
|
|
|
354 | fixed | 32f3f26a5565 |
bug-1929: xce_scheduler --sim REPL continue round summary prints empty jobids= for a dispatch-only round
Description
Observed: in continue mode a round whose only decision is a dispatch prints a round summary with an empty job list, with tracing off as well as on. From the 6.3 trace-equivalence harness (XCE_TRACE_EQUIV_DUMP=1, extra replay, 8 occurrences):
[sim] round 1-1 (1 round(s), t=1970-01-01T00:00:00Z..1970-01-01T00:00:00Z): 4 dispatch, 1 pend, 0 preempt -- jobids=0-0-0-202
[sim] round 2-2 (1 round(s), t=1970-01-01T00:00:00Z..1970-01-01T00:00:00Z): 1 dispatch, 0 pend, 0 preempt -- jobids=
With the 1.1 contention fixture the dispatched job is missing even when a pend job is listed (round 8 dispatched 0-0-0-108):
[sim] round 8-8 (1 round(s), t=1970-01-01T00:00:00Z..1970-01-01T00:00:00Z): 1 dispatch, 1 pend, 0 preempt -- jobids=0-0-0-107
Expected: "jobids=" names the jobs the round's decisions affected (scheduler-sim-repl-verbosity Requirement 2.1: "the count of each decision type and the identifiers of the jobs affected"), so the dispatched (and preempted) jobs are listed: jobids=0-0-0-202 (the job pending in round 1 and dispatched in round 2) and jobids=0-0-0-107,0-0-0-108.
Impact: wrong/misleading REPL output only: the operator cannot see which job a round dispatched or preempted. A second effect of the same cause: rounds with the same counts and pend set but different dispatched jobs collapse into one range (Requirement 3.2 says a range needs the same affected job identifiers). Scheduling decisions are not affected.
Found by: scheduler-sim-decision-trace validation (rollup output in the 6.1/6.3 e2e and equivalence harness dumps).
Environment
- OS: no /etc/os-release; Docker container; NixOS kernel; kernel Linux 6.18.33 x86_64
- libc: glibc 2.42-47 (interpreter /nix/store/wb6rhpznjfczwlwx23zmdrrw74bayxw4-glibc-2.42-47/lib/ld-linux-x86-64.so.2)
- Toolchain: gcc (GCC) 15.2.0, meson 1.9.1
- Build: asan (xce.build), tests run with
ASAN_OPTIONS=detect_leaks=0(suite convention for these binaries); the symptom does not depend on sanitizer options or on tracing - Code: scheduler-framework @ 5ca59dc9-dirty
- Deployment: standalone simulator only (
xce_scheduler --sim ... --interactive), no controller, no workers; single dev host
Reproduction
- Build:
bash src/tools/xce-build.sh scheduler --jobs 12 --incrementalat the Environment commit. cd src/xce.build/scheduler/testsuite && XCE_TRACE_EQUIV_DUMP=1 ASAN_OPTIONS=detect_leaks=0 ./sched_trace_equivalence_test 2>&1 | grep 'jobids=$'-- 8 lines... 1 dispatch, 0 pend, 0 preempt -- jobids=.- Contention fixture:
printf 'continue\nquit\n' | TERM=dumb src/xce.build/scheduler/xce_scheduler --sim src/scheduler/testsuite/fixtures/repl_trace_baseline/contention.replay --interactive --logfile <tmp>/sched.log(repo root; with bug-1928 unfixed addASAN_OPTIONS=detect_leaks=0) -- round 8-8 lists only 0-0-0-107; rounds 1-1 and 5-5 list only the pend set. - Smallest:
test_round_summary_lists_dispatched_jobids_goldenin test_repl_round_rollup.c (drives xce_repl_on_begin_round/xce_repl_on_decision/repl_round_rollup_process directly).
- Frequency: deterministic (every run, 2026-10-09)
- Evidence: /home/claude/tmp/bug-1929/ -- equiv-dump-red.txt / equiv-dump-green.txt, e2e-dump-red.txt, contention-continue-red.txt / contention-continue-green.txt, rollup-red.txt, transcript.diff, fixture-backup/ (the baseline fixtures before regeneration)
Root cause
repl_round_emit() (src/scheduler/src/repl_rollup.c:178, listing built at :201-202 before the fix) built the "jobids=" listing from pend_jobids only, and repl_round_rollup_process() (repl_rollup.c:285) only ever collected the pend set (repl_query_pend_jobids(), a walk of core->jobs for JOB_IS_PEND jobs). The dispatch and preempt decisions were counted in xce_repl_on_decision() (src/scheduler/src/repl_break.c:953-959, last_n_dispatch/last_n_preempt) but their job ids were never recorded anywhere. A dispatched job is no longer pending after the round, so a dispatch-only round has an empty pend set and printed jobids= with nothing after it; in mixed rounds the dispatched jobs were silently left out. The same pend-only fingerprint made rounds that dispatched different jobs compare equal and collapse.
Since: 921c72bb (scheduler-sim-repl-verbosity task 2.2, Round Rollup), written while bug-1611 meant the simulator produced no DISPATCH decisions, so the pend set was the only affected-job information then.
Scope: the traced-round path (scheduler-sim-decision-trace 7.3/7.4) and the allocation-failure fallback go through the same repl_round_emit(); step mode prints per-decision lines and was not affected.
Fix
- src/scheduler/src/repl_internal.h: new state in
xce_sched_repl_state_s--round_decided_jobids/round_n_decided/round_cap_decided/round_decided_lost(this round's dispatch/preempt jobids) andcollapse_decided_jobids/collapse_n_decided_jobids(the active range's); declarations ofrepl_round_note_decided()/repl_round_reset_decided(). - src/scheduler/src/repl_break.c:
xce_repl_on_decision()records the jobid of each DISPATCH and PREEMPT decision (a decision with no body, jobid 0, is skipped);xce_repl_on_begin_round()resets the per-round list. - src/scheduler/src/repl_rollup.c:
repl_round_rollup_process()takes over the round's list (sorted, de-duplicated) and makes it part of the fingerprint next to the counts and the pend set, so rounds collapse only when the affected jobs match;repl_round_emit()lists the union of the pend set and the dispatch/preempt set (repl_fmt_affected(), through the existingrepl_fmt_jobid_range()compressor) and takes the pend count separately;repl_round_collapse_flush()frees the new list. If the per-round list cannot grow (out of memory) or the pend set cannot be built, the round is reported on its own withjobids=(unavailable)instead of an empty or partial list. - Tests: test_repl_trace_emit.c and test_repl_trace_wiring.c teardowns free the new lists (both run with leak detection on).
- src/scheduler/testsuite/fixtures/repl_trace_baseline/transcript.txt regenerated (XCE_REPL_BASELINE_REGEN=1, .replay fixtures restored from the backup): exactly two lines change, both
jobids=lines -- round 5-5jobids=0-0-0-107->jobids=0-0-0-104,0-0-0-105,0-0-0-106,0-0-0-107and round 8-8jobids=0-0-0-107->jobids=0-0-0-107,0-0-0-108.
Output format change: "jobids=" now means every job the range's decisions affected (Requirement 2.1), not only the jobs left pending; the counts are unchanged.
Verification
- Test:
test_round_summary_lists_dispatched_jobids_goldenin src/scheduler/testsuite/test_repl_round_rollup.c (exact golden lines for two dispatch-only rounds of different jobs, and a dispatch+preempt round): RED before the fix --Expected '[sim] round 1-1 ...: 1 dispatch, 0 pend, 0 preempt -- jobids=0-0-0-5101\n[sim] round 2-2 ...: 1 dispatch, 0 pend, 0 preempt -- jobids=0-0-0-5102\n' Was '[sim] round 1-2 (2 round(s), ...): 1 dispatch, 0 pend, 0 preempt -- jobids=\n'-- GREEN after (8 Tests 0 Failures).scheduler repl trace baseline testwith the regenerated transcript: GREEN (4 Tests 0 Failures, leak detection on). - Harness: equivalence dump (
XCE_TRACE_EQUIV_DUMP=1) has 8 emptyjobids=lines before and 0 after; all 8 dispatch-only rounds now readround 2-2 ... 1 dispatch, 0 pend, 0 preempt -- jobids=0-0-0-202(equiv-dump-green.txt). - Suites:
bash src/tools/xce-build.sh scheduler --jobs 12 --incremental: scheduler suite 118/118 OK, asan (log: /home/claude/tmp/bug-1929/gate-scheduler-suite.log). - Live: standalone contention run (Reproduction step 3) after the fix: round 8-8
jobids=0-0-0-107,0-0-0-108, round 1-1 lists 101-107 (contention-continue-green.txt).
References
- Related: bug-1611 (no DISPATCH decisions in sim at the time the rollup was written), bug-1610 (rollup introduced to replace per-decision lines)
- Docs: .kiro/specs/scheduler-sim-repl-verbosity/requirements.md (Requirement 2.1, 3.2); src/scheduler/testsuite/fixtures/repl_trace_baseline/transcript.txt