Skip to content

v0.9.5

Latest

Choose a tag to compare

@sarsko sarsko released this 01 Oct 19:13
· 9 commits to main since this release
401f607
  • Fix a process abort when a Drop handler touches a modelled Mutex, RwLock or semaphore outside a running task. Every BatchSemaphore operation looks up the running task's vector clock, and current::clock() panicked when there was no running task, when ExecutionState was already borrowed, or outside a Shuttle execution. The first case is reached whenever ExecutionState::cleanup force-unwinds a task that was still parked when the execution ended, for example after an ordinary test failure. The panic came from a destructor, so the process aborted, and the failure report and persisted schedule were lost with it. current::clock() now returns an empty clock in all three cases: an operation that belongs to no task has no causality to record. (#357)

  • Fix spans leaking on the thread's entered-span stack while any thread in the process holds a scoped default subscriber, such as one installed with tracing::subscriber::set_default by a concurrently running test. Shuttle exited a task's spans by calling Span::current() inside tracing::dispatcher::get_default, where it returns Span::none() while a scoped default exists anywhere in the process, so it exited nothing but still entered the execution's span. Every scheduling step leaked one entry and every Runner::run another: a span entered before a context switch was no longer current after it, and once the leaked spans had closed, a later Span::current() panicked with tried to clone a span (Id(..)) that already closed. Spans are now exited and entered through Span::with_subscriber. (#359)

  • A task's default tracing dispatcher is now saved and restored across context switches, like its span stack. The default dispatcher is per OS thread and every task runs on the same one, so a task that yielded inside tracing::dispatcher::with_default left its dispatcher installed while the scheduler and every other task ran: their events went to that dispatcher instead of the test's subscriber, and the task's spans stayed entered, so later events were attributed to the wrong task. If the execution was stopped or panicked while such a task was switched out, the task's default stayed installed after the execution ended too. Shuttle only parks a task's default when it may differ from the execution's, so runs without a scoped default subscriber skip it. (#359)

  • Deadlock reports now print blocked tasks' backtraces (captured when SHUTTLE_CAPTURE_BACKTRACE is set) with Display, in the numbered layout panics use under RUST_BACKTRACE=1, instead of with {:#?}, which printed one Debug record per frame wrapped in Some(Backtrace [ .. ]). A task without a captured backtrace prints <not captured>. Output without SHUTTLE_CAPTURE_BACKTRACE is unchanged. (#360)

  • Publish shuttle-engine 0.1.3, which has all of the changes above. shuttle-std and shuttle-schedulers are unchanged at 0.1.2 and 0.1.1; they take shuttle-engine as ^0.1.2 and ^0.1.1, so they build against 0.1.3 as they stand. shuttle's own source is unchanged too; it now requires shuttle-engine 0.1.3, so that upgrading to 0.9.5 brings the fixes with it.