fix(scheduler): the simulator's threads stop when its run returns (bug-1632, bug-1763)
sched_sim_driver_run() started the picker and allocator threads on &sim->core and returned with them still running; only sched_sim_driver_fini() stopped them, and 24 test files (35 call sites) run the driver on a stack-local sim without calling it. The leftover threads kept a pointer into the dead frame, and ASAN occasionally caught one reading it (stack-use-after-return in cbuf_get) in sched_sim_verify_test and sched_sim_record_output_test. sched_sim_driver_run() now wraps the loop and stops both threads on every return (new sched_sim_driver_stop_threads(), shared with fini). If the allocator fails to start, the running picker is stopped too. The stop no longer pushes a jobid 0 to wake the allocator: cbuf_get/put wait in pthread_cond_wait, a cancellation point, and the fake end-of-session was visible to the allocator. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
dc94da207a
commit
cfa0a94166
4 changed files with 101 additions and 18 deletions
|
|
@ -1579,6 +1579,46 @@ static void test_verify_against_self_reports_zero_mismatches(void)
|
|||
printf("test_verify_against_self_reports_zero_mismatches: PASS\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* bug-1632/bug-1763: sched_sim_driver_run() must not return with its picker
|
||||
* and allocator threads still running. Nearly every caller (this file's
|
||||
* run_sim_and_capture_stdout() among them) runs the driver on a stack-local
|
||||
* xce_sched_sim_driver_t and never calls sched_sim_driver_fini(); threads
|
||||
* left running kept a pointer into that dead frame, and ASAN caught one
|
||||
* reading it (stack-use-after-return in cbuf_get).
|
||||
*/
|
||||
static void test_run_returns_with_its_threads_stopped(void)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
FILE* f;
|
||||
sched_sim_args_t args;
|
||||
xce_sched_sim_driver_t sim;
|
||||
int rc;
|
||||
|
||||
f = write_header_and_snapshot(path, sizeof(path), "_threads");
|
||||
TEST_ASSERT_NOT_NULL(f);
|
||||
|
||||
append_queue_update_event(f, 1000ULL, "normal");
|
||||
append_jobs_push_event(f, 1500ULL, 777ULL, "normal");
|
||||
append_replay_session_with_pend(f, 2000ULL, 777ULL, 0);
|
||||
append_end_of_stream_marker(f);
|
||||
fclose(f);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.replay_path = path;
|
||||
args.sim_start_ts = SCHED_SIM_START_TS_LATEST;
|
||||
|
||||
rc = sched_sim_driver_run(&sim, &args);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(0, rc);
|
||||
TEST_ASSERT_FALSE_MESSAGE(sim.allocator_thread_live,
|
||||
"bug-1632: sched_sim_driver_run() returned with its picker and "
|
||||
"allocator threads still running");
|
||||
|
||||
sched_sim_driver_fini(&sim);
|
||||
printf("test_run_returns_with_its_threads_stopped: PASS\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Observable (b): replaying against a deliberately-altered copy (recorded
|
||||
* main_reason flipped to 99, which the real picker thread can never
|
||||
|
|
@ -2005,6 +2045,7 @@ int main(void)
|
|||
test_verify_with_multiple_already_resolved_jobs_across_rounds_reports_no_mismatch);
|
||||
RUN_TEST(
|
||||
test_reconciliation_no_longer_masks_a_pend_jobs_dispatch_mismatch);
|
||||
RUN_TEST(test_run_returns_with_its_threads_stopped);
|
||||
|
||||
return UNITY_END();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue