programing

Xcode의 All Exceptions 중단점을 사용할 때 특정 예외 무시

goodsources 2023. 11. 7. 20:49
반응형

Xcode의 All Exceptions 중단점을 사용할 때 특정 예외 무시

Xcode에서 All Exceptions 중단점을 구성했습니다.

screenshot of an exception breakpoint configured in Xcode breakpoint pain, configured to make a sound when an exception is thrown

Xcode는 때때로 다음과 같은 라인에서 멈춥니다.

[managedObjectContext save:&error];

다음과 같은 역추적을 통해

backtrace showing NSPersistentStoreCoordinator throwing an exception inside the call to save:

계속을 클릭하면 아무 일도 없었던 것처럼 프로그램이 계속됩니다.

어떻게 하면 이러한 "정상적인" 예외를 무시하면서도 내 코드에 있는 예외에 대해 디버거가 중지되도록 할 수 있습니까?

(Core Data가 내부적으로 예외를 던지고 잡기 때문에 이런 일이 발생한다는 것을 알고 있으며, Xcode는 예외가 발생할 때마다 프로그램을 일시 중지해 달라는 제 요청을 단순히 존중하는 것입니다.하지만, 저는 제 자신의 코드 디버깅으로 돌아갈 수 있도록 이것들을 무시하고 싶습니다!)

사회자: 이것은 "Xcode 4 예외 중단점 필터링"과 유사하지만, 이 질문은 요점을 파악하는 데 시간이 너무 오래 걸리고 유용한 답이 없다고 생각합니다.연결될 수 있습니까?

핵심 데이터 예외의 경우 일반적으로 Xcode에서 "모든 예외" 중단점을 제거하고 대신 다음을 수행합니다.

  1. 기호 중단점 추가objc_exception_throw
  2. 중단점 조건을 다음으로 설정합니다.(BOOL)(! (BOOL)[[(NSException *)$x0 className] hasPrefix:@"_NSCoreData"])

구성된 중단점은 다음과 같이 보여야 합니다.Configuring the Breakpoint

이는 클래스 이름 앞에 붙는 것에 따라 결정되는 모든 개인 코어 데이터 예외를 무시합니다._NSCoreData제어 흐름에 사용됩니다.적절한 레지스터는 실행 중인 대상 장치/시뮬레이터에 따라 달라집니다.참고로 이 표를 보세요.

이 기법은 다른 조건에 쉽게 적용될 수 있습니다.까다로운 부분은 BOOL과 NS Exception 캐스트를 제작하여 조건에 만족하는 것이었습니다.

훨씬 더 간단한 구문으로 Objective-C 예외를 선택적으로 무시할 수 있는 allldb 스크립트를 작성했고, OS X, iOS 시뮬레이터, 32bit 및 64bit 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 예외를 모두 잡습니다.
  • 중단점을 편집하고 다음 명령으로 디버거 명령을 추가합니다.ignore_specified_objc_exceptions name:NSAccessibilityException className:NSSomeException
  • 이것은 다음과 같은 예외를 무시합니다.NSException -name성냥들NSAccessibilityException오어-className성냥들NSSomeException

다음과 같이 보여야 합니다.

Screenshot showing a breakpoint set in Xcode per the instructions

당신의 경우, 당신은 다음을ignore_specified_objc_exceptions className:_NSCoreData

스크립트 및 자세한 내용은 http://chen.do/blog/2013/09/30/selectively-ignoring-objective-c-exceptions-in-xcode/ 을 참조하십시오.

무시하고 싶은 여러 예외를 던지는 제3 파트 라이브러리와 같은 코드 블록이 있을 때에 대한 빠른 답변을 제공합니다.

  1. 무시할 코드의 예외 던지기 블록 앞과 뒤에 두 개의 중단점을 설정합니다.
  2. 예외에서 멈출 때까지 프로그램을 실행하고 '중단점 목록'을 디버거 콘솔에 입력하여 '모든 예외' 중단점의 수를 찾으면 다음과 같습니다.

2: 이름 = {'objc_exception_throw', '_cxa_throw'}, 위치 = 2 옵션: 사용 안 함 2.1: 여기서 = libobjc.디립objc_exception_throw, address = 0x00007fff8f8da6b3, unresolved, hit count = 0 2.2: where = libc++abi.dylib__cxa_throw, 주소 = 0x00007ff8d19 fab7, 미해결, 적중 횟수 = 0

  1. 이것은 브레이크 포인트 2를 의미합니다.이제 xcode에서 첫 번째 중단점(예외 던지기 코드 전)을 편집하고 작업을 'debugger command'로 변경하고 '중단점 비활성화 2'를 입력합니다(그리고 '자동으로 계속'을 설정합니다..)..' 확인란)을 누릅니다.

  2. 오펜딩 라인 이후의 중단점에 대해서도 동일하게 수행하고 '중단점 활성화 2' 명령을 받습니다.

이제 모든 중단점 예외가 켜지고 꺼지기 때문에 필요할 때만 활성화됩니다.

언급URL : https://stackoverflow.com/questions/14370632/ignore-certain-exceptions-when-using-xcodes-all-exceptions-breakpoint

반응형