Break on any occurrence of "fatal error: unexpectedly found nil while unwrapping an Optional value"
Break on any occurrence of "fatal error: unexpectedly found nil while unwrapping an Optional value"
我有一个庞大的代码库,我想打破错误 "fatal error: unexpectedly found nil while unwrapping an Optional value"
最好的方法是什么?
我尝试同时添加:(在断点子window)
- "Add Swift Error Breakpoint"
- "Add Exception Breakpoint"
但这并没有做到。这是否意味着 nil 在某些框架代码中而不是我的代码中?
解包选项被编译器翻译成对 _getOptionalValue() 的调用,在 nil
值的情况下调用 _preconditionFailure()
,它被翻译成对 [=14= 的调用].
所以需要为_fatalErrorMessage
设置断点。这里的技巧是您需要为函数的错位名称设置断点,即 _TTSf4s_s_d_d___TFSs18_fatalErrorMessageFTVSs12StaticStringS_S_Su_T_
。
如果为此添加符号断点,则每次发生致命错误时都会命中断点。这意味着您将捕获所有 nil
解包,但是您还将捕获一些其他触发致命错误的代码片段。您应该能够在函数的参数上设置一些条件,以便只有在传递 unexpectedly found nil while unwrapping an Optional value
时才会触发断点,但是我个人没有使用 lldb
的这个功能,所以我'我不确定您需要如何在断点编辑器中设置此条件。
Update.在Swift3(Xcode8 beta 6)中,断点应该设置为_TTSfq4n_n_d_d_n___TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su5flagsVs6UInt32_Os5Never
以下是您可以自己找出任何 Swift 版本的损坏函数名称的方法,以便将断点设置为:
- 找到您构建应用程序的位置(可以在 Xcode 导航器 -> 产品 -> 您的应用程序 Name.app 中轻松找到)
列出您应用程序包中嵌入的 libswiftCore.dylib
的所有全局符号,按 fatalError
grep。因此,例如,如果您的构建应用程序位于 /Users/your.username/Library/Developer/Xcode/DerivedData/YourApp-randomchars/Build/Products/Debug-iphonesimulator/YourApp.app/
,您应该 运行
nm -g /Users/your.username/Library/Developer/Xcode/DerivedData/YourApp-randomchars/Build/Products/Debug-iphonesimulator/YourApp.app//Frameworks/libswiftCore.dylib | grep fatalError
检查输出并获取损坏的方法名称。如果函数重载,可能会有多个符号。示例输出如下所示:
0000000000032f50 T __TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su5flagsVs6UInt32_Os5Never
00000000001663b0 T __TTSfq4n_n_d_d_n___TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su5flagsVs6UInt32_Os5Never
确保在添加断点之前删除前导下划线,该下划线来自 C 名称修改(因此对于上面的输出,您应该只为两个符号保留一个前导下划线)。
- 添加断点并强制解包一个 nil 值,以确保它们有效。
快乐的 nil-unwrapping 狩猎:)
我有一个庞大的代码库,我想打破错误 "fatal error: unexpectedly found nil while unwrapping an Optional value"
最好的方法是什么?
我尝试同时添加:(在断点子window)
- "Add Swift Error Breakpoint"
- "Add Exception Breakpoint"
但这并没有做到。这是否意味着 nil 在某些框架代码中而不是我的代码中?
解包选项被编译器翻译成对 _getOptionalValue() 的调用,在 nil
值的情况下调用 _preconditionFailure()
,它被翻译成对 [=14= 的调用].
所以需要为_fatalErrorMessage
设置断点。这里的技巧是您需要为函数的错位名称设置断点,即 _TTSf4s_s_d_d___TFSs18_fatalErrorMessageFTVSs12StaticStringS_S_Su_T_
。
如果为此添加符号断点,则每次发生致命错误时都会命中断点。这意味着您将捕获所有 nil
解包,但是您还将捕获一些其他触发致命错误的代码片段。您应该能够在函数的参数上设置一些条件,以便只有在传递 unexpectedly found nil while unwrapping an Optional value
时才会触发断点,但是我个人没有使用 lldb
的这个功能,所以我'我不确定您需要如何在断点编辑器中设置此条件。
Update.在Swift3(Xcode8 beta 6)中,断点应该设置为_TTSfq4n_n_d_d_n___TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su5flagsVs6UInt32_Os5Never
以下是您可以自己找出任何 Swift 版本的损坏函数名称的方法,以便将断点设置为:
- 找到您构建应用程序的位置(可以在 Xcode 导航器 -> 产品 -> 您的应用程序 Name.app 中轻松找到)
列出您应用程序包中嵌入的
libswiftCore.dylib
的所有全局符号,按fatalError
grep。因此,例如,如果您的构建应用程序位于/Users/your.username/Library/Developer/Xcode/DerivedData/YourApp-randomchars/Build/Products/Debug-iphonesimulator/YourApp.app/
,您应该 运行nm -g /Users/your.username/Library/Developer/Xcode/DerivedData/YourApp-randomchars/Build/Products/Debug-iphonesimulator/YourApp.app//Frameworks/libswiftCore.dylib | grep fatalError
检查输出并获取损坏的方法名称。如果函数重载,可能会有多个符号。示例输出如下所示:
0000000000032f50 T __TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su5flagsVs6UInt32_Os5Never 00000000001663b0 T __TTSfq4n_n_d_d_n___TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su5flagsVs6UInt32_Os5Never
确保在添加断点之前删除前导下划线,该下划线来自 C 名称修改(因此对于上面的输出,您应该只为两个符号保留一个前导下划线)。
- 添加断点并强制解包一个 nil 值,以确保它们有效。
快乐的 nil-unwrapping 狩猎:)