feat(scheduler-core): implement REPL breakpoints and state inspection (task 12.2)
Adds the interactive simulation REPL's breakpoint and state-inspection commands (Req 5 AC 22): `break <event_type> [key=value ...]` / `info break` / `delete <id>|all` on event and decision types, and `info session/job/queue/worker/resource/summary`. repl.c (370 lines after task 12.1) couldn't hold this task's full surface under the project's 800-line cap, so it's split three ways (matching the snapshot.c/snapshot_wire.c/snapshot_load.c precedent): repl.c (execution control + dispatch), repl_break.c (matching/CRUD + the three new driver-facing hooks), repl_info.c (info dumps), sharing state via repl_internal.h. sim_loop.c gained 3 new bare hook calls (repl.h inline wrappers, same pattern as task 12.1's two) at the points design.md's pseudocode requires -- per decoded event before it joins the batch, per session boundary, and per drained decision -- landing sim_loop.c at exactly 800/800 lines. Two real bugs found and fixed during development (bug-1506, bug-1507): an uninitialized xstr_table left breakpoint filter fields silently NULL instead of failing loud, and repl_breakpoint_free() called a bare free() on an RTTI-refcounted makeString() string, corrupting the heap. Review found one gap: `info job` printed only a resreq presence flag instead of the actual resreq text, when format_resreq() already existed in this repo for exactly this purpose. Fixed to match. Scheduler suite: 35/35 clean (was 34/34). RED-phase evidence (2 real bugs plus 2 synthetic probes, all reverted with confirmed zero residue) recorded in tasks.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JPPXeKSUXUqcqvzNXY1rzJ
This commit is contained in:
parent
02f7f48ff9
commit
2fecea3592
18 changed files with 3067 additions and 212 deletions
|
|
@ -14840,5 +14840,48 @@
|
|||
],
|
||||
"occurrences": 1,
|
||||
"last_seen": "2026-08-07T08:10:00Z"
|
||||
},
|
||||
{
|
||||
"id": "bug-1506",
|
||||
"timestamp": "2026-08-07T09:05:00Z",
|
||||
"error_message": "sched_repl_breakpoints_inspection_test: repl_dispatch(sim, \"break JOB_STATE_CHANGE jobid=12345\") stored NULL for the breakpoint's token/filter key/value -- TEST_ASSERT_EQUAL_STRING(\"jobid\", ...) failed with 'Expected jobid Was NULL'.",
|
||||
"file": "src/scheduler/testsuite/test_repl_breakpoints_inspection.c",
|
||||
"root_cause": "makeString() (src/lib/xstring.c) is an interned-xstring allocator backed by a process-global xstr_table that must be initialized via xstring_table_init() before first use -- xce_sched_core_init() (core.c) is the only call site in the scheduler tree and does this transitively. New task 12.2 unit tests built a bare xce_sched_sim_driver_t via memset(0) and called repl_state_ensure()/repl_dispatch() directly for pure command-dispatch tests, without ever calling xce_sched_core_init() first (the real driver flow always does, via sched_sim_driver_start() before xce_repl_start() runs, so this precondition is always satisfied in production -- only the test fixtures skipped it). With xstr_table uninitialized (NULL), makeString()'s internal key_find()/key_add() against a NULL kvmgr container fail gracefully and return NULL rather than crash, so the bug surfaced as silently-NULL breakpoint fields, not an immediate crash.",
|
||||
"fix": "Added xce_sched_core_init(&(sim.core)) as the first statement (right after memset) in every Group A/B test in test_repl_breakpoints_inspection.c that calls repl_dispatch()'s break/delete commands or the repl_break.c matcher functions -- matching the real driver's own precondition ordering.",
|
||||
"tags": [
|
||||
"scheduler-core",
|
||||
"task-12.2",
|
||||
"repl",
|
||||
"xstring",
|
||||
"test-fixture",
|
||||
"makeString"
|
||||
],
|
||||
"related_bugs": [
|
||||
"bug-1507"
|
||||
],
|
||||
"occurrences": 1,
|
||||
"last_seen": "2026-08-07T09:05:00Z"
|
||||
},
|
||||
{
|
||||
"id": "bug-1507",
|
||||
"timestamp": "2026-08-07T09:10:00Z",
|
||||
"error_message": "sched_repl_breakpoints_inspection_test: 'free(): invalid pointer' SIGABRT inside repl_breakpoint_free(), reached from repl_cmd_break()'s malformed-filter rejection path (\"break JOB_PUSH nofiltermark\"). gdb backtrace: malloc_printerr <- repl_breakpoint_free (repl_break.c:375) <- repl_cmd_break <- repl_dispatch <- test_break_malformed_filter_rejected.",
|
||||
"file": "src/scheduler/src/repl_break.c",
|
||||
"root_cause": "repl_breakpoint_free() called FREEUP() (a bare free()) on bp->token and each filter's key/value, all of which are makeString()-produced xstrings -- RTTI reference-counted objects (src/lib/xstring.c: xstring_type has custom .reference/.dereference interface functions; the returned pointer is the object's DATA region inside an RTTI-managed allocation, not a plain malloc() chunk). Releasing one requires going through the RTTI dereference path (xstring_dereference(), which only fires the real free when the refcount hits zero via the owning kvtab's key_del), never a bare free(). This codebase's own kill_sched_job()/kill_sched_queue() (schedobj.c) establish the identical precedent for every other makeString()'d field in the scheduler tree (xce_sched_job_t.submit fields, xce_sched_queue_t.name, etc.): none of them are ever explicitly released either -- they live for the process's lifetime, matching this whole test suite's 'detect_leaks=0 by design' convention. My new repl_break.c code was the first place in this file family to call free() directly on a makeString() result.",
|
||||
"fix": "Removed the FREEUP() calls on bp->token/filters[i].key/filters[i].value from repl_breakpoint_free() (repl_break.c) -- it now only frees the plain calloc'd bp->filters array and bp itself, matching kill_sched_job()/kill_sched_queue()'s established never-release-xstrings precedent. Updated repl_internal.h's xce_repl_filter_t doc comment to state this explicitly so a future maintainer doesn't reintroduce the same free() on an RTTI-managed pointer.",
|
||||
"tags": [
|
||||
"scheduler-core",
|
||||
"task-12.2",
|
||||
"repl",
|
||||
"xstring",
|
||||
"heap-corruption",
|
||||
"free",
|
||||
"rtti"
|
||||
],
|
||||
"related_bugs": [
|
||||
"bug-1506"
|
||||
],
|
||||
"occurrences": 1,
|
||||
"last_seen": "2026-08-07T09:10:00Z"
|
||||
}
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue