fix(scheduler): clock/resval/jobid-format fixes plus REPL live-operator gaps (task 12.5)
Bugs fixed, discovered across a day of live-operator testing against a real deployed cluster: - bug-1584: clock anchors never initialized to real wall-clock values, timestamps showed system uptime instead of Unix epoch. - bug-1585: heap-use-after-free in the normal-mode driver's periodic resval update path -- core_events.c's RESVALS_FULL/_DELTA handlers do a shallow zarray_put() of the wire-decoded xce_val_t*, but driver.c's release_translated_payload() unconditionally freed the same decoded array right after, so the next periodic report for the same worker+resource triggered a UAF read via kill_sched_resval(). New regression test: test_resval_ownership.c. - bug-1587/1588/1591: raw-ns/raw-uint64 jobid/timestamp prints across the REPL/SIM family converted to the same human-readable formatting already used elsewhere (fmt_jobid(), timestamp formatting). - bug-1590: repl_info.c's XCE_VAL_NUMERIC checks corrected to Value_u_fvalue, fixing `info worker`/`info resource` falling back to 0.00 for real numeric resvals. task 12.5 (Req 5.22 amendment) -- five REPL gaps surfaced by a live operator session, each with its own bug id: - bug-1594: `continue`/`step` reaching EOF with no breakpoint hit now re-enters the REPL via xce_repl_on_replay_complete() instead of exiting the process; step/continue issued after replay is already complete re-prompt instead of silently exiting. - bug-1595: `step`/`continue` now echo each input event (not just decisions) via repl_print_event_summary(), in real event/decision order. - bug-1593: `info resource <name>|all` now reports resource definition metadata restricted to XCE_RESF_GLOBAL/XCE_RESF_SHARED resources, read from core->sharedInst, instead of aggregating host-based resources across every worker. - bug-1596: repl_split_tokens() strips one matching pair of surrounding quote characters from each token. See requirements.md's Req 5 AC 22 "Amendment (2026-08-19)" for the full rationale on each of the five task 12.5 gaps. Full scheduler suite green (41/42; the one remaining failure, test_recordstart_symlink_escape_replies_error, is the pre-existing unrelated bug-1560).
This commit is contained in:
parent
515f4ca098
commit
c9acd502c0
32 changed files with 2547 additions and 295 deletions
|
|
@ -246,6 +246,53 @@ static void test_xce_sched_core_init_seeds_normal_mode_defaults(void)
|
|||
1, atomic_load_explicit(&(core.speed_den), memory_order_acquire));
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* xce_core_set_wallclock_anchor() -- normal-mode epoch seeding (bug-1584) */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static uint64_t test_epoch_ns(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
return ((uint64_t)ts.tv_sec * TEST_NSEC_PER_SEC) + (uint64_t)ts.tv_nsec;
|
||||
}
|
||||
|
||||
static void test_xce_core_set_wallclock_anchor_seeds_real_epoch_time(void)
|
||||
{
|
||||
/* bug-1584: xce_sched_core_init() alone leaves xce_core_now() returning
|
||||
* raw CLOCK_MONOTONIC-since-boot nanoseconds (see
|
||||
* test_xce_sched_core_init_seeds_normal_mode_defaults above) -- NOT
|
||||
* epoch time, which every real consumer of a normal-mode timestamp
|
||||
* needs (recording.c's record_start_ts, SchedAdminReply.startedAt,
|
||||
* documented in controller.capnp as "nanoseconds since epoch").
|
||||
* xce_core_set_wallclock_anchor() is the fix: bracket its effect on
|
||||
* xce_core_now() between two back-to-back CLOCK_REALTIME reads taken
|
||||
* immediately before/after the call -- deterministic (real time only
|
||||
* moves forward) and immune to sleep-based flakiness. Before this fix,
|
||||
* `result` would be a small monotonic-since-boot value, far below
|
||||
* `before` (a real epoch value ~1.7e18 ns as of 2026) -- this bracket
|
||||
* fails loudly on that regression rather than passing by coincidence. */
|
||||
xce_sched_core_t core;
|
||||
uint64_t before, result, after;
|
||||
|
||||
fixture_init(&core);
|
||||
|
||||
before = test_epoch_ns();
|
||||
xce_core_set_wallclock_anchor(&core);
|
||||
result = xce_core_now(&core);
|
||||
after = test_epoch_ns();
|
||||
|
||||
TEST_ASSERT_TRUE(result >= before);
|
||||
TEST_ASSERT_TRUE(result <= after);
|
||||
}
|
||||
|
||||
static void test_xce_core_set_wallclock_anchor_null_core_is_a_safe_noop(void)
|
||||
{
|
||||
/* Mirrors xce_core_now(NULL)'s defensive contract -- no crash. */
|
||||
xce_core_set_wallclock_anchor(NULL);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* tlog format integration (Req 5 AC 3) */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
|
@ -451,6 +498,8 @@ int main(void)
|
|||
RUN_TEST(test_xce_core_now_fast_simulation_scales_up_by_speed);
|
||||
RUN_TEST(test_xce_core_now_slow_simulation_scales_down_by_speed);
|
||||
RUN_TEST(test_xce_sched_core_init_seeds_normal_mode_defaults);
|
||||
RUN_TEST(test_xce_core_set_wallclock_anchor_seeds_real_epoch_time);
|
||||
RUN_TEST(test_xce_core_set_wallclock_anchor_null_core_is_a_safe_noop);
|
||||
RUN_TEST(test_tlog_format_shows_frozen_virtual_time_not_infotime);
|
||||
RUN_TEST(test_tlog_format_frozen_time_is_stable_across_calls);
|
||||
RUN_TEST(test_tlog_format_falls_back_to_infotime_when_no_active_core);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue