Understanding and Analyzing Application Crash Reports (2/2)
Understanding and Analyzing Application Crash Reports (1/2)
Understanding and Analyzing Application Crash Reports (2/2)
Symbolicating iOS Crash Reports With Xcode
Symbolicating Crash Reports With atos
Determining Whether a Crash Report is Symbolicated
Exceptions
Binary Images
Thread State
위에 내용은 건너뛰었습니다. 전체 내용을 확인하실려면 여기에서 확인해 주세요.
Analyzing Crash Reports
Header
모든 충돌 보고서는 헤더로 시작합니다.
Incident Identifier: B6FD1E8E-B39F-430B-ADDE-FC3A45ED368C
CrashReporter Key: f04e68ec62d3c66057628c9ba9839e30d55937dc
Hardware Model: iPad6,8
Process: TheElements [303]
Path: /private/var/containers/Bundle/Application/888C1FA2-3666-4AE2-9E8E-62E2F787DEC1/TheElements.app/TheElements
Identifier: com.example.apple-samplecode.TheElements
Version: 1.12
Code Type: ARM-64 (Native)
Role: Foreground
Parent Process: launchd [1]
Coalition: com.example.apple-samplecode.TheElements [402]
Date/Time: 2016-08-22 10:43:07.5806 -0700
Launch Time: 2016-08-22 10:43:01.0293 -0700
OS Version: iPhone OS 10.0 (14A5345a)
Report Version: 104
- Incident Identifier: 보고서의 고유 식별자입니다. 두 보고서는 동일한 인시던트 식별자를 공유하지 않습니다.
- CrashReporter Key: 익명화 된 장치 별 식별자입니다. 동일한 장치의 두 보고서에는 동일한 값이 포함됩니다.
- Beta Identifier: 충돌 한 응용 프로그램의 장치와 공급 업체의 조합에 대한 고유 식별자입니다. 동일한 공급 업체와 동일한 장치의 응용 프로그램에 대한 두 개의 보고서에는 동일한 값이 포함됩니다. 이 필드는 TestFlight를 통해 배포 된 응용 프로그램에 대해 생성 된 충돌 보고서에만 있으며 CrashReporter Key 필드를 대체합니다.
- Process: 충돌 한 프로세스의 실행 파일 이름입니다. 응용 프로그램 정보 등록 정보 목록의 CFBundleExecutable 키 값과 일치합니다.
- Version: 충돌 한 프로세스 버전. 이 필드의 값은 충돌 한 응용 프로그램의 CFBundleVersion 및 CFBundleVersionString을 연결 한 것입니다.
- Code Type: 충돌 한 프로세스의 대상 아키텍처 이것은 ARM-64, ARM, x86-64 또는 x86 중 하나입니다.
- Role: 종료시 프로세스에 할당 된 task_role
- OS Version: 충돌이 발생한 빌드 번호를 포함한 OS 버전
Exception Information
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [0]
Triggered by Thread: 0
- Exception Type: 하나 이상의 64 비트 16 진수로 인코딩 된 예외에 대한 프로세서 특정 정보. 일반적으로 Crash Reporter는 예외 코드를 구문 분석하여 다른 필드에서 사람이 읽을 수있는 설명으로 표시하기 때문에 존재하지 않습니다.
- Exception Subtype: 사람이 읽을 수있는 예외 코드 이름입니다.
- Exception Message: 예외 코드에서 추출 된 사람이 읽을 수있는 추가 정보.
- Exception Note: 하나의 예외 유형에만 해당되지 않는 추가 정보. 이 필드에 SIMULATED (크래시가 아님)가 포함 된 경우 프로세스가 중단되지 않았지만 시스템, 일반적으로 워치 독의 요청에 따라 프로세스가 종료되었습니다.
- Termination Signal: 예외 코드에서 추출 된 사람이 읽을 수있는 추가 정보.
- Termination Reason: 프로세스가 종료 될 때 지정된 종료 이유 정보. 프로세스 내부 및 외부의 주요 시스템 구성 요소는 치명적인 오류 (예 : 잘못된 코드 서명, 누락 된 종속 라이브러리 또는 적절한 권한없이 개인 정보 보호 정보에 액세스)가 발생하면 프로세스를 종료합니다. MacOS Sierra, iOS 10, watchOS 3 및 tvOS 10은 이러한 오류를 기록하기 위해 새로운 인프라를 채택했으며 이러한 운영 체제에서 생성 된 충돌 보고서는 종료 이유 필드에 오류 메시지를 나열합니다.
- Triggered by Thread: 예외가 발생한 스레드
그 밖에 Exception
Bad Memory Access [EXC_BAD_ACCESS // SIGSEGV // SIGBUS]
Abnormal Exit [EXC_CRASH // SIGABRT]
Trace Trap [EXC_BREAKPOINT // SIGTRAP]
Illegal Instruction [EXC_BAD_INSTRUCTION // SIGILL]
Quit [SIGQUIT]
Killed [SIGKILL]
Guarded Resource Violation [EXC_GUARD]
Resource Limit [EXC_RESOURCE]
Other Exception Types
- 0xbaaaaaad: 로그가 충돌 보고서가 아니라 전체 시스템의 스택 샷임을 나타냅니다.
- 0xbad22222: VoIP 애플리케이션이 너무 자주 재개되어 iOS에 의해 종료되었습니다.
- 0x8badf00d: 애플리케이션이 시스템 이벤트를 시작, 종료 또는 응답하는 데 너무 오래 걸렸습니다.
- 0xc00010ff: 단말의 온도가 높아지면 운영 체제에서 앱이 종료되었음을 나타냅니다.
- 0xdead10cc: 응용 프로그램이 일시 중단 중에 파일 잠금 또는 sqlite 데이터베이스 잠금을 유지했기 때문에 OS에 의해 종료되었음을 나타냅니다.
- 0x2bad45ec: 보안 위반으로 인해 iOS에서 응용 프로그램이 종료되었음을 나타냅니다. '보안 모드에서 안전하지 않은 그리기를 수행하는 프로세스가 감지되었습니다'는 화면이 잠겨있을 때와 같이 허용되지 않을 때 앱이 화면에 그리기를 시도했음을 나타냅니다.
Additional Diagnostic Information
- Application Specific Information: 프로세스가 종료되기 직전에 캡처 된 프레임 워크 오류 메시지
- Kernel Messages: 코드 서명 문제에 대한 세부 사항
- Dyld Error Messages: 동적 링커에서 생성 된 오류 메시지
Dyld Error Messages
링크된 프레임 워크를 찾을 수 없기 때문에 프로세스가 종료
Dyld Error Message: Dyld Message: Library not loaded: @rpath/MyCustomFramework.framework/
MyCustomFramework Referenced from: /private/var/containers/Bundle/Application/
CD9DB546-A449-41A4-A08B-87E57EE11354/TheElements.app/TheElements Reason: no suitable image found.
Application Specific Information
초기 뷰 컨트롤러를 빠르게 로드하지 못해 프로세스가 종료
Application Specific Information:
com.example.apple-samplecode.TheElements failed to scene-create after 19.81s (launch took 0.19s of total time limit 20.00s)
Elapsed total CPU time (seconds): 7.690 (user 7.690, system 0.000), 19% CPU
Elapsed application CPU time (seconds): 0.697, 2% CPU
Backtraces
충돌 보고서의 가장 흥미로운 부분은 프로세스가 종료 될 때 각 프로세스 스레드의 역 추적입니다.
이러한 각 추적은 디버거로 프로세스를 일시 중지 할 때 표시되는 것과 유사합니다.
Thread 0 name: Dispatch queue:
com.apple.main-thread
Thread 0 Crashed:
0 TheElements 0x000000010006bc20 -[AtomicElementViewController myTransitionDidStop:finished:context:] (AtomicElementViewController.m:203)
1 UIKit 0x0000000194cef0f0 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 312
2 UIKit 0x0000000194ceef30 -[UIViewAnimationState animationDidStop:finished:] + 160
3 QuartzCore 0x0000000192178404 CA::Layer::run_animation_callbacks(void*) + 260
4 libdispatch.dylib 0x000000018dd6d1c0 _dispatch_client_callout + 16
5 libdispatch.dylib 0x000000018dd71d6c _dispatch_main_queue_callback_4CF + 1000
6 CoreFoundation 0x000000018ee91f2c __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
7 CoreFoundation 0x000000018ee8fb18 __CFRunLoopRun + 1660
8 CoreFoundation 0x000000018edbe048 CFRunLoopRunSpecific + 444
9 GraphicsServices 0x000000019083f198 GSEventRunModal + 180
10 UIKit 0x0000000194d21bd0 -[UIApplication _run] + 684
11 UIKit 0x0000000194d1c908 UIApplicationMain + 208
12 TheElements 0x00000001000653c0 main (main.m:55)
13 libdyld.dylib 0x000000018dda05b8 start + 4
Thread 1:
0 libsystem_kernel.dylib 0x000000018deb2a88 __workq_kernreturn + 8
1 libsystem_pthread.dylib 0x000000018df75188 _pthread_wqthread + 968
2 libsystem_pthread.dylib 0x000000018df74db4 start_wqthread + 4
Understanding Low Memory Reports
메모리 부족 상태가 감지되면 iOS의 가상 메모리 시스템은 응용 프로그램의 협력을 통해 메모리를 해제합니다.
메모리 부족 알림은 사용중인 메모리 양을 줄이기 위해 메모리를 확보하기위한 요청으로 실행중인 모든 응용 프로그램 및 프로세스에 전송됩니다.
메모리 압력이 여전히 존재하면 시스템은 백그라운드 프로세스를 종료하여 메모리 압력을 완화 할 수 있습니다.
충분한 메모리를 확보 할 수 있으면 응용 프로그램이 계속 실행됩니다.
그렇지 않은 경우 응용 프로그램의 요구를 충족시키기에 메모리가 충분하지 않아 iOS에서 응용 프로그램이 종료되고 메모리 부족 보고서가 생성되어 장치에 저장됩니다.
메모리 부족 보고서의 형식은 응용 프로그램 스레드에 대한 역 추적이 없다는 점에서 다른 충돌 보고서와 다릅니다.
메모리 부족 보고서는 충돌 보고서의 헤더와 유사한 헤더로 시작합니다. 헤더 다음에는 시스템 전체 메모리 통계가 나열된 필드 모음이 있습니다.
페이지 크기 필드의 값을 기록해 두십시오. 메모리 부족 보고서에서 각 프로세스의 메모리 사용량은 메모리 페이지 수로보고됩니다.
메모리 부족 보고서에서 가장 중요한 부분은 프로세스 테이블입니다. 이 테이블에는 메모리 부족 보고서가 생성 될 때 시스템 데몬을 포함하여 실행중인 모든 프로세스가 나열됩니다.
프로세스가 'jettisoned'인 경우 이유는 [이유] 열 아래에 나열됩니다.
[per-process-limit] : 프로세스가 시스템에서 부과 한 메모리 제한을 초과했습니다.
Extension은 프로세스 당 메모리 제한이 훨씬 낮습니다. 맵 뷰 및 SpriteKit과 같은 특정 기술은 기본 메모리 비용이 높으며 확장에 사용하기에 적합하지 않을 수 있습니다.
[vm-pageshortage]/[vm-thrashing]/[vm]: 메모리 압력으로 인해 프로세스가 종료되었습니다.
[vnode-limit]: 너무 많은 파일이 열려 있습니다
vnode가 거의 소진 될 때 시스템은 가장 Front에 있는 앱을 종료하지 않습니다.
이는 백그라운드에서 애플리케이션이 과도한 vnode 사용의 소스가 아니더라도 종료될 수 있음을 의미합니다.
[highwater]: 시스템 데몬이 메모리 사용량에 대한 상위 워터 마크를 넘었습니다
[jettisoned]: 다른 이유로 프로세스가 소거되었습니다.
Leak 및 Allocations instruments는 모든 메모리 사용량을 추적하지는 않습니다.
전체 메모리 사용량을 보려면 VM Tracker Instruments (Instruments Allocations 템플릿에 포함)로 응용 프로그램을 실행해야합니다.
VM 트래커는 기본적으로 비활성화되어 있습니다.
VM Tracker로 애플리케이션을 프로파일링하려면 Instruments를 클릭하고 '자동 스냅 샷' 플래그를 확인하거나 '지금 스냅 샷'버튼을 수동으로 누르십시오.
실제로 분석해보자!
첨부된 파일을 열어봅시다.
제가 배포한 앱이 아니기 때문에 Symbolicating 하지 않았으며 unsymbolicating 상태에서 분석합니다.
발생한 이유:
Exception Type: EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: Namespace SPRINGBOARD, Code 0x8badf00d
Termination Description: SPRINGBOARD, scene-create watchdog transgression: com.rainxxx.bxxxsalad2 exhausted CPU time allowance of 0.31 seconds | ProcessVisibility: Background | ProcessState: Running | WatchdogEvent: scene-create | WatchdogVisibility: Background | WatchdogCPUStatistics: ( | "Elapsed total CPU time (seconds): 24.620 (user 24.620, system 0.000), 72% CPU", | "Elapsed application CPU time (seconds): 5.170, 15% CPU" | )
Triggered by Thread: 0
문서를 찾아보니 2가지 이유가 연결되어 있습니다.
시스템 요청에 따라 프로세스가 종료되었다고 합니다.
애플리케이션이 시스템 이벤트를 시작, 종료 또는 응답하는 데 너무 오래 걸렸습니다.
이것의 일반적인 원인 중 하나는 메인 스레드에서 동기 네트워킹을 수행하는 것입니다.
시나리오를 예상해 본 결과
App이 foreground로 올라오면서 tracking events 하는 데 시간이 초과하여 시스템이 앱을 종료시킨 것으로 판단됩니다.
Amplitude-iOS 라이브러리 내부에서 Crash가 발생하였습니다.
Symbolicating 를 하였다면 어느 메소드에서 발생했는지까지 알 수 있을 것 같습니다.
참조:
https://www.raywenderlich.com/2805-demystifying-ios-application-crash-logs