좋아요, 내 중단 점이 objc_exception_throw
방금 트리거 되었다고 상상해보세요 . 디버거 프롬프트에 앉아 예외 개체에 대한 추가 정보를 얻고 싶습니다. 어디서 찾을 수 있나요?
좋아요, 내 중단 점이 objc_exception_throw
방금 트리거 되었다고 상상해보세요 . 디버거 프롬프트에 앉아 예외 개체에 대한 추가 정보를 얻고 싶습니다. 어디서 찾을 수 있나요?
답변:
예외 개체는에 대한 첫 번째 인수로 전달됩니다 objc_exception_throw
. LLDB는 올바른 호출 규칙에서 인수를 참조하는 $arg1
.. $argn
변수를 제공 하므로 예외 세부 정보를 간단하게 인쇄 할 수 있습니다.
(lldb) po $arg1
(lldb) po [$arg1 name]
(lldb) po [$arg1 reason]
objc_exception_throw
이러한 명령을 실행하기 전에 호출 스택에서 프레임 을 선택해야 합니다. 무대에서 수행되는 작업을 보려면 WWDC15 세션 비디오의 "Advanced Debugging and the Address Sanitizer"를 참조하십시오.
오래된 정보
GDB를 사용하는 경우 첫 번째 인수를 참조하는 구문은 실행중인 아키텍처의 호출 규칙에 따라 다릅니다. 실제 iOS 기기에서 디버깅하는 경우 객체에 대한 포인터는 register에 r0
있습니다. 인쇄하거나 메시지를 보내려면 다음과 같은 간단한 구문을 사용하십시오.
(gdb) po $r0
(gdb) po [$r0 name]
(gdb) po [$r0 reason]
iPhone Simulator에서는 모든 함수 인수가 스택에 전달되므로 구문이 훨씬 더 끔찍합니다. 내가 만들 수있는 가장 짧은 표현은 *(id *)($ebp + 8)
. 일을 덜 고통스럽게 만들기 위해 편의 변수를 사용하는 것이 좋습니다.
(gdb) set $exception = *(id *)($ebp + 8)
(gdb) po $exception
(gdb) po [$exception name]
(gdb) po [$exception reason]
$exception
중단 점에 명령 목록을 추가하여 중단 점이 트리거 될 때마다 자동으로 설정할 수도 있습니다 objc_exception_throw
.
(내가 테스트 한 모든 경우에서 예외 객체는 중단 점에 도달 할 때 eax
및 edx
레지스터 에도 존재했습니다 . 그래도 항상 그런 경우는 아닙니다.)
아래 댓글에서 추가되었습니다.
에서 lldb 에 대한 스택 프레임을 선택 objc_exception_throw
하고이 명령을 입력 :
(lldb) po *(id *)($esp + 4)
objc_exception_throw
에 LLDB : po *(id *)($esp + 4)
.
objc_exception_throw
).
po $eax
시뮬레이터 $r0
에서 장치에있을 때 펜던트로 작동 합니다.
새 시뮬레이터 (iOS 8, 64 비트) xcode 6 im 예외 프레임에서 사용 : objc_exception_throw
po $rax
32 비트 :
po $eax
Rax는 무엇입니까?
Rax는 이전 eax를 대체하는 64 비트 레지스터입니다.
모든 레지스터를 찾는 방법은 무엇입니까?
register read
이 글을 쓰는 시점에서이 게시물은 lldb print exception에 대한 Google 최고의 히트작입니다 . 따라서 lldb 및 x86_64를 설명하기 위해이 답변을 추가하고 있습니다.
를 사용하여 예외를 찾으려는 시도가 po $eax
실패했습니다 error: Couldn't materialize struct: Couldn't read eax (materialize)
. 이전 답변의 링크 된 문서에 설명 된 다른 시도도 실패했습니다.
핵심은 objc_exception_throw
메인 스레드 의 프레임 을 먼저 클릭해야한다는 것 입니다. lldb 는 해당 프레임에서 시작되지 않습니다.
내 모든 검색 및 다음 예제 에서이 블로그 항목 은 나를 위해 일한 방식으로 일을 설명하는 첫 번째 항목 이었습니다. 더 현대적이며 2012 년 8 월에 게시됩니다.
catch 문이있는 경우 거기에 중단 점을 입력하면 해당 지점에서 예외 개체를 검사 할 수 있습니다.
catch 문이 없으면 계속하십시오.
다음과 같은 메시지가 터미널에 표시됩니다.
포착되지 않은 예외 'NSInvalidArgumentException'으로 인해 앱 종료, 이유 : ' * -[__ NSPlaceholderDictionary initWithObjects : forKeys : count :] : 개체에서 nil 개체 삽입 시도 [0]'
그러나 응용 프로그램이 종료되면 멋진 스택 추적을 잃게되므로 계속하지 않고 검사 할 방법을 찾고있을 것입니다.
이를 위해 Fnord의 답변이 가장 좋은 것처럼 들리지만 LLDB에서 작동하지 못했습니다.