中断“致命错误的任何发生:解开可选值时意外发现nil”。 [英] Break on any occurrence of "fatal error: unexpectedly found nil while unwrapping an Optional value"

查看:87
本文介绍了中断“致命错误的任何发生:解开可选值时意外发现nil”。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个庞大的代码库,我想打破错误致命错误:在展开可选值时意外发现nil



最好的方法是什么



我尝试添加两者:(在断点子窗口中)




  • 添加Swift错误断点

  • 添加异常断点



但是那没做。这是否意味着nil在某些框架代码中而不在我的代码中?

解决方案

展开可选内容由编译器翻译为对 _ getOptionalValue(),它调用 _preconditionFailure()如果值为 nil ,则将其转换为对 _fatalErrorMessage()的调用。



因此,您需要为 _fatalErrorMessage 设置断点。这里的技巧是,您需要为函数的错误名称设置断点,该名称为 _TTSf4s_s_d_d ___ TFSs18_fatalErrorMessageFTVSs12StaticStringS_S_Su_T _



如果为此添加了符号断点,则每次发生致命错误时都将命中该断点。这意味着您将捕获所有 nil 的解包,但是,您还将捕获其他一些触发致命错误的代码。您应该能够在函数的参数上设置一些条件,以便仅当意外发现nil并解开一个可选值时才打断点,但是我个人没有使用 lldb 的此功能,因此我不确定您如何在断点编辑器中设置此条件。






更新。在Swift 3(Xcode 8 beta 6)中,应将断点设置为 _TTSfq4n_n_n_d_d_n ___ TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su5flagsVs6Nant32



在这里,您可以自行查找任何Swift版本的错误函数名称,以便将断点设置为:


  1. 查找您要构建的应用位置(可以在Xcode Navigator-> Products-> Your App Name.app中轻松找到)

  2. 列出嵌入在应用程序捆绑包中的 libswiftCore.dylib 的所有全局符号,并通过 fatalError 。因此,例如,如果您的构建应用程序位于 /Users/your.username/Library/Developer/Xcode/DerivedData/YourApp-rancharchars/Build/Products/Debug-iphonesimulator/YourApp.app / ,您应该运行

      nm -g /Users/your.username/Library/Developer/Xcode/DerivedData/YourApp -randomchars /构建/产品/Debug-iphonesimulator/YourApp.app//Frameworks/libswiftCore.dylib | grep fatalError 


  3. 检查输出并获取错误的方法名称。如果函数重载,则可能有多个符号。输出示例如下所示: c>


  4. 确保在添加断点之前先删除下划线,该断点来自C名称修饰符(因此对于上面的输出,


  5. 添加断点并强制解开nil值,以确保它们起作用。

快乐的零缠绕狩猎:)


I have a huge code base and I want to break on the error "fatal error: unexpectedly found nil while unwrapping an Optional value"

What is the best approach to do that?

I tried adding both: (In the breakpoints sub-window)

  • "Add Swift Error Breakpoint"
  • "Add Exception Breakpoint"

But that didn't do it. Does that mean that the nil was in some framework code and not my code?

解决方案

Unwrapping optionals gets translated by the compiler into calls to _getOptionalValue(), which calls _preconditionFailure() in case of anil value, which gets translated into a call to _fatalErrorMessage().

So you need to set breakpoints for _fatalErrorMessage. The trick here is that you need to set the breakpoints for the mangled name of the function, which is _TTSf4s_s_d_d___TFSs18_fatalErrorMessageFTVSs12StaticStringS_S_Su_T_.

If you add a symbolic breakpoint for this, the breakpoint will be hit everytime a fatal error occurs. This means you'll catch all nil unwraps, however you'll also catch some other pieces of code that trigger fatal errors. You should be able to set some conditions on the arguments of the function so that your breakpoint is hit only when the unexpectedly found nil while unwrapping an Optional value is passed, however I personally didn't played with this feature of lldb so I'm not sure how you need to set this condition in the breakpoint editor.


Update. In Swift 3 (Xcode 8 beta 6), the breakpoint should be set for _TTSfq4n_n_d_d_n___TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su5flagsVs6UInt32_Os5Never

Here's how you can find out for your own the mangled function name for any Swift version, in order to set a breakpoint to:

  1. Find you build app location (can be easily found in Xcode Navigator -> Products -> Your App Name.app)
  2. List all your global symbols for the libswiftCore.dylib embeded within your app bundle, grep by fatalError. So for example if your build app is at /Users/your.username/Library/Developer/Xcode/DerivedData/YourApp-randomchars/Build/Products/Debug-iphonesimulator/YourApp.app/, you should run

    nm -g /Users/your.username/Library/Developer/Xcode/DerivedData/YourApp-randomchars/Build/Products/Debug-iphonesimulator/YourApp.app//Frameworks/libswiftCore.dylib | grep fatalError
    

  3. Check the output and grab the mangled method names. There could be more than one symbol, if the function is overloaded. A sample output looks like this:

    0000000000032f50 T __TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su5flagsVs6UInt32_Os5Never
    00000000001663b0 T __TTSfq4n_n_d_d_n___TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su5flagsVs6UInt32_Os5Never
    

  4. Make sure you remove the leading underscore before adding the breakpoint, that one comes from the C name mangling (so for the above output you should remain with only one leading underscore for the two symbols).

  5. Add the breakpoints and force unwrap a nil value, to make sure they work.

Happy nil-unwrapping hunting :)

这篇关于中断“致命错误的任何发生:解开可选值时意外发现nil”。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆