App crashes of type EXC_BREAKPOINT (SIGTRAP) SIGNAL 5 Trace/BPT trap on iOS17

In the iOS app I'm developing, I've noticed that since upgrading to iOS 17 (Xcode 15.1), crashes of this type occur frequently. The crashes are random and can't be reliably reproduced. Below is a typical crash report:

CrashReporter Key:   fd24cf14a51d73ebfc1852cccb1b8d50822b247c
Hardware Model:      iPhone11,2
Process:             MyApp [89057]
Path:                /private/var/containers/Bundle/Application/06B982E0-B818-48A9-B2D1-F28999EC3BC0/MyApp.app/MyApp
Identifier:          com.company.MyApp
Version:             2.0.0 (72)
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]
Coalition:           com.company.MyApp [4659]

Date/Time:           2024-03-24 14:50:46.3982 +0800
Launch Time:         2024-03-24 14:38:38.1438 +0800
OS Version:          iPhone OS 17.3.1 (21D61)
Release Type:        User
Baseband Version:    6.00.00
Report Version:      104

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x000000018c44e838
Termination Reason: SIGNAL 5 Trace/BPT trap: 5
Terminating Process: exc handler [89057]

Triggered by Thread:  0

Kernel Triage:
VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter
VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter
VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter
VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter
VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter


Thread 0 name:   Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libobjc.A.dylib               	       0x18c44e838 object_getClass + 48
1   Foundation                    	       0x1930807b4 _NSKeyValueObservationInfoGetObservances + 264
2   Foundation                    	       0x19307fc7c NSKeyValueWillChangeWithPerThreadPendingNotifications + 232
3   QuartzCore                    	       0x19572f14c CAAnimation_setter(CAAnimation*, unsigned int, _CAValueType, void const*) + 128
4   QuartzCore                    	       0x19574a6b4 -[CAAnimation setBeginTime:] + 52
5   QuartzCore                    	       0x1957485b4 CA::Layer::commit_animations(CA::Transaction*, double (*)(CA::Layer*, double, void*), void (*)(CA::Layer*, CA::Render::Animation*, void*), void (*)(CA::Layer*, __CFString const*, void*), CA::Render::TimingList* (*)(CA::Layer*, void*), void*) + 740
6   QuartzCore                    	       0x195700bf0 invocation function for block in CA::Context::commit_transaction(CA::Transaction*, double, double*) + 148
7   QuartzCore                    	       0x195700af8 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 368
8-14QuartzCore                    	       0x195700a84 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 252
15  QuartzCore                    	       0x195745248 CA::Context::commit_transaction(CA::Transaction*, double, double*) + 11192
16  QuartzCore                    	       0x19573bb80 CA::Transaction::commit() + 648
17  QuartzCore                    	       0x19573b828 CA::Transaction::flush_as_runloop_observer(bool) + 88
18  CoreFoundation                	       0x1940ff7bc __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 36
19  CoreFoundation                	       0x1940fe1c4 __CFRunLoopDoObservers + 548
20  CoreFoundation                	       0x1940fd8e0 __CFRunLoopRun + 1028
21  CoreFoundation                	       0x1940fd3f8 CFRunLoopRunSpecific + 608
22  GraphicsServices              	       0x1d768b4f8 GSEventRunModal + 164
23  UIKitCore                     	       0x1965238a0 -[UIApplication _run] + 888
24  UIKitCore                     	       0x196522edc UIApplicationMain + 340
25  MyApp                         	       0x102c1f014 main + 140
26  dyld                          	       0x1b6e52dcc start + 2240

By looking up information on the Exception Type and Termination Reason, I found that Apple officially mentions that EXC_BREAKPOINT (SIGTRAP) SIGNAL 5 Trace/BPT trap: 5 could be caused by Swift runtime error crashing mechanisms, mainly due to:

If you use the ! operator to force unwrap an optional value that’s nil, or if you force a type downcast that fails with the as! operator, the Swift runtime catches these errors and intentionally crashes the app.

For details, see the link: https://developer.apple.com/documentation/xcode/addressing-crashes-from-swift-runtime-errors

My project is a mix of Objc+Swift compilation, the crash usually occurs after a button click triggers a change in UIView properties, mostly related to layout. All Swift code in the project is unrelated to this type of UI. So, I speculate that it might not be related to Swift runtime errors, but I'm unsure what other possible causes could lead to the aforementioned crash.

A common denominator in all similar crash reports is that they occur on the main thread during system framework function calls,

All show multiple instances of

VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter

CA::Layer::commit_if_needed is always invoked. I noticed many crashes relate to CALayer setting properties internally calling CAAnimation, so I added:

@implementation CALayer (Animation)
/// Prevent crashes
+ (void)disableAnimation:(VoidBlock)block{
    [CATransaction begin];
    [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
    block();
    [CATransaction commit];
}
@end

Using [CALayer disableAnimation:^{view.layer.someProperty = someValue;}] to disable animations has prevented some crashes, but I'm powerless in situations like the stack trace above, where all calls are made by system frameworks.

I've also noticed other similar crash issues on forums: EXC_BREAKPOINT - libobjc.A.dylib object_getClass Crash on the main thread. The author experienced this issue after iOS 16 and iOS 17, with very similar stack information to mine.

I suspect other potential causes might include:

  • Whether it's related to KVO in UI code not being correctly released.

  • Whether it involves calls to GPU resources from other threads. I've rewritten most of the code to ensure no GPU-related image operations occur on other threads during CoreAnimation runtime.

  • Whether it's related to high memory usage and peak virtual memory. My app is related to image processing, and opening 4K photos for processing typically consumes more than 500MB of memory.

If you've encountered similar situations or can help identify potential causes, please advise. Many thanks!

Replies

Below are parts of similar crash reports with slightly different stack traces:

0   libobjc.A.dylib               	       0x18c44e838 object_getClass + 48
1   Foundation                    	       0x1930807b4 _NSKeyValueObservationInfoGetObservances + 264
2   Foundation                    	       0x19307fc7c NSKeyValueWillChangeWithPerThreadPendingNotifications + 232
3   QuartzCore                    	       0x19572f14c CAAnimation_setter(CAAnimation*, unsigned int, _CAValueType, void const*) + 128
4   QuartzCore                    	       0x19572f0a4 -[CAPropertyAnimation setKeyPath:] + 52
5   UIKitCore                     	       0x1963e8fc8 -[UIImageView startAnimating] + 684
6   UIKitCore                     	       0x1963e8ce4 -[UIActivityIndicatorView layoutSubviews] + 1128
7   UIKitCore                     	       0x196329c04 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1528
8   QuartzCore                    	       0x19573c7ec CA::Layer::layout_if_needed(CA::Transaction*) + 500
9   QuartzCore                    	       0x19573c374 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 144
10  QuartzCore                    	       0x195742860 CA::Context::commit_transaction(CA::Transaction*, double, double*) + 464
11  QuartzCore                    	       0x19573bb80 CA::Transaction::commit() + 648
12  QuartzCore                    	       0x19573b828 CA::Transaction::flush_as_runloop_observer(bool) + 88
13  CoreFoundation                	       0x1940ff7bc __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 36
14  CoreFoundation                	       0x1940fe1c4 __CFRunLoopDoObservers + 548
15  CoreFoundation                	       0x1940fd8e0 __CFRunLoopRun + 1028
16  CoreFoundation                	       0x1940fd3f8 CFRunLoopRunSpecific + 608
17  GraphicsServices              	       0x1d768b4f8 GSEventRunModal + 164
18  UIKitCore                     	       0x1965238a0 -[UIApplication _run] + 888
19  UIKitCore                     	       0x196522edc UIApplicationMain + 340
20  MyApp                         	       0x1048431b0 main + 140
21  dyld                          	       0x1b6e52dcc start + 2240

Thread 0 Crashed:
0   libobjc.A.dylib               	       0x18c44e838 object_getClass + 48
1   Foundation                    	       0x1930807b4 _NSKeyValueObservationInfoGetObservances + 264
2   Foundation                    	       0x19307fc7c NSKeyValueWillChangeWithPerThreadPendingNotifications + 232
3   QuartzCore                    	       0x19572f14c CAAnimation_setter(CAAnimation*, unsigned int, _CAValueType, void const*) + 128
4   QuartzCore                    	       0x195780354 -[CABasicAnimation setFromValue:] + 52
5   QuartzCore                    	       0x195780200 CALayerCreateImplicitAnimation + 276
6   QuartzCore                    	       0x195715f20 -[CALayer actionForKey:] + 420
7   QuartzCore                    	       0x195715c84 CA::Layer::begin_change(CA::Transaction*, unsigned int, objc_object*, objc_object*&) + 204
8   QuartzCore                    	       0x195716984 CA::Layer::setter(unsigned int, _CAValueType, void const*) + 792
9   QuartzCore                    	       0x195716644 -[CALayer setOpacity:] + 56
10  MyApp                         	       0x100972ae4 -[CALayer(Visbility) setSimHidden:] + 200

Thread 0 Crashed:
0   libobjc.A.dylib               	       0x18c44e838 object_getClass + 48
1   Foundation                    	       0x1930807b4 _NSKeyValueObservationInfoGetObservances + 264
2   Foundation                    	       0x19307fc7c NSKeyValueWillChangeWithPerThreadPendingNotifications + 232
3   QuartzCore                    	       0x19572f14c CAAnimation_setter(CAAnimation*, unsigned int, _CAValueType, void const*) + 128
4   QuartzCore                    	       0x19572f0a4 -[CAPropertyAnimation setKeyPath:] + 52
5   QuartzCore                    	       0x19572f050 +[CAPropertyAnimation animationWithKeyPath:] + 36
6   UIKitCore                     	       0x196448c8c __67-[_UIViewAdditiveAnimationAction runActionForKey:object:arguments:]_block_invoke_2 + 384
7   UIKitCore                     	       0x196448a3c -[_UIViewAdditiveAnimationAction runActionForKey:object:arguments:] + 1968
8   QuartzCore                    	       0x195704dec CA::Layer::set_bounds(CA::Rect const&, bool) + 436
9   QuartzCore                    	       0x195704c0c -[CALayer setBounds:] + 132
10  QuartzCore                    	       0x1957048ac -[CALayer setFrame:] + 416
11  UIKitCore                     	       0x1963102fc -[UIView _backing_setFrame:] + 240
12  UIKitCore                     	       0x19630e7e8 -[UIView(Geometry) setFrame:] + 296
13  UIKitCore                     	       0x19630fa38 -[UIImageView _setViewGeometry:forMetric:] + 160
14  UIKitCore                     	       0x196367104 -[UIButtonLegacyVisualProvider layoutSubviews] + 108
15  UIKitCore                     	       0x196367058 -[UIButton layoutSubviews] + 40
16  UIKitCore                     	       0x196329c04 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1528
17  QuartzCore                    	       0x19573c7ec CA::Layer::layout_if_needed(CA::Transaction*) + 500
18  UIKitCore                     	       0x19632ccb4 -[UIView(Hierarchy) layoutBelowIfNeeded] + 296
19  MyApp                         	       0x10465973c __74-[KKAssetBrowseCollectionViewController willOpenAssetThumbnailCompletion:]_block_invoke + 328

The crash location likely indicates some kind of corruption has occurred – object_getClass() mostly does memory fetches from the start of the object, so if the object is corrupted, or the pointer passed to it is bad, then it is likely to crash. But unfortunately beyond that I'm not sure what might be causing this. Not animating things is only hiding the issue (as you likely have surmised).

  • I want to know what changes typically trigger the invocation of NSKeyValueWillChangeWithPerThreadPendingNotifications in CAAnimation_setter, and whether changes to the object make object_getClass ineffective.

Add a Comment