Fix race condition crashes in Chart and Stack widgets#2944
Merged
exelban merged 1 commit intoexelban:masterfrom Feb 1, 2026
Merged
Fix race condition crashes in Chart and Stack widgets#2944exelban merged 1 commit intoexelban:masterfrom
exelban merged 1 commit intoexelban:masterfrom
Conversation
Ensure data mutations from background readers are dispatched to the main thread to prevent conflicts with drawing logic (which runs on main thread). This resolves SIGTRAP and SIGABRT crashes observed during extended runtime.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description:
This PR fixes multiple race conditions identified in StackWidget, NetworkChart, LineChart, and BarChart that were causing hard-to-reproduce crashes (SIGABRT and SIGTRAP) after extended runtimes (typically 1-3 days).
Issues
This issue always show up when 'Combined modules' is enabled.
The crashes stem from a classic Reader-Writer race condition between background module threads and the main UI thread.
SIGABRT in StackWidget (Memory Corruption):
Context: StackWidget maintains a values: [Stack_t] array. This array is passed as an UnsafeMutablePointer to its subview OrderTableView.
The Bug: The Sensors module (running on a background thread) updates the stack values via StackWidget.setValues. This method was mutating the values array directly on the background thread.
The Crash: If the background thread triggered a reallocation of the values array (e.g., during append or reassignment) while the Main Thread was simultaneously accessing it via the unsafe pointer in OrderTableView's drawing/delegate methods, the application would crash with a memory corruption error (swift_release_dealloc).
SIGTRAP in NetworkChart (Index Out of Bounds):
Context: NetworkChart maintains a points array for drawing the graph.
The Bug: The Net module (background thread) calls setValue(upload:download:), which was mutating (remove(at: 0) / append) the points array without any lock or thread affinity.
The Crash: The NetworkChart.draw(_:) method (Main Thread) iterates over this array to draw the paths. If the array is mutated by the background thread during this iteration, the bounds check fails (or the internal buffer is swapped out), triggering a SIGTRAP (assertion failure) for Index Out of Bounds.
Similar Patterns in LineChart and BarChart:
Identified similar unprotected mutations of self._value and other state variables (pressureLevel, colorZones) from background threads while they were being read/copied on the Main Thread for drawing.
The Fix
The fix ensures that all state mutations in these widgets are dispatched to the Main Thread, strictly serializing them with the drawing cycle.
StackWidget.swift: Wrapped setValues mutation logic in DispatchQueue.main.async. This ensures the array underlying the UnsafeMutablePointer is only touched by the Main Thread.
NetworkChart.swift
: Wrapped setValue array mutation in DispatchQueue.main.async.
LineChart.swift / BarChart.swift
: Wrapped setValue, setPressure, and configuration setters in
DispatchQueue.main.async.
Verification
Reproduction: Confirmed SIGABRT in Kit.StackWidget.setValues and SIGTRAP in Kit.NetworkChart.draw via custom signal handlers and stack trace logging during extended debugging sessions.
Stability Test: After applying the fixes, the application ran stable for 182+ hours (7.6 days) with zero crashes or issues, confirming the resolution.