Chr*_*eat 5 crash backtrace ios swift
我在以下回溯中遇到了很多崩溃,但我找不到原因。
根据 Apple -[NSObject(NSObject)doesNotRecognizeSelector:]当一个新对象被分配到先前被释放的对象占用的内存中时发生。
注意:向先前释放的对象发送消息可能会引发 NSInvalidArgumentException 而不是由于内存访问冲突而导致程序崩溃。当在先前被释放的对象占用的内存中分配新对象时,就会发生这种情况。如果您的应用程序由于未捕获的 NSInvalidArgumentException(在异常回溯中查找 -[NSObject(NSObject) doesNotRecognizeSelector:])而崩溃,请考虑使用 Zombies 工具分析您的应用程序以消除不正确的内存管理是原因的可能性。
https://developer.apple.com/library/archive/technotes/tn2151/_index.html
但是回溯的其余部分是怎么回事,尤其是-[UIUndoGestureInteraction didMoveToView:]事情?
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0
Last Exception Backtrace:
0 CoreFoundation 0x1ae45498c __exceptionPreprocess + 220 (NSException.m:199)
1 libobjc.A.dylib 0x1ae17d0a4 objc_exception_throw + 56 (objc-exception.mm:565)
2 CoreFoundation 0x1ae35843c -[NSObject(NSObject) doesNotRecognizeSelector:] + 140 (NSObject.m:144)
3 UIKitCore 0x1b24902a8 -[UIResponder doesNotRecognizeSelector:] + 296 (UIResponder.m:659)
4 CoreFoundation 0x1ae458e08 ___forwarding___ + 1324 (NSForwarding.m:3325)
5 CoreFoundation 0x1ae45abec _CF_forwarding_prep_0 + 92
6 UIKitCore 0x1b2353040 -[UIUndoGestureInteraction didMoveToView:] + 108 (UIUndoGestureInteraction.m:725)
7 UIKitCore 0x1b28eb3c4 _setInteractionView + 84 (UIView.m:16421)
8 UIKitCore 0x1b28eb2a0 -[UIView(Dragging) addInteraction:] + 268 (UIView.m:16450)
9 UIKitCore 0x1b26cd2b8 -[UIEditingOverlayViewController _addInteractions] + 260 (UIEditingOverlayViewController.m:79)
10 UIKitCore 0x1b1e5b2ec -[UIViewController _setViewAppearState:isAnimating:] + 832 (UIViewController.m:4695)
11 UIKitCore 0x1b1e5b6fc __52-[UIViewController _setViewAppearState:isAnimating:]_block_invoke + 268 (UIViewController.m:4758)
12 CoreFoundation 0x1ae42773c __NSARRAY_IS_CALLING_OUT_TO_A_BLOCK__ + 16 (NSArrayHelpers.m:9)
13 CoreFoundation 0x1ae32b86c -[__NSArrayI enumerateObjectsWithOptions:usingBlock:] + 152 (NSArrayI.m:108)
14 UIKitCore 0x1b1e5b49c -[UIViewController _setViewAppearState:isAnimating:] + 1264 (UIViewController.m:4736)
15 UIKitCore 0x1b1e5d530 __64-[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:]_block_invoke + 44 (UIViewController.m:5272)
16 UIKitCore 0x1b1e5c32c -[UIViewController _executeAfterAppearanceBlock] + 88 (UIViewController.m:5050)
17 UIKitCore 0x1b246bca4 _runAfterCACommitDeferredBlocks + 584 (UIApplication.m:3027)
18 UIKitCore 0x1b245b7c0 _cleanUpAfterCAFlushAndRunDeferredBlocks + 232 (UIApplication.m:2986)
19 UIKitCore 0x1b248b594 _afterCACommitHandler + 76 (UIApplication.m:3048)
20 CoreFoundation 0x1ae3d1c48 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32 (CFRunLoop.c:1758)
21 CoreFoundation 0x1ae3ccb34 __CFRunLoopDoObservers + 416 (CFRunLoop.c:1868)
22 CoreFoundation 0x1ae3cd100 __CFRunLoopRun + 1308 (CFRunLoop.c:2910)
23 CoreFoundation 0x1ae3cc8bc CFRunLoopRunSpecific + 464 (CFRunLoop.c:3192)
24 GraphicsServices 0x1b8238328 GSEventRunModal + 104 (GSEvent.c:2246)
25 UIKitCore 0x1b24626d4 UIApplicationMain + 1936 (UIApplication.m:4753)
26 JustConnect 0x10425ca60 main + 68 (APIInfoUser.swift:7)
27 libdyld.dylib 0x1ae257460 start + 4
Run Code Online (Sandbox Code Playgroud)
以下是 Apple 开发人员和技术支持人员的回复:
\n\n\n\n\n这里要注意的关键是,此回溯的第 0 帧到第 5 帧只是与无法识别的选择器关联的样板。也就是说,第 6 帧调用了对象上的方法,该对象无法识别该选择器,因此它进入了 Objective-C\n 运行时转发基础结构(第 5 帧到第 4 帧)。它落在 UIResponder 中(第 3 帧),因为 UIResponder 支持某种通用消息转发。该消息转发失败,因此 UIResponder 调用 super(第 2 帧),然后抛出异常。
\n\n所以真正的问题是,第 6 帧中\xe2\x80\x99 发生了什么。要了解更多\n 相关信息,您可以反汇编代码(-:
\n\nRun Code Online (Sandbox Code Playgroud)\n\n(lldb) disas -n \'-[UIUndoGestureInteraction didMoveToView:]\' \nUIKitCore`-[UIUndoGestureInteraction didMoveToView:]: \n 0x1bbe92fd4 <+0>: stp x22, x21, [sp, #-0x30]! \n 0x1bbe92fd8 <+4>: stp x20, x19, [sp, #0x10] \n 0x1bbe92fdc <+8>: stp x29, x30, [sp, #0x20] \n 0x1bbe92fe0 <+12>: add x29, sp, #0x20 ; =0x20 \n 0x1bbe92fe4 <+16>: mov x21, x2 \n 0x1bbe92fe8 <+20>: mov x19, x0 \n 0x1bbe92fec <+24>: add x20, x0, #0x10 ; =0x10 \n 0x1bbe92ff0 <+28>: mov x0, x20 \n 0x1bbe92ff4 <+32>: mov x1, x2 \n 0x1bbe92ff8 <+36>: bl 0x1b7cd71d8 ; objc_storeWeak \n 0x1bbe92ffc <+40>: cbz x21, 0x1bbe930a8 ; <+212> \n 0x1bbe93000 <+44>: adrp x8, 208464 \n 0x1bbe93004 <+48>: add x1, x8, #0x7b1 ; =0x7b1 \n 0x1bbe93008 <+52>: mov x0, x19 \n 0x1bbe9300c <+56>: bl 0x1b7cb9180 ; objc_msgSend \n 0x1bbe93010 <+60>: mov x0, x20 \n 0x1bbe93014 <+64>: bl 0x1b7cd7a80 ; objc_loadWeakRetained \n 0x1bbe93018 <+68>: mov x20, x0 \n 0x1bbe9301c <+72>: adrp x8, 208304 \n 0x1bbe93020 <+76>: add x1, x8, #0xc04 ; =0xc04 \n 0x1bbe93024 <+80>: bl 0x1b7cb9180 ; objc_msgSend \n 0x1bbe93028 <+84>: mov x29, x29 \n 0x1bbe9302c <+88>: bl 0x1b7cd8864 ; objc_retainAutoreleasedReturnValue \n 0x1bbe93030 <+92>: mov x21, x0 \n 0x1bbe93034 <+96>: adrp x8, 208502 \n 0x1bbe93038 <+100>: add x1, x8, #0xbb7 ; =0xbb7 \n 0x1bbe9303c <+104>: bl 0x1b7cb9180 ; objc_msgSend \n 0x1bbe93040 <+108>: stp d0, d1, [x19, #0x100] \n你可以在这里学到很多东西。首先,回溯中的第 6 帧的偏移量为 +108,因此失败的实际调用位于 +104。objc_msgSend 有两个标准参数:目标对象和选择器。在 64 位 Arm 上,这些分别映射到 x0 和 x1。
\n\n让\xe2\x80\x99s先看一下选择器。这是由 +96 和 +100 处的两条\n 指令构造的。这两条指令构成了 PC 相对地址。adrp指令(\xe2\x80\x98add相对于page\xe2\x80\x99)\n取当前PC(0x1bbe93034),清除底部12位\n(0x1bbe93000,记住历史页面大小是4096[1 ]),然后\n 获取文字,将其左移 12 位 (208502 << 12),\n 然后将其添加进去。add 指令要简单得多。它采用之前计算的结果并加上 0xbb7(注意从十进制到十六进制的切换!)。
\n\n如果您在调试器中运行此计算,您\xe2\x80\x99将看到以下内容:
\n\nRun Code Online (Sandbox Code Playgroud)\n\n(lldb) p (char*)( 0x1bbe93000+(208502<<12)+0xbb7) \n(char *) $1 = 0x00000001eed09bb7 "actualSceneBounds" \n所以选择器是actualSceneBounds。凉爽的。
\n\n现在让\xe2\x80\x99s 看看这个物体。在调用时 (+104),预计该值位于 x0 中。在 +92 处,我们看到它将 x0 复制到 x21,但这只是一种干扰。实际上 x0 是 objc_retainAutoreleasedReturnValue 在 +88 处的函数结果。该函数接受并返回一个对象,因此 x0 是在 +80 处发送的消息返回的值。执行与之前相同的相对页面技巧,我们看到该调用的选择器是 -window。但是被调用的是哪个对象呢?
\n\n由于 objc_storeWeak\n / objc_loadWeakRetained 舞蹈,解决这个问题\xe2\x80\xa6 很好\xe2\x80\xa6 有点复杂。我相信它可以归结为通过 x2 传递到该方法的值,即第三个参数。根据方法名称,这显然是一个视图(请记住,对于 Objective-C 方法,前两个参数 x0 和 x1 保存目标和选择器,因此 x2 保存第一个实际参数)。
\n\n所以,总而言之:
\n\n\n
\n\n- \n
看来这个方法有一个view参数。
- \n
它\xe2\x80\x99s请求了window.window.screenBounds。
- \n
最后一次属性访问失败,因为 \xe2\x80\x99s 本来是一个窗口的东西并没有\xe2\x80\x99s 实现 -screenBounds getter。
我对 UIKit 的了解不够,无法解释其背景。我在这里有几个建议:
\n\n\n
\n\n- \n
运行标准内存调试工具,特别是僵尸,看看它们是否会出现任何有用的东西。确保根据我们分解的方法的类名来执行撤消手势。
- \n
如果这不起作用,请转到“应用程序框架”>“Cocoa Touch”,看看是否有人有任何建议。
分享和享受
\n\n\xe2\x80\x94
\n\n[1] 在 64 位 Arm 上,实际页面大小通常为 64 KiB,但 adrp 指令使用历史页面大小 4096,因为它与 add 指令中的最大文字大小匹配。
\n
https://forums.developer.apple.com/message/389467
\n| 归档时间: |
|
| 查看次数: |
1625 次 |
| 最近记录: |