Loop 3.15.2 (26) crashes with EXC_BREAKPOINT (SIGTRAP) in GlucoseStore.addGlucoseSamples(_:) when processing glucose samples containing an invalid timestamp from CGM plugin (CGMBLEKitG6Plugin).
Date._unconditionallyBridgeFromObjectiveC is called when bridging the Swift Date to NSDate for CoreData storage, triggering Swift trap and terminating the app during bulk glucose sample mapping on CoreData background queue.
Environment
- Device: iPhone16,2
- iOS: 18.7.8 (22H352)
- Loop version: 3.15.2 (26), TestFlight beta
- CGM: G6 via CGMBLEKitG6Plugin
- Pump: Omnipod via OmnipodKitPlugin
- Incident Identifier:
D37C3980-F614-4D9C-925E-465EB979B349
Crash Stack
Thread 9 Crashed:
0 Foundation 0x000000018b350894 static Date._unconditionallyBridgeFromObjectiveC(_:) + 52 (Date.swift:358)
1 LoopKit 0x0000000100d4b610 closure #3 in closure #1 in GlucoseStore.addGlucoseSamples(_:) + 8 (GlucoseStore.swift:324)
2 LoopKit 0x0000000100d4b610 specialized Collection.map<A, B>(_:) + 116 (/<compiler-generated>:0)
3 LoopKit 0x0000000100d4b610 closure #1 in GlucoseStore.addGlucoseSamples(_:) + 1416 (GlucoseStore.swift:324)
4 LoopKit 0x0000000100d5367c partial apply for closure #1 in GlucoseStore.addGlucoseSamples(_:) + 16 (/<compiler-generated>:0)
5 CoreData 0x00000001947b8150 closure #1 in closure #1 in NSManagedObjectContext._rethrowsHelper_perform_enqueued<A>(_:rescue:) + 372 (NSManagedObjectContext.swift:180)
Root Cause
NewGlucoseSample.startDate is defined as non-optional Swift Date, but the underlying CGM plugin can produce invalid Date values (.isInfinite / .isNaN).
When this invalid Date is bridged to NSDate for CoreData storage in CachedGlucoseObject.create(from:), it triggers Date._unconditionallyBridgeFromObjectiveC trap.
A single malformed sample crashes the entire batch ingestion and kills Loop.
Note: This is not a nil Swift Date. Swift enforces non-optional, but invalid time intervals create a Date that cannot bridge to ObjC NSDate.
Expected Behavior
Loop should skip individual malformed glucose samples with invalid timestamps, log the bad sample details (syncIdentifier), and continue processing remaining valid samples instead of hard crashing.
Actual Behavior
App terminates immediately with EXC_BREAKPOINT (SIGTRAP) when receiving a glucose sample with invalid timestamp.
Suggested Fix
Add validation before processing the batch: filter out samples with infinite / NaN startDate at the entry of addGlucoseSamples, emit error log for bad entries, and only proceed with valid samples.
The filter runs before duplicate checking and CoreData object creation, preventing invalid values from ever reaching NSDate bridging.
Proposed Patch
public func addGlucoseSamples(_ samples: [NewGlucoseSample], completion: @escaping (_ result: Result<[StoredGlucoseSample], Error>) -> Void) {
guard !samples.isEmpty else {
completion(.success([]))
return
}
queue.async {
var storedSamples: [StoredGlucoseSample] = []
var error: Error?
self.cacheStore.managedObjectContext.performAndWait {
do {
+ // Filter out samples with invalid startDate to prevent crash during NSDate bridging
+ let validSamples = samples.compactMap { sample -> NewGlucoseSample? in
+ guard !sample.startDate.isInfinite, !sample.startDate.isNaN else {
+ self.log.error("Dropping glucose sample due to invalid startDate. syncIdentifier: %{public}@", sample.syncIdentifier)
+ return nil
+ }
+ return sample
+ }
+
+ guard !validSamples.isEmpty else {
+ self.log.default("All glucose samples were invalid, nothing to save")
+ return
+ }
+
// Filter samples to ensure no duplicate sync identifiers nor existing sample with matching sync identifier for our provenance identifier
var syncIdentifiers = Set<String>()
- let samples: [NewGlucoseSample] = try samples.compactMap { sample in
+ let samples: [NewGlucoseSample] = try validSamples.compactMap { sample in
Loop 3.15.2 (26) crashes with
EXC_BREAKPOINT (SIGTRAP)inGlucoseStore.addGlucoseSamples(_:)when processing glucose samples containing an invalid timestamp from CGM plugin (CGMBLEKitG6Plugin).Date._unconditionallyBridgeFromObjectiveCis called when bridging the Swift Date to NSDate for CoreData storage, triggering Swift trap and terminating the app during bulk glucose sample mapping on CoreData background queue.Environment
D37C3980-F614-4D9C-925E-465EB979B349Crash Stack
Root Cause
NewGlucoseSample.startDateis defined as non-optional SwiftDate, but the underlying CGM plugin can produce invalid Date values (.isInfinite/.isNaN).When this invalid
Dateis bridged toNSDatefor CoreData storage inCachedGlucoseObject.create(from:), it triggersDate._unconditionallyBridgeFromObjectiveCtrap.A single malformed sample crashes the entire batch ingestion and kills Loop.
Expected Behavior
Loop should skip individual malformed glucose samples with invalid timestamps, log the bad sample details (syncIdentifier), and continue processing remaining valid samples instead of hard crashing.
Actual Behavior
App terminates immediately with
EXC_BREAKPOINT (SIGTRAP)when receiving a glucose sample with invalid timestamp.Suggested Fix
Add validation before processing the batch: filter out samples with infinite / NaN
startDateat the entry ofaddGlucoseSamples, emit error log for bad entries, and only proceed with valid samples.The filter runs before duplicate checking and CoreData object creation, preventing invalid values from ever reaching NSDate bridging.
Proposed Patch