显示未发生的调用堆栈的崩溃日志

Posted

技术标签:

【中文标题】显示未发生的调用堆栈的崩溃日志【英文标题】:crash log showing a call stack that doesn't occur 【发布时间】:2018-06-08 05:09:49 【问题描述】:

这是 .crash 文件的一部分

Thread 0 name:
Thread 0 Crashed:
0   libsystem_kernel.dylib          0x000000018181d2ec __pthread_kill + 8
1   libsystem_pthread.dylib         0x00000001819be288 pthread_kill$VARIANT$mp + 376 (pthread.c:1484)
2   libsystem_c.dylib               0x000000018178bd0c abort + 140 (abort.c:91)
3   libc++abi.dylib                 0x0000000180f272c8 abort_message + 132 (abort_message.cpp:75)
4   libc++abi.dylib                 0x0000000180f27470 default_terminate_handler() + 304 (cxa_default_handlers.cpp:68)
5   libobjc.A.dylib                 0x0000000180f508d4 _objc_terminate() + 124 (objc-exception.mm:657)
6   libc++abi.dylib                 0x0000000180f4137c std::__terminate(void (*)()) + 16 (cxa_handlers.cpp:66)
7   libc++abi.dylib                 0x0000000180f40ccc __cxa_throw + 132 (cxa_exception.cpp:130)
8   libobjc.A.dylib                 0x0000000180f50720 objc_exception_throw + 364 (objc-exception.mm:547)
9   Realm                           0x00000001029405f0 -[RLMRealm verifyThread] + 80 (RLMRealm.mm:152)
10  Realm                           0x00000001028c8a78 invocation function for block in objc_object* (anonymous namespace)::makeBoxedGetter<realm::StringData>(unsigned long) + 80 (RLMObject_Private.hpp:47)
11  My App                  0x00000001025ab94c CallerDetailViewController.getTitleOfCaller() + 64 (CallerDetailViewController.swift:1864)
12  My App                  0x00000001025b4db8 specialized CallerDetailViewController.displayUnableToMarkAsNotSpamErrorMessage(error:) + 48
13  My App                  0x00000001025b5684 specialized closure #2 in closure #2 in CallerDetailViewController.blockNumber() + 100 (CallerDetailViewController.swift:0)
14  My App                  0x00000001025b809c partial apply for closure #2 in closure #2 in CallerDetailViewController.blockNumber() + 176 (CallerDetailViewController.swift:0)
15  My App                  0x0000000102629b7c thunk for @callee_owned () -> () + 36 (Toast.swift:0)
16  libdispatch.dylib               0x0000000181688aa0 _dispatch_call_block_and_release + 24 (init.c:994)

然而,这个堆栈轨迹是不会出现在应用程序中的——方法 blockNumber() 不会调用方法 displayUnableToMarkAsNotSpamErrorMessage(),也不会调用任何会调用的方法(也不会出现任何 swizzling 等情况)在)。崩溃堆栈如何显示一个不存在的方法调用堆栈?

func blockNumber()

    Model.log("CallerDetailViewController:blockNumber()")
    if editActionIsInProgress == true
    
        return
    
    var op : UsageStats.Op = UsageStats.Op("ios-VZ-UI-\(self.VCNAME)-BLOCKEXISTING")
    let mdnToBlock = self.caller!.number
    editActionIsInProgress = true
    RootNavigationController.displayActivityIndicator(message: NSLocalizedString("VC_CALLER_DETAIL_BLOCKING_IN_PROGRESS", comment: ""))
    if isExistingCaller
    
        Model.instance().robocallerManager().blockExistingCaller(mdn: mdnToBlock) (error) -> Void in
            Model.log("CallerDetailViewController:blocExistingCaller() completion")
            self.editActionIsInProgress = false
            RootNavigationController.hideActivityIndicator   () in
                DispatchQueue.main.async 
                    if error == nil
                    
                        self.displayBlockedConfirmationMessage()
                        self.displayGUIBasedOnCategory()
                    
                    else
                    
                        let err = error! as NSError
                        self.displayUnableToUnblockErrorMessage(error: err)
                        let _ = op.withError(error!)
                    
                    UsageStats.collectUIStatistics(op)
                
            
        
    
    else
    
        let mdn = caller?.number
        var op : UsageStats.Op = UsageStats.Op("IOS-VZ-UI-\(self.VCNAME)-BLOCKNEW")

        // disable the block button in the popup until the operation has completed to prevent user's from
        // tapping it twice
        Model.instance().robocallerManager().blockNewCaller(caller: caller!, completion:  (error) in
            Model.log("CallerDetailViewController:blockNewCaller() completion")
            self.editActionIsInProgress = false
            RootNavigationController.hideActivityIndicator(completion: )
            DispatchQueue.main.async 
                if error == nil
                
                    // Fetch the newly added Realm managed object within the main thread to ensure the realm is the one for the main thread
                    self.caller = Model.instance().database().findCaller(mdn: mdn!)
                    self.isExistingCaller = true
                    self.addRealmNotification()
                    self.displayBlockedConfirmationMessage()
                    self.displayGUIBasedOnCategory()
                
                else
                
                    let err = error! as NSError
                    self.displayUnableToUnblockErrorMessage(error: err)
                    let _ = op.withError(error!)
                
                UsageStats.collectUIStatistics(op)
            
        )
    



func displayUnableToMarkAsNotSpamErrorMessage(error:Swift.Error)

    var message = self.getTitleOfCaller()
    message = message + " - " + (self.caller?.number.formatPhoneNumberForDisplay())! + " " + NSLocalizedString("VC_CALLER_DETAIL_UNABLE_TO_MARK_AS_NOT_SPAM", comment: "")
    RootNavigationController.displayErrorDialog(title: message, err: error as NSError)

【问题讨论】:

不是blockCaller(),根据崩溃报告是blockNumber() @Oscar Apepland 我花了几天时间阅读崩溃教程,但没有结果。这就是问题的原因,因为它们没有帮助。 "方法 blockNumber() 没有调用方法 displayUnableToMarkAsNotSpamErrorMessage()" 显然它确实。这里是否有一个完成处理程序被传递? @matt。不,没有。我想我可能知道可能会发生什么。 blockNumber() 没有被调用,也没有涉及完成处理程序。但是,正在调用与 blockNumber 类似的方法;有 5 个名称不同的方法,每个方法都有相似的内容,但每个方法都有不同的可本地化字符串。也许编译器已经将这些方法优化为一个,所以这就是为什么它在堆栈中以这种方式出现,这听起来可行吗? 对我来说听起来像 flimflam。我认为您更有可能遇到线程问题并且此视图控制器以某种方式处理不当,而您看到的情况是对之前发生的错误的诊断。正如您被正确告知的那样,要问自己的问题是为什么 Realm 认为您走错了方向。 【参考方案1】:

我实际上并不认为CallerDetailViewController.displayUnableToMarkAsNotSpamErrorMessage 被调用。您会注意到在堆栈跟踪中其放置的末尾没有符号化的执行行。

我有一些猜测这里可能会发生什么,但如果没有实际查看您的代码或了解这些方法中的任何一个实际上是什么,我无法确定它为什么会出现在此时的堆栈跟踪中。

【讨论】:

【参考方案2】:

根据您的崩溃日志,CallerDetailViewController 类的getTitleOfCaller 函数中的代码导致了崩溃。崩溃发生在 RLMRealm 的 verifyThread 函数中的事实告诉我,您正在尝试访问不同线程上的领域对象。这在 Realm 中是不允许的,因为对象是线程受限的。

您可以查看Realm’s documentation on how to fix this.

【讨论】:

谢谢,是的,我知道 getTitleOfCaller 中发生了崩溃,并且我知道 Realm 的线程问题。然而,我的问题是关于为什么调用堆栈显示的调用序列只是没有发生。 好吧,这似乎确实发生了,因为您遇到了崩溃。尝试在 displayUnableToMarkAsNotSpamErrorMessage 函数中添加一个断点,看看会发生什么。

以上是关于显示未发生的调用堆栈的崩溃日志的主要内容,如果未能解决你的问题,请参考以下文章

需要帮助解释来自 QuincyKit 的崩溃日志

应用程序崩溃后未填充 xCode 设备日志

iOS应用崩溃日志分析

符号化没有崩溃日志的 iOS 崩溃堆栈跟踪

Python - 创建有意义的崩溃日志/崩溃报告

iOS测试常见崩溃