fondo
Recientemente, las estadísticas en segundo plano encontraron un bloqueo aleatorio que atrajo nuestra atención.
Desde el punto de vista del sistema operativo, todos son sistemas iOS 16+.
La pila de bloqueos es la siguiente:
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)
analizar
pila
A través de la pila de fallos podemos analizar que se trata de un fallo sistémico y luego lo localizamos. objc-weak.mm:421
Después de verificar el código fuente, encontramos que el fallo debería ser causado por un problema de lanzamiento de transición.
trayectoria de comportamiento
Desde la pila de fallos, podemos ver que se debe al problema de lanzamiento de transición del sistema, por lo que necesitamos encontrar el comportamiento específico del usuario. para continuar el análisis.
A través del análisis de la trayectoria del comportamiento del usuario, se encontró que todos los usuarios fallaron cuando hicieron clic en el cuadro de búsqueda, se especula que está relacionado con la entrada del teclado.
encontrar un caso
Debido a que se trata de una caída sistémica, creemos firmemente que alguien debe haber encontrado el mismo problema. Efectivamente, encontré un método de reproducción en el foro oficial de desarrolladores de Apple.
A través de este método de prueba, el problema se puede reproducir al 100%.
Después de la depuración, la salida de la consola es la siguiente:
solución
En el foro algunos expertos ya han dado soluciones . Simplemente arrástrelo UIWindow+FixCrashOnInputKeyboard.h/m
al proyecto.
A través de experimentos, el problema se resolvió.
El código se muestra a continuación:
+ (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;
}