【问题标题】:Custom Keyboard crash shared-library-event (Memory leak?)自定义键盘崩溃共享库事件(内存泄漏?)
【发布时间】:2018-01-10 02:39:53
【问题描述】:

我有一个自定义键盘,其中包含按类别划分的图像。现在我在每个类别中有 12 张图片。如果我有一个包含 20 个图像的类别,例如键盘崩溃。我一直在寻找解决方案很长时间没有运气。 当我在我的 iPhone 中调试键盘时,我收到一个 SIGQUIT 信号:

    dyld`_dyld_start:
->  0x10014d000 <+0>:   mov    x28, sp
    0x10014d004 <+4>:   and    sp, x28, #0xfffffffffffffff0
    0x10014d008 <+8>:   mov    x0, #0x0
    0x10014d00c <+12>:  mov    x1, #0x0
    0x10014d010 <+16>:  stp    x1, x0, [sp, #-0x10]!
    0x10014d014 <+20>:  mov    x29, sp
    0x10014d018 <+24>:  sub    sp, sp, #0x10             ; =0x10 
    0x10014d01c <+28>:  ldr    x0, [x28]
    0x10014d020 <+32>:  ldr    x1, [x28, #0x8]
    0x10014d024 <+36>:  add    x2, x28, #0x10            ; =0x10 
    0x10014d028 <+40>:  adrp   x4, -1
    0x10014d02c <+44>:  add    x4, x4, #0x0              ; =0x0 
    0x10014d030 <+48>:  adrp   x3, 52
    0x10014d034 <+52>:  ldr    x3, [x3, #0xd90]
    0x10014d038 <+56>:  sub    x3, x4, x3
    0x10014d03c <+60>:  mov    x5, sp
    0x10014d040 <+64>:  bl     0x10014d088               ; dyldbootstrap::start(macho_header const*, int, char const**, long, macho_header const*, unsigned long*)
    0x10014d044 <+68>:  mov    x16, x0
    0x10014d048 <+72>:  ldr    x1, [sp]
    0x10014d04c <+76>:  cmp    x1, #0x0                  ; =0x0 
    0x10014d050 <+80>:  b.ne   0x10014d05c               ; <+92>
    0x10014d054 <+84>:  add    sp, x28, #0x8             ; =0x8 
    0x10014d058 <+88>:  br     x16
    0x10014d05c <+92>:  mov    x30, x1
    0x10014d060 <+96>:  ldr    x0, [x28, #0x8]
    0x10014d064 <+100>: add    x1, x28, #0x10            ; =0x10 
    0x10014d068 <+104>: add    x2, x1, x0, lsl #3
    0x10014d06c <+108>: add    x2, x2, #0x8              ; =0x8 
    0x10014d070 <+112>: mov    x3, x2
    0x10014d074 <+116>: ldr    x4, [x3]
    0x10014d078 <+120>: add    x3, x3, #0x8              ; =0x8 
    0x10014d07c <+124>: cmp    x4, #0x0                  ; =0x0 
    0x10014d080 <+128>: b.ne   0x10014d074               ; <+116>
    0x10014d084 <+132>: br     x16

如果我点击继续,我会得到。线程 1:共享库事件:

dyld`_dyld_debugger_notification:
->  0x10022cdc4 <+0>: ret    

在我得到的控制台中执行“bt”:

* thread #1, stop reason = shared-library-event
  * frame #0: 0x000000010022cdc4 dyld`_dyld_debugger_notification
    frame #1: 0x000000010022c9a4 dyld`gdb_image_notifier(dyld_image_mode, unsigned int, dyld_image_info const*) + 112
    frame #2: 0x000000010022c5f0 dyld`notifyGDB(dyld_image_states, unsigned int, dyld_image_info const*) + 60
    frame #3: 0x0000000100224b4c dyld`dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) + 1040
    frame #4: 0x000000010023035c dyld`ImageLoader::link(ImageLoader::LinkContext const&, bool, bool, bool, ImageLoader::RPathChain const&, char const*) + 140
    frame #5: 0x0000000100225214 dyld`dyld::link(ImageLoader*, bool, bool, ImageLoader::RPathChain const&, unsigned int) + 228
    frame #6: 0x0000000100226274 dyld`dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) + 2544
    frame #7: 0x0000000100221044 dyld`_dyld_start + 68

有什么想法吗? 更新 我创建了一个预期断点,并获得了加载 nib 文件的断点。

- (void)arrangeXib{

    self.keyboard = [[[NSBundle mainBundle]loadNibNamed:@"iPhone" owner:nil options:nil] objectAtIndex:0];

    self.inputView = (UIInputView *)self.keyboard;
}

例外:

* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGQUIT
    frame #0: 0x00000001847b3224 libsystem_kernel.dylib`mach_msg_trap + 8
    frame #1: 0x00000001847b309c libsystem_kernel.dylib`mach_msg + 72
    frame #2: 0x00000001846a4ee4 libdispatch.dylib`_dispatch_mach_send_and_wait_for_reply + 540
    frame #3: 0x00000001846a52e8 libdispatch.dylib`dispatch_mach_send_with_result_and_wait_for_reply + 56
    frame #4: 0x00000001848ccee0 libxpc.dylib`xpc_connection_send_message_with_reply_sync + 196
    frame #5: 0x0000000185754368 CoreFoundation`__78-[CFPrefsPlistSource sendRequestNewDataMessage:toConnection:retryCount:error:]_block_invoke + 24
    frame #6: 0x00000001857797a8 CoreFoundation`CFPREFERENCES_IS_WAITING_FOR_SYSTEM_CFPREFSD + 48
    frame #7: 0x00000001857542ac CoreFoundation`-[CFPrefsPlistSource sendRequestNewDataMessage:toConnection:retryCount:error:] + 264
    frame #8: 0x000000018575348c CoreFoundation`__50-[CFPrefsPlistSource alreadylocked_requestNewData]_block_invoke + 92
    frame #9: 0x0000000185819d90 CoreFoundation`-[_CFXPreferences withConnectionForRole:performBlock:] + 48
    frame #10: 0x00000001857533e4 CoreFoundation`-[CFPrefsPlistSource alreadylocked_requestNewData] + 288
    frame #11: 0x0000000185750be4 CoreFoundation`_copyValueForKey + 548
    frame #12: 0x00000001857511f0 CoreFoundation`-[CFPrefsPlistSource copyValueForKey:] + 60
    frame #13: 0x0000000185818418 CoreFoundation`__66-[_CFXPreferences copyValueForKey:identifier:user:host:container:]_block_invoke + 40
    frame #14: 0x0000000185813758 CoreFoundation`-[_CFXPreferences(SourceAdditions) withSourceForIdentifier:user:byHost:container:cloud:perform:] + 748
    frame #15: 0x000000018577af20 CoreFoundation`-[_CFXPreferences(SearchListAdditions) with23930198HackSourceForIdentifier:user:byHost:container:cloud:perform:] + 360
    frame #16: 0x0000000185818378 CoreFoundation`-[_CFXPreferences copyValueForKey:identifier:user:host:container:] + 336
    frame #17: 0x000000018754b3d0 ImageIO`IOPreferencesGetBoolean + 196
    frame #18: 0x000000018754c14c ImageIO`InitDebugFlags + 3136
    frame #19: 0x000000018468e9a0 libdispatch.dylib`_dispatch_client_callout + 16
    frame #20: 0x000000018468f6cc libdispatch.dylib`dispatch_once_f + 56
    frame #21: 0x0000000187462ad8 ImageIO`CGImageSourceCreateWithFile + 364
    frame #22: 0x000000018b96c178 UIKit`ImageRefAtPath + 300
    frame #23: 0x000000018b96bff0 UIKit`GetImageAtPath + 36
    frame #24: 0x000000018b96bc60 UIKit`_UIImageAtPath + 396
    frame #25: 0x000000018be10a1c UIKit`-[UIImageNibPlaceholder initWithCoder:] + 524
    frame #26: 0x000000018bf5da50 UIKit`UINibDecoderDecodeObjectForValue + 680
    frame #27: 0x000000018bf5d790 UIKit`-[UINibDecoder decodeObjectForKey:] + 104
    frame #28: 0x000000018bca5ec4 UIKit`-[UIImageView initWithCoder:] + 132
    frame #29: 0x000000018bf5da50 UIKit`UINibDecoderDecodeObjectForValue + 680
    frame #30: 0x000000018bf5dbc8 UIKit`UINibDecoderDecodeObjectForValue + 1056
    frame #31: 0x000000018bf5d790 UIKit`-[UINibDecoder decodeObjectForKey:] + 104
    frame #32: 0x000000018bbed3ec UIKit`-[UIView initWithCoder:] + 652
    frame #33: 0x000000018be0f8d8 UIKit`-[UIClassSwapper initWithCoder:] + 248
    frame #34: 0x000000018bf5da50 UIKit`UINibDecoderDecodeObjectForValue + 680
    frame #35: 0x000000018bf5d790 UIKit`-[UINibDecoder decodeObjectForKey:] + 104
    frame #36: 0x000000018be0f548 UIKit`-[UIRuntimeConnection initWithCoder:] + 136
    frame #37: 0x000000018bf5da50 UIKit`UINibDecoderDecodeObjectForValue + 680
    frame #38: 0x000000018bf5dbc8 UIKit`UINibDecoderDecodeObjectForValue + 1056
    frame #39: 0x000000018bf5d790 UIKit`-[UINibDecoder decodeObjectForKey:] + 104
    frame #40: 0x000000018be0e8bc UIKit`-[UINib instantiateWithOwner:options:] + 1168
    frame #41: 0x000000018be10d40 UIKit`-[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:] + 224
  * frame #42: 0x00000001000b9698 Keyboard`-[KeyboardViewController arrangeXib](self=0x0000000121e058e0, _cmd="arrangeXib") at KeyboardViewController.m:346
    frame #43: 0x00000001000bbbc4 Keyboard`-[KeyboardViewController viewDidLoad](self=0x0000000121e058e0, _cmd="viewDidLoad") at KeyboardViewController.m:514
    frame #44: 0x000000018b907ec0 UIKit`-[UIViewController loadViewIfRequired] + 1036
    frame #45: 0x000000018b907a9c UIKit`-[UIViewController view] + 28
    frame #46: 0x000000018c1de298 UIKit`-[_UIViewServiceViewControllerOperator __createViewController:withContextToken:fbsDisplays:appearanceSerializedRepresentations:legacyAppearance:traitCollection:initialInterfaceOrientation:hostAccessibilityServerPort:canShowTextServices:replyHandler:] + 4172
    frame #47: 0x00000001857dce80 CoreFoundation`__invoking___ + 144
    frame #48: 0x00000001856d22c4 CoreFoundation`-[NSInvocation invoke] + 292
    frame #49: 0x00000001856d6e9c CoreFoundation`-[NSInvocation invokeWithTarget:] + 60
    frame #50: 0x000000018c2e0ce4 UIKit`-[_UIViewServiceImplicitAnimationDecodingProxy forwardInvocation:] + 108
    frame #51: 0x00000001857dad54 CoreFoundation`___forwarding___ + 404
    frame #52: 0x00000001856d6d4c CoreFoundation`_CF_forwarding_prep_0 + 92
    frame #53: 0x00000001857dce80 CoreFoundation`__invoking___ + 144
    frame #54: 0x00000001856d22c4 CoreFoundation`-[NSInvocation invoke] + 292
    frame #55: 0x00000001856d6e9c CoreFoundation`-[NSInvocation invokeWithTarget:] + 60
    frame #56: 0x000000018c232048 UIKit`-[_UIQueueingProxy forwardInvocation:] + 372
    frame #57: 0x00000001857dad54 CoreFoundation`___forwarding___ + 404
    frame #58: 0x00000001856d6d4c CoreFoundation`_CF_forwarding_prep_0 + 92
    frame #59: 0x00000001857dce80 CoreFoundation`__invoking___ + 144
    frame #60: 0x00000001856d22c4 CoreFoundation`-[NSInvocation invoke] + 292
    frame #61: 0x00000001856d6e9c CoreFoundation`-[NSInvocation invokeWithTarget:] + 60
    frame #62: 0x00000001857dad54 CoreFoundation`___forwarding___ + 404
    frame #63: 0x00000001856d6d4c CoreFoundation`_CF_forwarding_prep_0 + 92
    frame #64: 0x00000001857dce80 CoreFoundation`__invoking___ + 144
    frame #65: 0x00000001856d22c4 CoreFoundation`-[NSInvocation invoke] + 292
    frame #66: 0x000000018737f884 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 36
    frame #67: 0x000000018737f6f0 FrontBoardServices`-[FBSSerialQueue _performNext] + 176
    frame #68: 0x000000018737faa0 FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 56
    frame #69: 0x000000018578542c CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
    frame #70: 0x0000000185784d9c CoreFoundation`__CFRunLoopDoSources0 + 540
    frame #71: 0x00000001857829a8 CoreFoundation`__CFRunLoopRun + 744
    frame #72: 0x00000001856b2da4 CoreFoundation`CFRunLoopRunSpecific + 424
    frame #73: 0x000000018711c074 GraphicsServices`GSEventRunModal + 100
    frame #74: 0x000000018b96d058 UIKit`UIApplicationMain + 208
    frame #75: 0x00000001848d7cd0 libxpc.dylib`_xpc_objc_main + 788
    frame #76: 0x00000001848d9984 libxpc.dylib`xpc_main + 200
    frame #77: 0x00000001863dad90 Foundation`-[NSXPCListener resume] + 180
    frame #78: 0x000000018e15712c PlugInKit`-[PKService run] + 752
    frame #79: 0x000000018e156cf0 PlugInKit`+[PKService main] + 56
    frame #80: 0x000000018e157150 PlugInKit`+[PKService _defaultRun:arguments:] + 20
    frame #81: 0x00000001863c0ba4 Foundation`NSExtensionMain + 64
    frame #82: 0x00000001846c159c libdyld.dylib`start + 4

更新 2: 我很确定这与内存问题有关...如果我在单元格中仅显示彩色背景,则可以正常工作。现在,如果我显示图像,如果它们小于 10-15,则没有问题,但如果我有更多,它将崩溃并出现不同的错误,例如上面的错误或:

libz.1.dylib`inflate:
libsystem_kernel.dylib`_kernelrpc_mach_vm_deallocate_trap:

起初我有一个滚动视图,我认为问题在于它直接加载了所有图像,所以我尝试使用 collectionView 但结果相同。我尝试以 3 种不同的方式加载图像,结果相同:

UIImage imageWithContentsOfFile:
UIImage imageWithData:
UIImage imageNamed:

【问题讨论】:

  • 尝试创建exception breakpoint 并重现崩溃;您可能会发现代码崩溃的地方。
  • @the4kman 尝试并在我加载 nib 文件的地方得到它。我会用代码更新问题
  • 你能告诉我们实际的异常是什么吗?
  • @CharlesSrstka 我更新了异常发生时使用 bt 命令得到的内容,不知道是不是你的意思。如果没有,请解释如何获取它,因为我在控制台中没有得到任何其他内容
  • 如果抛出异常,通常会在控制台中记录异常的名称和简短描述,解释发生了什么问题。如果由于某种原因没有,如果您在 objc_exception_throw 上设置断点并在调试器中键入“po $rdi”,您应该得到它。或者,您可以暂时将崩溃的行包含在 @try/@catch 块中并从那里记录异常。可能是 nib 文件有问题,如果我们能看到异常,就会清楚。

标签: objective-c iphone xcode custom-keyboard


【解决方案1】:

现在可以使用了。正如我所料,问题与内存有关。对于第 3 方键盘,我读过苹果将内存限制为 30Mb。

运行应用扩展的内存限制明显低于 对前台应用程序施加的内存限制。在这两个平台上, 系统可能会积极终止扩展,因为用户想要 返回到他们在主机应用程序中的主要目标。一些扩展可能有 比其他内存限制更低:例如,小部件必须是 特别有效,因为用户可能有多个小部件 同时打开。

我有每个大约 60Kb 的 png 图像,但它有一个 24 位彩色位图,当我加载它们时,它使每个图像在内存中大约 5-6Mb。我的解决方案是改用 jpeg 图像,我将无法使用透明背景,但至少我会有一个可以工作的应用程序。

【讨论】:

    【解决方案2】:

    尝试使用DispatchQueue 排除这样的内存泄漏问题:

        DispatchQueue.main.async {[self] in
            // your code here. Dont forget to use "self" before your variables.
    
        }
    

    对我有帮助。

    这个假设的原因来自这个 WWDC 视频: https://developer.apple.com/videos/play/wwdc2017/413/ 表示 有了新的 dyld,他们将立即开始崩溃应用程序,如果 加载时间太长。 Source

    【讨论】:

      【解决方案3】:

      我的应用使用 PLCrashReporter 库从用户设备收集崩溃日志。如果我像这样使用信号处理程序类型 Mach 初始化 PLCrashReporter:

      [[PLCrashReporterConfig alloc] initWithSignalHandlerType:PLCrashReporterSignalHandlerTypeMach];

      然后,当我尝试调试应用程序时,它会崩溃并出现类似的堆栈跟踪:

      Thread 2 Crashed:
      0   dyld                            0x00000001018408b8 _dyld_debugger_notification + 0
      1   dyld                            0x000000010183fd6c gdb_image_notifier+ 64876 (dyld_image_mode, unsigned int, dyld_image_info const*) + 172
      2   dyld                            0x000000010183fa10 notifyGDB+ 64016 (dyld_image_states, unsigned int, dyld_image_info const*) + 64
      3   dyld                            0x00000001018359c0 dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)+ 22976 (dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) + 1348
      4   dyld                            0x0000000101841e60 ImageLoader::link+ 73312 (ImageLoader::LinkContext const&, bool, bool, bool, ImageLoader::RPathChain const&, char const*) + 176
      5   dyld                            0x0000000101835f8c dyld::link+ 24460 (ImageLoader*, bool, bool, ImageLoader::RPathChain const&, unsigned int) + 328
      6   dyld                            0x000000010183e1a8 dlopen_internal + 716
      7   libdyld.dylib                   0x0000000197b5c3bc dlopen_internal+ 21436 (char const*, int, void*) + 176
      

      运行调试器时,无论应用是在 Debug 还是 Release 中构建,都使用处理程序类型 PLCrashReporterSignalHandlerTypeBSD

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-30
        • 2012-09-19
        • 1970-01-01
        • 2020-09-07
        • 1970-01-01
        相关资源
        最近更新 更多