background
Recently, background statistics found a random Crash, which attracted our attention.
From the operating system point of view, they are all iOS 16+ systems.
The crash stack is as follows:
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x00000001daa1808c
Termination Reason: SIGNAL 5 Trace/BPT trap: 5
Terminating Process: exc handler [44398]
Triggered by Thread: 0
Kernel Triage:
VM - pmap_enter retried due to resource shortage
VM - pmap_enter retried due to resource shortage
VM - pmap_enter retried due to resource shortage
VM - pmap_enter retried due to resource shortage
VM - pmap_enter retried due to resource shortage
Thread 0 name:
Thread 0 Crashed:
0 libsystem_platform.dylib 0x00000001daa1808c _os_unfair_lock_recursive_abort + 36 (lock.c:508)
1 libsystem_platform.dylib 0x00000001daa12898 _os_unfair_lock_lock_slow + 280 (lock.c:567)
2 libobjc.A.dylib 0x00000001859e28d4 objc_object::rootRetain_overflow(bool) + 112 (objc-object.h:684)
3 CoreFoundation 0x000000018c83d114 -[__NSDictionaryM __setObject:forKey:] + 352 (NSCollectionAux.h:40)
4 CoreFoundation 0x000000018c83b0e4 -[__NSFrozenDictionaryM __apply:context:] + 128 (NSDictionaryM_Common.h:247)
5 CoreFoundation 0x000000018c86bd60 -[CFPrefsSource mergeIntoDictionary:sourceDictionary:cloudKeyEvaluator:] + 168 (CFPrefsSource.m:965)
6 CoreFoundation 0x000000018c86bbc0 -[CFPrefsSearchListSource alreadylocked_getDictionary:] + 744 (CFPrefsSearchListSource.m:1243)
7 CoreFoundation 0x000000018c843394 -[CFPrefsSearchListSource alreadylocked_copyValueForKey:] + 172 (CFPrefsSearchListSource.m:639)
8 CoreFoundation 0x000000018c8432c8 -[CFPrefsSource copyValueForKey:] + 52 (CFPrefsSource.m:894)
9 CoreFoundation 0x000000018c84327c __76-[_CFXPreferences copyAppValueForKey:identifier:container:configurationURL:]_block_invoke + 32 (CFXPreferences.m:1085)
10 CoreFoundation 0x000000018c8c3ca4 __108-[_CFXPreferences(SearchListAdditions) withSearchListForIdentifier:container:cloudConfigurationURL:perform:]_block_invoke + 392 (CFPrefsSearchListSource.m:1767)
11 CoreFoundation 0x000000018c8af878 normalizeQuintuplet + 356 (CFPrefsSearchListSource.m:74)
12 CoreFoundation 0x000000018c8ac124 -[_CFXPreferences withSearchListForIdentifier:container:cloudConfigurationURL:perform:] + 152 (CFPrefsSearchListSource.m:1639)
13 CoreFoundation 0x000000018c852d5c -[_CFXPreferences copyAppValueForKey:identifier:container:configurationURL:] + 168 (CFXPreferences.m:1081)
14 CoreFoundation 0x000000018c852bb4 _CFPreferencesCopyAppValueWithContainerAndConfiguration + 112 (CFXPreferences.m:2160)
15 Foundation 0x0000000186ba586c -[NSUserDefaults(NSUserDefaults) objectForKey:] + 60 (NSUserDefaults.m:224)
16 CsdnPlus 0x0000000104c1f5ac 0x102ec0000 + 30799276
17 CsdnPlus 0x0000000104c842ac 0x102ec0000 + 31212204
18 CsdnPlus 0x0000000104c7c920 0x102ec0000 + 31181088
19 CsdnPlus 0x0000000104c783c4 0x102ec0000 + 31163332
20 CsdnPlus 0x0000000104c7bdcc 0x102ec0000 + 31178188
21 CsdnPlus 0x0000000104c79db0 0x102ec0000 + 31169968
22 libsystem_platform.dylib 0x00000001daa13a90 _sigtramp + 56 (sigtramp.c:116)
23 libsystem_kernel.dylib 0x00000001ca375bf0 abort_with_payload_wrapper_internal + 104 (terminate_with_reason.c:102)
24 libsystem_kernel.dylib 0x00000001ca375b88 abort_with_reason + 32 (terminate_with_reason.c:116)
25 libobjc.A.dylib 0x00000001859e3a5c _objc_fatalv(unsigned long long, unsigned long long, char const*, char*) + 116 (objc-errors.mm:199)
26 libobjc.A.dylib 0x00000001859e39e8 _objc_fatal(char const*, ...) + 32 (objc-errors.mm:215)
27 libobjc.A.dylib 0x00000001859b6c24 weak_register_no_lock + 392 (objc-weak.mm:421)
28 libobjc.A.dylib 0x00000001859bb88c objc_storeWeak + 484 (NSObject.mm:365)
29 UIKitCore 0x000000018eb1af2c _UIResponderForwarderWantsForwardingFromResponder + 736 (UITouch.m:185)
30 UIKitCore 0x000000018ea307dc __forwardTouchMethod_block_invoke + 44 (UIResponder.m:2168)
31 CoreFoundation 0x000000018c8313cc __NSSET_IS_CALLING_OUT_TO_A_BLOCK__ + 24 (NSSetHelpers.m:10)
32 CoreFoundation 0x000000018c8b2264 -[__NSSetM enumerateObjectsWithOptions:usingBlock:] + 200 (NSSetM_Common.h:157)
33 UIKitCore 0x000000018ebfddcc forwardTouchMethod + 236 (UIResponder.m:2167)
34 UIKitCore 0x000000018eaf81b0 -[UIWindow _sendTouchesForEvent:] + 356 (UIWindow.m:3160)
35 UIKitCore 0x000000018eaf7770 -[UIWindow sendEvent:] + 3284 (UIWindow.m:3481)
36 UIKitCore 0x000000018eaf6a20 -[UIApplication sendEvent:] + 676 (UIApplication.m:12635)
37 UIKitCore 0x000000018eaf60d8 __dispatchPreprocessedEventFromEventQueue + 7084 (UIEventDispatcher.m:2417)
38 UIKitCore 0x000000018eb3de00 __processEventQueue + 5632 (UIEventDispatcher.m:2726)
39 UIKitCore 0x000000018f79b820 updateCycleEntry + 168 (UIEventDispatcher.m:117)
40 UIKitCore 0x000000018f04e5b0 _UIUpdateSequenceRun + 84 (_UIUpdateSequence.mm:112)
41 UIKitCore 0x000000018f69d310 schedulerStepScheduledMainSection + 172 (_UIUpdateScheduler.m:987)
42 UIKitCore 0x000000018f69c4dc runloopSourceCallback + 92 (_UIUpdateScheduler.m:1079)
43 CoreFoundation 0x000000018c8fcf24 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 (CFRunLoop.c:1957)
44 CoreFoundation 0x000000018c9092fc __CFRunLoopDoSource0 + 176 (CFRunLoop.c:2001)
45 CoreFoundation 0x000000018c88d1c0 __CFRunLoopDoSources0 + 244 (CFRunLoop.c:2038)
46 CoreFoundation 0x000000018c8a2b7c __CFRunLoopRun + 836 (CFRunLoop.c:2953)
47 CoreFoundation 0x000000018c8a7eb0 CFRunLoopRunSpecific + 612 (CFRunLoop.c:3418)
48 GraphicsServices 0x00000001c6a9d368 GSEventRunModal + 164 (GSEvent.c:2196)
49 UIKitCore 0x000000018ed9d668 -[UIApplication _run] + 888 (UIApplication.m:3758)
50 UIKitCore 0x000000018ed9d2cc UIApplicationMain + 340 (UIApplication.m:5348)
51 CsdnPlus 0x0000000103650e04 0x102ec0000 + 7933444
52 dyld 0x00000001ab1a0960 start + 2528 (dyldMain.cpp:1170)
analyze
stack
Through the crash stack, we can analyze that it is a systemic Crash, and then we locate it objc-weak.mm:421
. After checking the source code, we find that the Crash should be caused by a transitional release problem.
behavior trajectory
From the crash stack, we can see that it is caused by the system's transitional release problem, so we need to find the user's specific behavior. to continue the analysis.
Through user behavior trajectory analysis, it was found that all crash users crashed when they clicked on the search box. It is speculated that it is related to the keyboard input.
Find a case
Because it is a systemic crash, we firmly believe that someone must have encountered the same problem. Sure enough, I found a reproduction method on Apple's official developer forum.
Through this method test, the problem can indeed be reproduced 100%.
After debugging, the console output is as follows:
solution
In the forum, some experts have already given solutions . Just drag UIWindow+FixCrashOnInputKeyboard.h/m
into the project.
Through experiments, the problem was indeed solved.
code show as below:
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = objc_getClass("UIWindow");
SEL originalSelector = @selector(sendEvent:);
SEL swizzledSelector = @selector(sendEventEx:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
method_exchangeImplementations(originalMethod, swizzledMethod);
});
}
- (void)sendEventEx:(UIEvent *)event {
if ([UIWindow isSendEventToDealloctingObject:event]) {
return;
}
[self sendEventEx: event];
}
#pragma mark - check if sending Event to deallocating object
+ (BOOL) isSendEventToDealloctingObject:(UIEvent *)event {
if (event.type == UIEventTypeTouches) {
for (UITouch *touch in event.allTouches) {
NSString *windowName = NSStringFromClass([touch.window class]);
if ([windowName isEqualToString:@"UIRemoteKeyboardWindow"]) {
UIView* view = touch.view;
UIResponder *arg2 = view.nextResponder;
NSString* responderClassName = NSStringFromClass([arg2 class]);
if ([responderClassName isEqualToString:@"_UIRemoteInputViewController"]) {
bool isDeallocating = false;
// Use 'performSelector' when u are develop a App-Store App.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
SEL sel = NSSelectorFromString(@"_isDeallocating");
isDeallocating = [arg2 respondsToSelector:sel] && [arg2 performSelector:sel];
#pragma clang diagnostic pop
if (isDeallocating) {
NSLog(@"UIWindow - BingGo a deallocating object ...");
return true;
}
}
}
}
}
return false;
}