1. ホーム
  2. iphone

[解決済み] XcodeのAll Exceptionsブレークポイント使用時に特定の例外を無視する。

2023-07-14 10:04:06

質問

Xcode で All Exceptions ブレークポイントが設定されています。

のような行でXcodeが止まってしまうことがあります。

[managedObjectContext save:&error];

を実行すると、以下のようなバックトレースが表示されます。

というメッセージが表示されますが、[続行] をクリックすると、プログラムは何事もなかったかのように続行されます。

これらの "normal" 例外を無視して、私自身のコードの例外でデバッガを停止させるにはどうしたらよいでしょうか。

(Core Data が内部的に例外をスローおよびキャッチするためにこれが起こること、そして Xcode が例外がスローされるたびにプログラムを一時停止する私の要求に単に応えていることを理解しています。)

Core Data の例外を無視したいです。しかし、私はこれらを無視したいので、自分のコードのデバッグに戻ることができます!)

モデレーター: これは Xcode 4 の例外ブレークポイントのフィルタリングと同じです。 , しかし、私はその質問がポイントに回り込むのに時間がかかりすぎ、有用な答えを持っていないと思います。それらはリンクすることができますか?

どのように解決するのですか?

私は、よりシンプルな構文で Objective-C 例外を選択的に無視できる lldb スクリプトを書き、OS X、iOS Simulator、および 32 ビットと 64 ビットの ARM の両方を処理しました。

インストール

  1. このスクリプトを ~/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')

  1. に以下を追加します。 ~/.lldbinit :

    command script import ~/Library/lldb/ignore_specified_objc_exceptions.py

    置き換え ~/Library/lldb/ignore_specified_objc_exceptions.py を正しいパスに置き換えてください。

使用方法

  • Xcode で、すべての Objective-C 例外
  • ブレークポイントを編集し、以下のコマンドでDebugger Commandを追加します。 ignore_specified_objc_exceptions name:NSAccessibilityException className:NSSomeException
  • これは、以下のような例外を無視します。 NSException -name にマッチする NSAccessibilityException または -className マッチ NSSomeException

このような感じになるはずです。

あなたの場合 ignore_specified_objc_exceptions className:_NSCoreData

参照 http://chen.do/blog/2013/09/30/selectively-ignoring-objective-c-exceptions-in-xcode/ を参照してください。