![](/img/trans.png)
[英]How do I know when safe to ignore __cxa_throw on an All Exceptions breakpoint?
[英]Ignore certain exceptions when using Xcode's All Exceptions breakpoint
我在Xcode中配置了一個All Exceptions斷點:
有時候Xcode會停在一條線上:
[managedObjectContext save:&error];
具有以下回溯:
但如果單擊“繼續”,程序將繼續運行,就好像什么也沒發生
如何忽略這些“正常”異常,但仍然讓調試器在我自己的代碼中停止異常?
(我知道發生這種情況是因為Core Data內部拋出並捕獲異常,並且Xcode只是在拋出異常時遵循暫停程序的請求。但是,我想忽略這些,所以我可以回到調試我自己的代碼!)
版主:這類似於“Xcode 4異常斷點過濾” ,但我認為這個問題需要很長時間才能解決問題並且沒有任何有用的答案。 它們可以聯系起來嗎?
對於核心數據異常,我通常做的是從Xcode中刪除“All Exceptions”斷點,而是:
objc_exception_throw
上添加一個符號斷點 (BOOL)(! (BOOL)[[(NSException *)$x0 className] hasPrefix:@"_NSCoreData"])
配置的斷點應如下所示:
這將忽略用於控制流的任何私有Core Data異常(由類名稱為_NSCoreData
前綴_NSCoreData
)。 請注意,相應的寄存器將取決於您運行的目標設備/模擬器。請查看此表以供參考。
請注意,此技術可以輕松適應其他條件。 棘手的部分在於制作BOOL和NSException強制轉換以使lldb對條件感到滿意。
我編寫了一個lldb腳本,它允許您使用更簡單的語法選擇性地忽略Objective-C異常,並且它可以處理OS X,iOS模擬器以及32位和64位ARM。
~/Library/lldb/ignore_specified_objc_exceptions.py
或其他有用的地方。 import lldb
import re
import shlex
# This script allows Xcode to selectively ignore Obj-C exceptions
# based on any selector on the NSException instance
def getRegister(target):
if target.triple.startswith('x86_64'):
return "rdi"
elif target.triple.startswith('i386'):
return "eax"
elif target.triple.startswith('arm64'):
return "x0"
else:
return "r0"
def callMethodOnException(frame, register, method):
return frame.EvaluateExpression("(NSString *)[(NSException *)${0} {1}]".format(register, method)).GetObjectDescription()
def filterException(debugger, user_input, result, unused):
target = debugger.GetSelectedTarget()
frame = target.GetProcess().GetSelectedThread().GetFrameAtIndex(0)
if frame.symbol.name != 'objc_exception_throw':
# We can't handle anything except objc_exception_throw
return None
filters = shlex.split(user_input)
register = getRegister(target)
for filter in filters:
method, regexp_str = filter.split(":", 1)
value = callMethodOnException(frame, register, method)
if value is None:
output = "Unable to grab exception from register {0} with method {1}; skipping...".format(register, method)
result.PutCString(output)
result.flush()
continue
regexp = re.compile(regexp_str)
if regexp.match(value):
output = "Skipping exception because exception's {0} ({1}) matches {2}".format(method, value, regexp_str)
result.PutCString(output)
result.flush()
# If we tell the debugger to continue before this script finishes,
# Xcode gets into a weird state where it won't refuse to quit LLDB,
# so we set async so the script terminates and hands control back to Xcode
debugger.SetAsync(True)
debugger.HandleCommand("continue")
return None
return None
def __lldb_init_module(debugger, unused):
debugger.HandleCommand('command script add --function ignore_specified_objc_exceptions.filterException ignore_specified_objc_exceptions')
將以下內容添加到~/.lldbinit
:
command script import ~/Library/lldb/ignore_specified_objc_exceptions.py
如果將其保存在其他~/Library/lldb/ignore_specified_objc_exceptions.py
,請使用正確的路徑替換~/Library/lldb/ignore_specified_objc_exceptions.py
。
ignore_specified_objc_exceptions name:NSAccessibilityException className:NSSomeException
NSException
-name
匹配NSAccessibilityException
OR -className
匹配NSSomeException
它應該看起來像這樣:
在您的情況下,您將使用ignore_specified_objc_exceptions className:_NSCoreData
有關腳本和更多詳細信息,請參見http://chen.do/blog/2013/09/30/selectively-ignoring-objective-c-exceptions-in-xcode/ 。
這里有一個替代的快速答案,當你有一個代碼塊時,例如第三方庫引發了你想要忽略的多個異常:
2:names = {'objc_exception_throw','__ cxa_throw'},locations = 2選項:禁用2.1:where = libobjc.A.dylib
objc_exception_throw, address = 0x00007fff8f8da6b3, unresolved, hit count = 0 2.2: where = libc++abi.dylib
__cxa_throw,address = 0x00007fff8d19fab7,unresolved,hit count = 0
這意味着它是斷點2.現在在xcode中,編輯第一個斷點(在拋出異常代碼之前)並將操作更改為“debugger command”並輸入'breakpoint disable 2'(並設置'自動繼續...'復選框)。
對違規行后的斷點執行相同操作,並使用命令'breakpoint enable 2'。
所有斷點異常現在將打開和關閉,因此它僅在您需要時才會激活。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.