기술 노트 TN2151

Understanding and Analyzing Application Crash Reports 응용 프로그램 충돌 보고서 이해 및 분석

When an application crashes, a crash report is created which is very useful for understanding what caused the crash. 응용 프로그램이 충돌하면 충돌을 일으킨 원인을 이해하는 데 매우 유용한 충돌 보고서가 작성됩니다. This document contains essential information about how to symbolicate, understand, and interpret crash reports. 이 문서에는 충돌 보고서를 상징, 이해 및 해석하는 방법에 대한 필수 정보가 포함되어 있습니다.

Introduction 소개

When an application crashes, a crash report is created and stored on the device. 응용 프로그램이 충돌하면 충돌 보고서 가 만들어져 장치에 저장됩니다. Crash reports describe the conditions under which the application terminated, in most cases including a complete backtrace for each executing thread, and are typically very useful for debugging issues in the application. 크래시 보고서는 응용 프로그램이 종료되는 조건을 설명하며 대부분의 경우 실행중인 각 스레드에 대한 백 트레이스를 포함하며 응용 프로그램의 문제를 디버깅하는 데 매우 유용합니다. You should look at these crash reports to understand what crashes your application is having, and then try to fix them. 이러한 충돌 보고서를보고 응용 프로그램이 충돌하는 것을 이해하고이를 수정하려고 시도해야합니다.

Crash reports with backtraces need to be symbolicated before they can be analyzed. 백 트레이스를 사용하는 오류 보고서는 분석하기 전에 기호화 해야합니다. Symbolication replaces memory addresses with human-readable function names and line numbers. 기호는 사람이 읽을 수있는 함수 이름과 행 번호로 메모리 주소를 대체합니다. If you get crash logs off a device through Xcode's Devices window, then they will be symbolicated for you automatically after a few seconds. Xcode의 장치 창을 통해 장치에서 오류 로그를 받으면 몇 초 후에 자동으로 기호화됩니다. Otherwise you will need to symbolicate the .crash file yourself by importing it to the Xcode Devices window. 그렇지 않으면 Xcode 장치 창으로 가져 와서 .crash 파일을 직접 기호화해야합니다. See Symbolicating Crash Reports for details. 자세한 내용은 크래시 보고서 기호화 하기를 참조하십시오.

A Low Memory report differs from other crash reports in that there are no backtraces in this type of report. 메모리 부족 보고서 는이 보고서 유형에 역 추적이 없다는 점에서 다른 오류 보고서 와 다릅니다. When a low memory crash happens, you must investigate your memory usage patterns and your responses to low memory warnings. 낮은 메모리 충돌이 발생하면 메모리 사용 패턴과 메모리 부족 경고에 대한 응답을 조사해야합니다. This document points to you several memory management references that you might find useful. 이 문서는 유용한 메모리 관리 참조를 가리킨다.

Acquiring Crash and Low Memory Reports 크래시 및 메모리 부족 보고서 가져 오기

Debugging Deployed iOS Apps discusses how to retrieve crash and low memory reports directly from an iOS device. 디버깅 배치 된 iOS 앱 은 iOS 장비에서 충돌 및 메모리 부족 보고서를 직접 가져 오는 방법에 대해 설명합니다.

Analyzing Crash Reports in the App Distribution Guide discusses how to view aggregate crash reports collected from TestFlight beta testers and users who have downloaded your app from the App Store. 앱 배포 가이드크래시 보고서 분석 에서는 TestFlight 베타 테스터 및 앱 스토어에서 앱을 다운로드 한 사용자로부터 수집 된 전체 크래시 보고서를 보는 방법에 대해 설명합니다.

Symbolicating Crash Reports 충돌 보고서 기호화

Symbolication is the process of resolving 기호화는 해결 과정입니다. backtrace 역 추적 addresses to source code method or function names, known as symbols. 기호로 알려진 소스 코드 메소드 또는 함수 이름에 대한 주소. Without first symbolicating a crash report it is difficult to determine where the crash occurred. 충돌 보고서를 먼저 나타내지 않으면 충돌이 어디에서 발생했는지 판단하기가 어렵습니다.

Figure 1 Overview of the crash reporting and symbolication process. 그림 1 충돌보고 및 심볼 프로세스 개요.
  1. As the compiler translates your source code into machine code, it also generates debug symbols which map each machine instruction in the compiled binary back to the line of source code from which it originated. 컴파일러가 소스 코드를 기계어 코드로 변환 할 때 컴파일 된 바이너리의 각 기계 명령어를 원래 소스 코드 행에 매핑하는 디버그 심볼도 생성합니다. Depending on the Debug Information Format ( DEBUG_INFORMATION_FORMAT ) build setting, these debug symbols are stored inside the binary or in a companion Debug Symbol ( dSYM ) file. 디버그 정보 형식 ( DEBUG_INFORMATION_FORMAT ) 빌드 설정에 DEBUG_INFORMATION_FORMAT 디버그 기호는 바이너리 또는 함께 제공되는 디버그 기호 ( dSYM ) 파일에 저장됩니다. By default, debug builds of an application store the debug symbols inside the compiled binary while release builds of an application store the debug symbols in a companion dSYM file to reduce the binary size. 기본적으로 응용 프로그램의 디버그 빌드는 컴파일 된 바이너리 내에 디버그 기호를 저장하고 응용 프로그램의 릴리스 빌드는 디버그 기호를 함께 제공되는 dSYM 파일에 저장하여 바이너리 크기를 줄입니다.

    The Debug Symbol file and application binary are tied together on a per-build-basis by the build UUID. 디버그 심볼 파일과 응용 프로그램 바이너리는 빌드 UUID에 의해 빌드마다 연결됩니다. A new UUID is generated for each build of your application and uniquely identifies that build. 응용 프로그램의 각 빌드에 대해 새 UUID가 생성되고 해당 빌드를 고유하게 식별합니다. Even if a functionally-identical executable is rebuilt from the same source code, with the same compiler settings, it will have a different build UUID. 기능적으로 동일한 실행 파일이 동일한 컴파일러 설정을 사용하여 동일한 소스 코드에서 다시 빌드 되더라도 다른 빌드 UUID를 갖습니다. Debug Symbol files from subsequent builds, even from the same source files, will not interoperate with binaries from other builds. 후속 빌드의 디버그 심볼 파일은 동일한 소스 파일 에서조차 다른 빌드의 바이너리와 상호 운용되지 않습니다.

  2. When you archive the application for distribution, Xcode will gather the application binary along with the . 배포를 위해 응용 프로그램을 보관하면 Xcode는 응용 프로그램 바이너리를 함께 수집합니다. dSYM file and store them at a location inside your home folder. dSYM 파일을 복사하여 홈 폴더 안의 위치에 저장하십시오. You can find all of your archived applications in the Xcode Organizer under the "Archived" section. 보관 된 모든 응용 프로그램은 Xcode Organizer의 "Archived"섹션에서 찾을 수 있습니다. For more information about creating an archive, refer to the App Distribution Guide . 보관 파일 만들기에 대한 자세한 내용은 App Distribution Guide를 참조하십시오.

  3. If you are distributing your app via the App Store, or conducting a beta test using Test Flight, you will be given the option of including the dSYM file when uploading your archive to iTunes Connect. App Store를 통해 응용 프로그램을 배포하거나 Test Flight를 사용하여 베타 테스트를 수행하는 경우 아카이브를 iTunes Connect에 업로드 할 때 dSYM 파일을 포함 할 수있는 옵션이 제공됩니다. In the submission dialog, check “Include app symbols for your application…”. 제출 대화 상자에서 '애플리케이션에 앱 기호 포함 ...'을 선택하십시오. Uploading your dSYM file is necessary to receive crash reports collected from TestFlight users and customers who have opted to share diagnostic data. TestFlight 사용자 및 진단 데이터를 공유하도록 선택한 고객으로부터 수집 된 오류 보고서를 받으려면 dSYM 파일을 업로드해야합니다. For more information about the crash reporting service, refer to the App Distribution Guide . 오류보고 서비스에 대한 자세한 내용은 앱 배포 가이드를 참조하십시오.

  4. When your application crashes, an 응용 프로그램이 충돌하면 unsymbolicated 기호가없는 crash report is created and stored on the device. 충돌 보고서가 생성되어 장치에 저장됩니다.

  5. Users can retrieve crash reports directly from their device by following the steps in Debugging Deployed iOS Apps . 사용자는 배포 된 iOS 앱 디버깅 의 단계에 따라 기기에서 직접 충돌 보고서를 검색 할 수 있습니다. If you have distributed your application via AdHoc or Enterprise distribution, this is the only way to acquire crash reports from your users. AdHoc 또는 Enterprise 배포를 통해 응용 프로그램을 배포 한 경우 이는 사용자로부터 충돌 보고서를 얻을 수있는 유일한 방법입니다.

  6. Crash reports retrieved from a device are 기기에서 검색된 오류 보고서는 unsymbolicated 기호가없는 and will need to be 그리고 있어야합니다 symbolicated using Xcode Xcode를 사용하여 상징화 됨 . . Xcode uses the dSYM file associated with your application binary to replace each address in the Xcode는 응용 프로그램 바이너리와 관련된 dSYM 파일을 사용하여 backtrace 역 추적 with its originating location in your source code. 소스 코드에서 원래 위치와 함께. The result is a symbolicated crash report. 결과는 상징적 인 충돌 보고서입니다.

  7. If the user has opted to share diagnostic data with Apple, or if the user has installed a beta version of your application through TestFlight, the crash report is uploaded to the App Store. 사용자가 Apple과 진단 데이터를 공유하도록 선택했거나 사용자가 TestFlight를 통해 응용 프로그램의 베타 버전을 설치 한 경우 충돌 보고서가 App Store에 업로드됩니다.

  8. The App Store symbolicates the crash report and groups it with similar crash reports. App Store는 충돌 보고서를 상징화하고 유사한 충돌 보고서와 함께 그룹화합니다. This aggregate of similar crash reports is called a Crash Point. 유사한 충돌 보고서의 집합체를 충돌 점이라고합니다.

  9. The symbolicated crash reports are made available to you in Xcode's Crashes organizer. Xcode의 충돌 구성 도구에서 기호화 된 충돌 보고서를 사용할 수 있습니다.

Bitcode 비트 코드

Bitcode is an intermediate representation of a compiled program. 비트 코드는 컴파일 된 프로그램의 중간 표현입니다. When you archive an application with bitcode enabled, the compiler produces binaries containing bitcode rather than machine code. 비트 코드를 활성화 한 상태에서 응용 프로그램을 보관하면 컴파일러에서 기계 코드가 아닌 비트 코드가 포함 된 바이너리를 생성합니다. Once the binary has been uploaded to the App Store, the bitcode is compiled down to machine code. 바이너리가 App Store에 업로드되면 비트 코드가 컴퓨터 코드로 컴파일됩니다. The App Store may compile the bitcode again in the future, to take advantage of future compiler improvements without any action on your part. App Store는 미래의 컴파일러 개선을 활용하기 위해 앞으로도 비트 코드를 다시 컴파일 할 수 있습니다.

Figure 2 Overview of the Bitcode compilation process. 그림 2 그림 2 비트 코드 컴파일 프로세스의 개요.

Because the final compilation of your binary occurs on the App Store, your Mac will not contain the debug symbol ( dSYM ) files needed to symbolicate crash reports received from App Review or from users who have sent you crash reports from their devices. 바이너리의 최종 컴파일은 App Store에서 수행되기 때문에 Mac에 App Review에서받은 오류 보고서 또는 사용자의 기기에서 오류 보고서를 보낸 사용자를 상징하는 데 필요한 디버그 기호 ( dSYM ) 파일이 포함되지 않습니다. Although a dSYM file is produced when you archive your application, it is for the bitcode binary and can not be used to symbolicate crash reports. dSYM 파일은 응용 프로그램을 아카이브 할 때 생성되지만 비트 코드 바이너리 용이므로 충돌 보고서를 나타 내기 위해 사용할 수 없습니다. The App Store makes the dSYM files generated during bitcode compilation available for you to download, from Xcode or from the iTunes Connect website. App Store를 사용하면 Xcode 또는 iTunes Connect 웹 사이트에서 비트 코드 편집 중에 생성 된 dSYM 파일을 다운로드 할 수 있습니다. You must download these dSYM files in order to symbolicate crash reports received from App Review or from users who have sent you crash reports from their devices. App Review 또는 사용자의 기기에서 충돌 보고서를 보낸 사용자로부터받은 오류 보고서를 상징화하려면 이러한 dSYM 파일을 다운로드해야합니다. Crash reports received through the crash reporting service will be symbolicated automatically. 오류보고 서비스를 통해 수신 된 오류 보고서는 자동으로 기호로 표시됩니다.

Downloading the dSYM files from Xcode Xcode에서 dSYM 파일 다운로드

  1. In the Archives organizer, select the archive that you originally submitted to the App Store. Archives 주최자에서 App Store에 원래 제출 한 아카이브를 선택하십시오.

  2. Click the Download dSYMs button. Download dSYMs 버튼을 클릭하십시오.

Xcode downloads the dSYM files and inserts them into the selected archive. Xcode는 dSYM 파일을 다운로드하여 선택한 아카이브에 삽입합니다.

Downloading the dSYM files from the iTunes Connect website iTunes Connect 웹 사이트에서 dSYM 파일 다운로드

  1. Open the App Details page. 앱 세부 정보 페이지를 엽니 다.

  2. Click Activity. 활동을 클릭하십시오.

  3. From the list of All Builds, select a version. 모든 빌드 목록에서 버전을 선택하십시오.

  4. Click the Download dSYM link. Download dSYM 링크를 클릭하십시오.

Translating 'hidden' symbol names back to their original names '숨겨진'기호 이름을 원래 이름으로 다시 변환

When you upload your app with bitcode to the App Store, you may choose not to send your application's symbols by unchecking the "Upload your app's symbols to receive symbolicated reports from Apple" box in the submission dialog. 비트 코드를 사용하여 앱을 App Store에 업로드 할 때 제출 대화 상자의 "Apple에서 기호화 된 보고서를 받기 위해 앱 심볼을 업로드"확인란의 선택을 취소하여 응용 프로그램의 심볼을 보내지 않도록 선택할 수 있습니다. If you choose not to send your app's symbol information to Apple, Xcode will replace the symbols in your app's . 앱의 심볼 정보를 Apple에 보내지 않기로 선택하면 Xcode가 앱의 심볼을 대체합니다. dSYM files with obfuscated symbols such as "__hidden#109_" before sending your app to iTunes Connect. 앱을 iTunes Connect에 보내기 전에 "__hidden # 109_"과 같은 난독 화 된 기호가있는 dSYM 파일. Xcode creates a mapping between the original symbols and the "hidden" symbols and stores this mapping in a .bcsymbolmap file inside the application archive. Xcode는 원본 심볼과 "숨겨진"심볼 사이의 매핑을 .bcsymbolmap 매핑을 응용 프로그램 아카이브 내부의 .bcsymbolmap 파일에 저장합니다. Each . 각각. dSYM file will have a corresponding .bcsymbolmap file. dSYM 파일에는 해당 .bcsymbolmap 파일이 있습니다.

Before symbolicating crash reports, you will need to de-obfuscate the symbols in the . 충돌 보고서를 기호화하기 전에에있는 기호의 난독 화를 제거해야합니다. dSYM files downloaded from iTunes Connect. iTunes Connect에서 다운로드 한 dSYM 파일. If you use the Download dSYMs button in Xcode, this de-obfuscation will be performed automatically for you. Xcode에서 dSYMs 다운로드 버튼을 사용하면이 난독 처리가 자동으로 수행됩니다. However, if you use the iTunes Connect website to download the . 그러나 iTunes Connect 웹 사이트를 사용하여를 다운로드하는 경우. dSYM files, open Terminal and use the following command to de-obfuscate your symbols (replacing the example paths with your own archive and the dSYMs folder downloaded from iTunes Connect): dSYM 파일을 열고 터미널을 열고 다음 명령을 사용하여 심볼의 난독 화를 제거합니다 (예제 경로를 자신의 아카이브로 바꾸고 iTunes Connect에서 다운로드 한 dSYM 폴더를 바꿉니다).

 xcrun dsymutil -symbol-map ~/Library/Developer/Xcode/Archives/2017-11-23/MyGreatApp\ 11-23-17\,\ 12.00\ PM.xcarchive/BCSymbolMaps ~/Downloads/dSYMs/3B15C133-88AA-35B0-B8BA-84AF76826CE0.dSYM xcrun dsymutil -symbol-map ~ / 라이브러리 / Developer / Xcode / Archives / 2017-11-23 / MyGreatApp \ 11-23-17 \, \ 12.00 \ PM.xcarchive / BCSymbolMaps ~ / Downloads / dSYMs / 3B15C133-88AA-35B0 -B8BA-84AF76826CE0.dSYM 

Run this command for each . 각각에 대해이 명령을 실행하십시오. dSYM file inside the dSYMs folder you downloaded. dSYM 파일은 다운로드 한 dSYMs 폴더 안에 있습니다.

Determining Whether a Crash Report is Symbolicated 오류 보고서의 기호화 여부 결정

A crash report may be unsymbolicated, fully symbolicated, or partially symbolicated. 충돌 보고서는 기호화되지 않거나 완전히 기호화되거나 부분적으로 기호화 될 수 있습니다. Unsymbolicated crash reports will not contain the method or function names in the Unsymbolicated crash report에는 메소드 또는 함수 이름이 포함되지 않습니다. backtrace 역 추적 . . Instead, you have hexadecimal addresses of executable code within the loaded binary images. 대신로드 된 바이너리 이미지 내에서 실행 가능한 코드의 16 진수 주소를가집니다. In a fully symbolicated crash report, the hexadecimal addresses in every line of the backtrace are replaced with the corresponding symbol. 완전히 상징화 된 오류 보고서에서는 백 트레이스의 모든 행에있는 16 진수 주소가 해당 기호로 바뀝니다. In a partially symbolicated crash report, only some of the addresses in the backtrace have been replaced with their corresponding symbols. 부분적으로 기호화 된 오류 보고서에서는 백 트레이스의 일부 주소 만 해당 기호로 바뀌 었습니다.

Obviously, you should try to fully symbolicate any crash report you receive as it will provide the most insight about the crash. 분명히 충돌 사고에 대한 통찰력을 가장 잘 전달할 수 있도록 충돌 보고서를 완전히 상징화해야합니다. A partially symbolicated crash report may contain enough information to understand the crash, depending upon the type of crash and which parts of the backtraces were successfully symbolicated. 부분적으로 상징화 된 충돌 보고서에는 충돌 유형 및 성공적으로 상징 된 역 추적의 부분에 따라 충돌을 이해하는 데 충분한 정보가 포함될 수 있습니다. An unsymbolicated crash report is rarely useful. 상징적이지 않은 충돌 보고서는 거의 유용하지 않습니다.

Figure 3 The same backtrace at various levels of symbolication. 그림 3 다양한 상징화 수준에서의 동일한 백 트레이스

Symbolicating iOS Crash Reports With Xcode Xcode로 iOS 크래시 보고서 기호화

Xcode will automatically attempt to symbolicate all crash reports that it encounters. Xcode는 자동으로 충돌 보고서를 모두 나타냅니다. All you need to do for symbolication is to add the crash report to the Xcode Organizer. 상징적으로하기 위해해야 ​​할 일은 크래시 보고서를 Xcode Organizer에 추가하는 것입니다.

  1. Connect an iOS device to your Mac iOS 기기를 Mac에 연결

  2. Choose "Devices" from the "Window" menu "창"메뉴에서 "장치"를 선택하십시오.

  3. Under the "DEVICES" section in the left column, choose a device 왼쪽 열의 '기기'섹션에서 기기를 선택합니다.

  4. Click the "View Device Logs" button under the "Device Information" section on the right hand panel 오른쪽 패널의 "Device Information (장치 정보)"섹션 아래에있는 "View Device Logs (장치 로그보기)"버튼을 클릭하십시오.

  5. Drag your crash report onto the left column of the presented panel 충돌 보고서를 표시된 패널의 왼쪽 열로 드래그하십시오.

  6. Xcode will automatically symbolicate the crash report and display the results Xcode는 자동으로 충돌 보고서를 표시하고 결과를 표시합니다.

To symbolicate a crash report, Xcode needs to be able to locate the following: 충돌 보고서를 나타내려면 Xcode가 다음을 찾을 수 있어야합니다.

  • The crashing application's binary and dSYM file. 충돌하는 응용 프로그램의 바이너리 및 dSYM 파일

  • The binaries and dSYM files for all custom frameworks that the application links against. 응용 프로그램이 링크하는 모든 사용자 정의 프레임 워크의 바이너리 및 dSYM 파일. For frameworks that were built from source with the application, their dSYM files are copied into the archive alongside the application's dSYM file. 응용 프로그램과 함께 소스에서 빌드 된 프레임 워크의 경우, dSYM 파일이 응용 프로그램의 dSYM 파일과 함께 아카이브로 복사됩니다. For frameworks that were built by a third-party, you will need to ask the author for the dSYM file. 제 3자가 만든 프레임 워크의 경우 dSYM 파일을 작성자에게 요청해야합니다.

  • Symbols for the OS that the that application was running on when it crashed. 해당 응용 프로그램이 충돌했을 때 실행중인 OS의 기호. These symbols contain debug information for the frameworks included in a specific OS release (eg iOS 9.3.3). 이 기호는 특정 OS 릴리스 (예 : iOS 9.3.3)에 포함 된 프레임 워크에 대한 디버그 정보를 포함합니다. OS symbols are architecture specific - a release of iOS for 64-bit devices won't include armv7 symbols. OS 기호는 아키텍처에 따라 다릅니다. 64 비트 장치 용 iOS에는 armv7 기호가 포함되지 않습니다. Xcode will automatically copy OS symbols from each device that you connect to your Mac. Xcode는 Mac에 연결하는 각 장치의 OS 심볼을 자동으로 복사합니다.

If any of these are missing Xcode may not be able to symbolicate the crash report, or may only 이 중 하나라도 누락 된 경우 Xcode에서 충돌 보고서를 나타낼 수 없거나 partially symbolicate 부분적으로 상징하다 the crash report. 충돌 보고서.

Symbolicating Crash Reports With atos Atos를 사용한 충돌 보고서 기호화

The 그만큼 atos 아토스 command converts numeric addresses to their symbolic equivalents. 명령은 숫자 주소를 해당 기호로 변환합니다. If full debug symbol information is available then the output of atos will include file name and source line number information. 전체 디버그 기호 정보를 사용할 수있는 경우 atos 의 출력에는 파일 이름과 소스 줄 번호 정보가 포함됩니다. The atos command can be used to symbolicate individual addresses in the backtrace of an unsymbolicated, or partially symbolicated, crash report. atos 명령은 기호화되지 않은 기호 또는 부분적으로 기호화 된 충돌 보고서의 백 트레이스에있는 개별 주소를 나타 내기 위해 사용할 수 있습니다. To symbolicate a part of a crash report using atos : atos 사용하여 충돌 보고서의 일부를 나타 내기 :

  1. Find a line in the 에서 라인 찾기 backtrace 역 추적 which you want to symbolicate. 당신이 상징하기를 원하는 것입니다. Note the name of the binary image in the second column, and the address in the third column. 두 번째 열의 이진 이미지 이름과 세 번째 열의 주소를 기록하십시오.

  2. Look for a binary image with that name in the list of 해당 이름의 이진 이미지를 목록에서 찾으십시오. binary images 이진 이미지 at the bottom of the crash report. 충돌 보고서의 맨 아래에 Note the architecture and load address of the binary image. 이진 이미지의 아키텍처 및로드 주소를 기록하십시오.

Figure 4 Information from the crash report that is needed to use atos . 그림 4 atos 를 사용하는 데 필요한 충돌 보고서의 정보
  1. Locate the dSYM file for the binary. 바이너리에 대한 dSYM 파일을 찾으십시오. You can use Spotlight to find the matching dSYM file for the UUID of the binary image. Spotlight를 사용하여 이진 이미지의 UUID와 일치하는 dSYM 파일을 찾을 수 있습니다. See the Symbolication Troubleshooting section. 기호 문제 해결 절을 참조하십시오. dSYM files are bundles in which reside a file containing the DWARF debugging information generated by the compiler at build time. dSYM 파일은 빌드시 컴파일러에서 생성 된 DWARF 디버깅 정보가 들어있는 파일이있는 번들입니다. You must provide the path to this file, not to the dSYM bundle, when invoking atos . atos 를 호출 할 때 dSYM 번들이 아닌이 파일에 대한 경로를 제공해야합니다.

  2. With the above information you can symbolicate addresses in the backtrace using the atos command. 위의 정보를 사용하여 atos 명령을 사용하여 역 추적의 주소를 나타낼 수 있습니다. You can specify multiple addresses to symbolicate, separated by a space. 공백으로 구분하여 여러 개의 주소를 기호로 지정할 수 있습니다.

    atos -arch <Binary Architecture> -o <Path to dSYM file>/Contents/Resources/DWARF/<binary image name> -l <load address> <address to symbolicate>

Listing 1 Example usage of the atos command following the steps above, and the resulting output. Listing 1 위의 단계와 결과 출력에 따른 atos 명령의 사용 예.

 $ atos -arch arm64 -o TheElements.app.dSYM/Contents/Resources/DWARF/TheElements -l 0x1000e4000 0x00000001000effdc $ atos -arch arm64 -o TheElements.app.dSYM / 내용 / 리소스 / DWARF / TheElements -l 0x1000e4000 0x00000001000effdc 
 -[AtomicElementViewController myTransitionDidStop:finished:context:] - [AtomicElementViewController myTransitionDidStop : finished : 컨텍스트 :] 

Symbolication Troubleshooting 기호 문제 해결

If Xcode is failing to fully symbolicate a crash report, it's likely because your Mac is missing the dSYM file for the application binary, the dSYM files for one or more frameworks the application links against, or the device symbols for the OS the application was running on when it crashed. Xcode에서 충돌 보고서를 완전히 나타내지 못하는 경우 Mac에 응용 프로그램 바이너리의 dSYM 파일, 응용 프로그램이 링크하는 하나 이상의 프레임 워크의 dSYM 파일 또는 응용 프로그램이 실행중인 OS의 장치 기호가 없기 때문입니다 때 그것은 추락했다. The steps below show how to use Spotlight to determine whether the dSYM file needed to symbolicate a backtrace addresse within a binary image is present on your Mac. 아래 단계는 Spotlight를 사용하여 바이너리 이미지 내의 백 트레이스 주소를 나타내는 데 필요한 dSYM 파일이 Mac에 있는지 여부를 확인하는 방법을 보여줍니다.

Figure 5 Locating the UUID for a binary image. 그림 5 이진 이미지의 UUID 찾기
  1. Find a line in the 에서 라인 찾기 backtrace 역 추적 which Xcode failed to symbolicate. 어떤 Xcode가 상징을 나타내지 못했습니다. Note the name of the binary image in the second column. 두 번째 열에있는 이진 이미지의 이름을 기록하십시오.

  2. Look for a binary image with that name in the list of 해당 이름의 이진 이미지를 목록에서 찾으십시오. binary images 이진 이미지 at the bottom of the crash report. 충돌 보고서의 맨 아래에 This list contains the UUIDs for each of the binary images that were loaded into the process at the time of the crash. 이 목록에는 충돌시 프로세스에로드 된 각 2 진 이미지의 UUID가 들어 있습니다.



    Listing 2 You can use the grep command line tool to quickly find the entry in the list of binary images. Listing 2 grep 명령 행 도구를 사용하여 바이너리 이미지 목록에서 항목을 빠르게 찾을 수있다.

     $ grep --after-context=1000 "Binary Images:" <Path to Crash Report> | $ grep --after-context = 1000 "이진 이미지 :"<충돌 보고서 경로> | grep <Binary Name> grep <이진 이름> 
  3. Convert the UUID of the binary image to a 32 character string seperated in groups of 8-4-4-4-12 ( XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX ). 이진 이미지의 UUID를 8-4-4-4-12 ( XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX ) 그룹으로 구분 된 32 자 문자열로 변환하십시오. Note that all letters must be uppercased. 모든 글자 대문자 여야 합니다.

  4. Search for the UUID using the mdfind command line tool using the query "com_apple_xcode_dsym_uuids == <UUID>" (include the quotation marks). 쿼리 "com_apple_xcode_dsym_uuids == <UUID>" (인용 부호 포함)를 사용하여 mdfind 명령 줄 도구를 사용하여 UUID를 검색하십시오.



    Listing 3 Using the mdfind command line tool to search for dSYM files with a given UUID. Listing 3 mdfind 명령 행 도구를 사용하여 주어진 UUID로 dSYM 파일을 검색한다.

     $ mdfind "com_apple_xcode_dsym_uuids == <UUID>" $ mdfind "com_apple_xcode_dsym_uuids == <UUID>" 
  5. If Spotlight finds a dSYM file for the UUID, mdfind will print the path to the dSYM file and possibly its containing archive. Spotlight가 UUID에 대한 dSYM 파일을 찾으면 mdfinddSYM 파일 및 해당 아카이브를 포함하는 경로를 인쇄합니다. If a dSYM file for the UUID was not found, mdfind will exit without printing anything. UUID에 대한 dSYM 파일을 찾을 수 mdfind 는 아무 것도 인쇄하지 않고 종료합니다.

If Spotlight found a dSYM file for the binary but Xcode was not able to symbolicate addresses within that binary image, then you should file a bug. Spotlight가 바이너리의 dSYM 파일을 찾았지만 Xcode가 그 바이너리 이미지 내의 주소를 나타낼 수 없다면 버그를 신고해야합니다. Attach the crash report and the relevant dSYM file(s) to the bug report. 충돌 보고서 및 관련 dSYM 파일을 버그 보고서에 첨부하십시오. As a workaround, you can manually symbolicate the address using atos . 이 문제를 해결하기 위해 atos 사용하여 수동으로 주소를 나타낼 수 있습니다. See Symbolicating Crash Reports With atos . Atos가있는 충돌 보고서 기호화를 참조하십시오.

If Spotlight did not find a dSYM for the binary image, verify that you still have the Xcode archive for the version of your application that crashed and that this archive is located somewhere that Spotlight can find it (any location in your home directory should do). Spotlight가 바이너리 이미지에 대한 dSYM 을 찾지 못하면, 충돌 한 응용 프로그램의 버전에 대한 Xcode 아카이브가 여전히 있는지, 그리고이 아카이브가 Spotlight에서 찾을 수있는 위치에 있는지 확인하십시오 (홈 디렉토리의 모든 위치에서 수행해야 함) . If your application was built with bitcode enabled, make sure you have downloaded the dSYM files for the final compilation from the App Store. 응용 프로그램이 비트 코드를 사용하도록 설정된 경우 App Store에서 최종 편집을위한 dSYM 파일을 다운로드했는지 확인하십시오. See Downloading the dSYM files from Xcode . Xcode에서 dSYM 파일 다운로드를 참조하십시오.

If you think that you have the correct dSYM for the binary image, you can use the dwarfdump command to print the matching UUIDs. 바이너리 이미지에 대해 올바른 dSYM 이 있다고 생각되면 dwarfdump 명령을 사용하여 일치하는 UUID를 인쇄 할 수 있습니다. You can also use the dwarfdump command to print the UUIDs of a binary. dwarfdump 명령을 사용하여 이진의 UUID를 인쇄 할 수도 있습니다.

xcrun dwarfdump --uuid <Path to dSYM file>

If you no longer have this archive, you should submit a new version of your application for which you retain the archive. 더 이상이 아카이브가 없으면 아카이브를 보유하고있는 새 버전의 응용 프로그램을 제출해야합니다. You will then be able to symbolicate crash reports for this new version. 그러면이 새 버전에 대한 오류 보고서를 나타낼 수 있습니다.

Analyzing Crash Reports 오류 보고서 분석

This section discusses each of the sections found within a standard crash report. 이 섹션에서는 표준 충돌 보고서에있는 각 섹션에 대해 설명합니다.

Header 머리글

Every crash report begins with a header. 모든 충돌 보고서는 머리글로 시작됩니다.

Listing 4 Excerpt of the header from a crash report. Listing 4 충돌 보고서의 헤더 발췌 록.

 Incident Identifier: B6FD1E8E-B39F-430B-ADDE-FC3A45ED368C 인시던트 식별자 : B6FD1E8E-B39F-430B-ADDE-FC3A45ED368C 
 CrashReporter Key: f04e68ec62d3c66057628c9ba9839e30d55937dc CrashReporter 키 : f04e68ec62d3c66057628c9ba9839e30d55937dc 
 Hardware Model: iPad6,8 하드웨어 모델 : iPad6,8 
 Process: TheElements [303] 프로세스 : TheElements [303] 
 Path: /private/var/containers/Bundle/Application/888C1FA2-3666-4AE2-9E8E-62E2F787DEC1/TheElements.app/TheElements 경로 : /private/var/containers/Bundle/Application/888C1FA2-3666-4AE2-9E8E-62E2F787DEC1/TheElements.app/TheElements 
 Identifier: com.example.apple-samplecode.TheElements 식별자 : com.example.apple-samplecode.TheElements 
 Version: 1.12 버전 : 1.12 
 Code Type: ARM-64 (Native) 코드 유형 : ARM-64 (기본) 
 Role: Foreground 역할 : 포 그라운드 
 Parent Process: launchd [1] 학부모 과정 : launchd [1] 
 Coalition: com.example.apple-samplecode.TheElements [402] Coalition : com.example.apple-samplecode.TheElement [402] 
 Date/Time: 2016-08-22 10:43:07.5806 -0700 날짜 / 시간 : 2016-08-22 10 : 43 : 07.5806 -0700 
 Launch Time: 2016-08-22 10:43:01.0293 -0700 시작 시간 : 2016-08-22 10 : 43 : 01.0293 -0700 
 OS Version: iPhone OS 10.0 (14A5345a) OS 버전 : iPhone OS 10.0 (14A5345a) 
 Report Version: 104 보고서 버전 : 104 

Most of the fields are self-explanatory but a few deserve special note: 대부분의 필드는 자명하지만 몇 가지 특별한주의가 필요합니다.

  • Incident Identifier : A unique identifier for the report. 사건 식별자 : 보고서의 고유 식별자입니다. Two reports will never share the same Incident Identifier. 두 개의 보고서는 절대로 동일한 인시던트 식별자를 공유하지 않습니다.

  • CrashReporter Key : An anonymized per-device identifier. CrashReporter 키 : 익명화 된 장치 별 식별자입니다. Two reports from the same device will contain identical values. 동일한 기기의 두 보고서에는 동일한 값이 포함됩니다.

  • Beta Identifier : A unique identifier for the combination of the device and vendor of the crashed application. 베타 식별자 : 충돌 한 응용 프로그램의 장치와 공급 업체의 조합에 대한 고유 식별자입니다. Two reports for applications from the same vendor and from the same device will contain identical values. 동일한 공급 업체 및 동일한 장치의 응용 프로그램에 대한 두 개의 보고서에는 동일한 값이 포함됩니다. This field is only present in crash reports generated for applications distributed through TestFlight, and replaces the CrashReporter Key field. 이 필드는 TestFlight를 통해 배포 된 응용 프로그램에 대해 생성 된 오류 보고서에만 나타나며 CrashReporter 키 필드를 대체합니다.

  • Process : The executable name for the process that crashed. 프로세스 : 충돌 한 프로세스의 실행 파일 이름입니다. This matches the value for the CFBundleExecutable key in the application's information property list. 이 값은 응용 프로그램의 정보 속성 목록에있는 CFBundleExecutable 키 값과 일치합니다.

  • Version : The version of the process that crashed. 버전 : 충돌 한 프로세스의 버전입니다. The value for this field is a concatenation of the crashed application's CFBundleVersion and CFBundleVersionString . 이 필드의 값은 충돌 한 응용 프로그램의 CFBundleVersionCFBundleVersionString 의 연결입니다.

  • Code Type : The target architecture of the process that crashed. 코드 유형 : 충돌 한 프로세스의 대상 아키텍처. This will be one of ARM-64 , ARM , x86-64 , or x86 . 이것은 ARM-64 , ARM , x86-64 또는 x86 중 하나입니다.

  • Role : The task_role assigned to the process at the time of termination. 역할 : 종료시 프로세스에 할당 된 task_role .

  • OS Version : The OS version, including the build number, on which the crash occurred. OS 버전 : 충돌이 발생한 빌드 번호를 포함한 OS 버전입니다.

Exception Information 예외 정보

Not to be confused with Objective-C/C++ exceptions (though one of those may be the cause of the crash), this section lists the Mach Exception Type and related fields which provide information about the nature of the crash. Objective-C / C ++ 예외 (그 중 하나가 충돌의 원인 일 수 있음)와 혼동해서는 안되지만,이 절에서는 충돌의 특성에 대한 정보를 제공하는 Mach Exception Type 및 관련 필드를 나열합니다. Not all fields will be present in every crash report. 모든 오류 보고서에 모든 입력란이 표시되지는 않습니다.

Listing 5 Excerpt of the Exception Codes section from a crash report generated when a process was terminated due to an uncaught Objective-C exception. Listing 5 포착되지 않은 Objective-C 예외로 인해 프로세스가 종료되었을 때 생성 된 충돌 보고서의 Exception Codes 섹션을 보여준다.

 Exception Type: EXC_CRASH (SIGABRT) 예외 유형 : EXC_CRASH (SIGABRT) 
 Exception Codes: 0x0000000000000000, 0x0000000000000000 예외 코드 : 0x0000000000000000, 0x0000000000000000 
 Exception Note: EXC_CORPSE_NOTIFY 예외 주 : EXC_CORPSE_NOTIFY 
 Triggered by Thread: 0 스레드에 의해 트리거 된 : 0 

Listing 6 Excerpt of the Exception Codes section from a crash report generated when a process was terminated because it dereferenced a NULL pointer. Listing 6 NULL 포인터를 역 참조했기 때문에 프로세스가 종료되었을 때 생성 된 오류 보고서의 Exception Codes 섹션을 발췌 한 것이다.

 Exception Type: EXC_BAD_ACCESS (SIGSEGV) 예외 유형 : EXC_BAD_ACCESS (SIGSEGV) 
 Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000 예외 하위 유형 : KERN_INVALID_ADDRESS (0x0000000000000000) 
 Termination Signal: Segmentation fault: 11 종단 신호 : 분할 오류 : 11 
 Termination Reason: Namespace SIGNAL, Code 0xb 종료 이유 : 네임 스페이스 SIGNAL, 코드 0xb 
 Terminating Process: exc handler [0] 프로세스 종료 : exc 핸들러 [0] 
 Triggered by Thread: 0 스레드에 의해 트리거 된 : 0 

An explanation of the fields that may appear in this section are presented below. 이 섹션에 나타날 수있는 필드에 대한 설명이 아래에 나와 있습니다.

  • Exception Codes : Processor specific information about the exception encoded into one or more 64-bit hexadecimal numbers. 예외 코드 : 하나 이상의 64 비트 16 진수로 인코딩 된 예외에 대한 프로세서 관련 정보입니다. Typically, this field will not be present because the Crash Reporter parses the exception codes to present them as a human-readable description in the other fields. 일반적으로이 필드는 Crash Reporter가 예외 코드를 구문 분석하여 다른 필드에 사람이 읽을 수있는 설명으로 표시하기 때문에 표시되지 않습니다.

  • Exception Subtype : The human-readable name of the exception codes. Exception Subtype : 사람이 읽을 수있는 예외 코드의 이름.

  • Exception Message : Additional human-readable information extracted from the exception codes. 예외 메시지 : 예외 코드에서 추출한 사람이 읽을 수있는 추가 정보.

  • Exception Note : Additional information that is not specific to one exception type. 예외 참고 사항 : 하나의 예외 유형과 관련된 추가 정보. If this field contains SIMULATED (this is NOT a crash) then the process did not crash, but was killed at the request of the system, typically the watchdog. 이 필드에 SIMULATED (this is NOT a crash) 가 포함되어 있으면 SIMULATED (this is NOT a crash) 프로세스가 충돌하지 않았지만 시스템 요청 (일반적으로 워치 독)에 종료되었습니다.

  • Termination Reason : Exit reason information specified when a process is terminated. 종료 이유 : 프로세스가 종료 될 때 지정된 종료 이유 정보. Key system components, both inside and outside of a process, will terminate the process upon encountering a fatal error (eg a bad code signature, a missing dependent library, or accessing privacy sensitive information without the proper entitlement). 프로세스 내부 및 외부의 주요 시스템 구성 요소는 치명적인 오류 (예 : 잘못된 코드 서명, 누락 된 종속 라이브러리 또는 적절한 권한없이 개인 정보 보호 정보에 액세스)가 발생하면 프로세스를 종료합니다. macOS Sierra, iOS 10, watchOS 3, and tvOS 10 have adopted new infrastructure to record these errors, and crash reports generated by these operating systems list the error messages in the Termination Reason field. macOS Sierra, iOS 10, watchOS 3 및 tvOS 10은 이러한 오류를 기록하기 위해 새로운 인프라를 채택했으며 이러한 운영 체제에서 생성 된 오류 보고서는 Termination Reason 필드에 오류 메시지를 나열합니다.

  • Triggered by Thread : The thread on which the exception originated. Triggered by Thread : 예외가 발생한 스레드입니다.

The following sections explain some of the most common exception types: 다음 섹션에서는 가장 일반적인 예외 유형 중 일부를 설명합니다.

Bad Memory Access [EXC_BAD_ACCESS // SIGSEGV // SIGBUS] 잘못된 메모리 액세스 [EXC_BAD_ACCESS // SIGSEGV // SIGBUS]

The process attempted to access invalid memory, or it attempted to access memory in a manner not allowed by the memory's protection level (eg writing to read-only memory). 프로세스가 유효하지 않은 메모리에 액세스하려고했거나 메모리 보호 수준 (예 : 읽기 전용 메모리에 쓰기)에서 허용하지 않는 방식으로 메모리에 액세스하려고 시도했습니다. The Exception Subtype field contains a kern_return_t describing error and the address of the memory that was incorrectly accessed. Exception Subtype 필드는 오류를 설명하는 kern_return_t 와 부정확하게 액세스 된 메모리의 주소를 포함합니다.

Here are some tips for debugging a bad memory access crash: 다음은 잘못된 메모리 액세스 충돌을 디버깅하기위한 몇 가지 팁입니다.

  • If objc_msgSend or objc_release are near the top of the Backtraces for the crashed thread, the process may have attempted to message a deallocated object. objc_msgSend 또는 objc_release 가 충돌 한 스레드의 objc_release 맨 위에 있으면 프로세스가 할당 해제 된 객체를 메시지로 보내려고 시도했을 수 있습니다. You should profile the application with the Zombies instrument to better understand the conditions of this crash. 이 충돌 상황을 더 잘 이해하려면 좀비 도구 로 응용 프로그램의 프로필을 작성해야합니다.

  • If gpus_ReturnNotPermittedKillClient is near the top of the Backtraces for the crashed thread, the process was killed because it attempted to do rendering with OpenGL ES or Metal while in the background. gpus_ReturnNotPermittedKillClient 가 충돌 한 스레드의 Backtraces 상단 근처에 있으면 gpus_ReturnNotPermittedKillClient 에서 OpenGL ES 또는 Metal로 렌더링을 시도했기 때문에 프로세스가 종료되었습니다. See QA1766: How to fix OpenGL ES application crashes when moving to the background . QA1766 : 배경으로 이동할 때 OpenGL ES 응용 프로그램 충돌을 해결하는 방법을 참조하십시오.

  • Run your application with the Address Sanitizer enabled. Address Sanitizer가 활성화 된 상태에서 응용 프로그램을 실행하십시오. The address sanitizer adds additional instrumentation around memory access in your compiled code. 주소 새 니타 이저는 컴파일 된 코드에서 메모리 액세스와 관련된 추가 수단을 추가합니다. As your application runs, Xcode will alert you if memory is accessed in a way that could lead to a crash. 응용 프로그램이 실행되면 충돌로 이어질 수있는 방식으로 메모리에 액세스하는 경우 Xcode에서 경고합니다.

Abnormal Exit [EXC_CRASH // SIGABRT] 비정상 종료 [EXC_CRASH // SIGABRT]

The process exited abnormally. 프로세스가 비정상적으로 종료되었습니다. The most common causes of crashes with this exception type are uncaught Objective-C/C++ 이 예외 유형으로 인한 가장 일반적인 충돌 원인은 catch되지 않습니다. Objective-C / C ++ exceptions 예외 and calls to abort() . abort() 호출합니다.

App Extensions will be terminated with this exception type if they take too much time to initialize (a watchdog termination). 초기화에 너무 많은 시간이 소요되는 경우 (워치 독 종료) 앱 확장이이 예외 유형으로 종료됩니다. If an extension is killed due to a hang at launch, the Exception Subtype of the generated crash report will be LAUNCH_HANG . 시작시 정지로 인해 확장 프로그램이 종료 된 경우 생성 된 오류 보고서의 Exception SubtypeLAUNCH_HANG 입니다. Because extensions do not have a main function, any time spent initializing occurs within static constructors and +load methods present in your extension and dependent libraries. 확장 기능에는 main 기능이 없기 때문에 확장 초기화 및 종속 라이브러리에있는 정적 생성자 및 +load 메소드 내에서 초기화하는 데 소요되는 시간이 소요됩니다. You should defer as much of this work as possible. 가능한 한이 작업을 연기해야합니다.

Trace Trap [EXC_BREAKPOINT // SIGTRAP] 추적 함정 [EXC_BREAKPOINT // SIGTRAP]

Similar to an 비슷한 Abnormal Exit 비정상 종료 , this exception is intended to give an attached debugger the chance to interrupt the process at a specific point in its execution. ,이 예외는 첨부 된 디버거가 실행중인 특정 지점에서 프로세스를 중단 할 수있는 기회를주기위한 것입니다. You can trigger this exception from your own code using the __builtin_trap() function. __builtin_trap() 함수를 사용하여 코드에서이 예외를 트리거 할 수 있습니다. If no debugger is attached, the process is terminated and a crash report is generated. 디버거가 연결되어 있지 않으면 프로세스가 종료되고 오류 보고서가 생성됩니다.

Lower-level libraries (eg libdispatch) will trap the process upon encountering a fatal error. 하위 수준 라이브러리 (예 : libdispatch)는 치명적인 오류가 발생하면 프로세스를 트랩합니다. Additional information about the error can be found in the Additional Diagnostic Information section of the crash report, or in the device's console. 오류에 대한 추가 정보는 오류 보고서의 추가 진단 정보 섹션이나 장치 콘솔에 있습니다.

Swift code will terminate with this exception type if an unexpected condition is encountered at runtime such as: 런타임시 예기치 않은 조건이 발생하면 Swift 코드가이 예외 유형으로 종료됩니다.

  • a non-optional type with a nil value nil 값을 가진 비 선택적 유형

  • a failed forced type conversion 강제 형 변환 실패

Look at the Backtraces to determine where the unexpected condition was encountered. Backtraces 를보고 예기치 않은 상황이 발생했는지 확인하십시오. Additional information may have also been logged to the device's console. 추가 정보가 장치의 콘솔에 기록되었을 수도 있습니다. You should modify the code at the crashing location to gracefully handle the runtime failure. 런타임 오류를 적절히 처리하려면 충돌 위치의 코드를 수정해야합니다. For example, use Optional Binding instead of force unwrapping an optional. 예를 들어, 선택 사항 을 언 래핑하는 대신 선택적 바인딩을 사용하십시오.

Illegal Instruction [EXC_BAD_INSTRUCTION // SIGILL] 불법 명령어 [EXC_BAD_INSTRUCTION // SIGILL]

The process attempted to execute an illegal or undefined instruction. 프로세스가 불법적이거나 정의되지 않은 명령을 실행하려고 시도했습니다. The process may have attempted to jump to an invalid address via a misconfigured function pointer. 프로세스가 잘못 구성된 함수 포인터를 통해 잘못된 주소로 점프하려고 시도했을 수 있습니다.

On Intel processors, the ud2 opcode causes an EXC_BAD_INSTRUCTION exception but is commonly used to trap the process for debugging purposes. Intel 프로세서에서 ud2 연산 코드는 EXC_BAD_INSTRUCTION 예외를 발생 시키지만 일반적으로 디버깅 목적으로 프로세스를 트래핑하는 데 사용됩니다. Swift code on Intel processors will terminate with this exception type if an unexpected condition is encountered at runtime. 런타임시 예기치 않은 상황이 발생하면 Intel 프로세서의 신속한 코드가이 예외 유형으로 종료됩니다. See 만나다 Trace Trap 추적 함정 for details. 자세한 내용은

Quit [SIGQUIT] 종료 [SIGQUIT]

The process was terminated at the request of another process with privileges to manage its lifetime. 이 프로세스는 수명을 관리 할 권한이있는 다른 프로세스의 요청으로 종료되었습니다. SIGQUIT does not mean that the process crashed, but it did likely misbehave in a detectable manner. SIGQUIT 은 프로세스가 추락 한 것을 의미하지는 않지만 감지 할 수있는 방식으로 오작동했을 가능성이 높습니다.

On iOS, keyboard extensions will be quit by the host app if they take too long to load. iOS에서는 키보드 앱이 너무 오래 걸리면 키보드 앱이 종료됩니다. It's unlikely that the Backtraces shown in the crash report will point to the responsible code. 충돌 보고서에 표시된 Backtraces 가 담당 코드를 가리킬 가능성은 거의 없습니다. Most likely, some other code along the startup path for the extension has taken a long time to complete but finished before the time limit, and execution moved onto the code shown in the Backtraces when the extension was quit. 대부분 확장 프로그램의 시작 경로에있는 일부 코드는 완료하는 데 오랜 시간이 걸렸지 만 제한 시간 전에 끝났으며 확장이 종료 될 때 백 트레 이스에 표시된 코드로 이동했습니다. You should profile the extension to better understand where most of the work during startup is occurring, and move that work to a background thread or defer it until later (after the extension has loaded). 시작하는 동안 대부분의 작업이 발생하는 곳을보다 잘 이해하고 해당 작업을 백그라운드 스레드로 옮기거나 나중에 (확장이로드 된 후)까지 지연시켜야합니다.

Killed [SIGKILL] 살해 된 [SIGKILL]

The process was terminated at the request of the system. 시스템의 요청에 따라 프로세스가 종료되었습니다. Look at the Termination Reason field to better understand the cause of the termination. 해지의 원인 을 더 잘 이해하려면 해지 이유 필드를 확인하십시오.

The Termination Reason field will contain a namespace followed by a code. Termination Reason 필드에는 네임 스페이스 뒤에 코드가옵니다. The following codes are specific to watchOS: 다음 코드는 watchOS에만 해당됩니다.

  • The termination code 0xc51bad01 indicates that a watch app was terminated because it used too much CPU time while performing a background task. 종료 코드 0xc51bad01 은 백그라운드 작업을 수행하는 동안 너무 많은 CPU 시간을 사용했기 때문에 시계 응용 프로그램이 종료되었음을 나타냅니다. To address this issue, optimize the code performing the background task to be more CPU efficient, or decrease the amount of work that the app performs while running in the background. 이 문제를 해결하려면 백그라운드 작업을 수행하는 코드를보다 효율적으로 CPU를 최적화하거나 백그라운드에서 실행하는 동안 앱이 수행하는 작업량을 줄이십시오.

  • The termination code 0xc51bad02 indicates that a watch app was terminated because it failed to complete a background task within the allocated time. 종료 코드 0xc51bad02 는 할당 된 시간 내에 백그라운드 작업을 완료하지 못하여 시계 응용 프로그램이 종료되었음을 나타냅니다. To address this issue, decrease the amount of work that the app performs while running in the background. 이 문제를 해결하려면 백그라운드에서 실행하는 동안 앱이 수행하는 작업량을 줄입니다.

  • The termination code 0xc51bad03 indicates that a watch app failed to complete a background task within the allocated time, and the system was sufficiently busy overall that the app may not have received much CPU time with which to perform the background task. 종료 코드 0xc51bad03 은 감시 응용 프로그램이 할당 된 시간 내에 백그라운드 작업을 완료하지 못했음을 나타내며 시스템이 백그라운드 작업을 수행하는 데 많은 CPU 시간을받지 못했을 정도로 전반적으로 충분히 바빴습니다. Although an app may be able to avoid the issue by reducing the amount of work it performs in the background task, 0xc51bad03 does not indicate that the app did anything wrong. 앱이 백그라운드 작업에서 수행하는 작업량을 줄임으로써 문제를 피할 수는 있지만 0xc51bad03 은 앱이 잘못되었음을 나타내지 않습니다. More likely, the app wasn't able to complete its work because of overall system load. 전체 시스템로드로 인해 앱이 작업을 완료하지 못했을 가능성이 큽니다.

Guarded Resource Violation [EXC_GUARD] 보호 된 리소스 위반 [EXC_GUARD]

The process violated a guarded resource protection. 프로세스가 보호 된 리소스 보호를 위반했습니다. System libraries may mark certain file descriptors as guarded , after which normal operations on those descriptors will trigger an EXC_GUARD exception (when it wants to operate on these file descriptors, the system uses special 'guarded' private APIs). 시스템 라이브러리는 특정 파일 디스크립터를 보호 된 것으로 표시 할 수 있습니다. 그런 다음 해당 디스크립터에 대한 정상적인 작업으로 인해 EXC_GUARD 예외가 트리거됩니다 (이러한 파일 설명자에서 작동하려면 시스템에서 특수한 보호 된 개인 API를 사용합니다). This helps you quickly track down issues such as closing a file descriptor that had been opened by a system library. 이렇게하면 시스템 라이브러리에서 열었던 파일 설명자를 닫는 것과 같은 문제를 신속하게 추적하는 데 도움이됩니다. For example, if an app closes the file descriptor used to access the SQLite file backing a Core Data store, Core Data would then crash mysteriously much later on. 예를 들어, 응용 프로그램이 코어 데이터 저장소를 뒷받침하는 SQLite 파일에 액세스하는 데 사용되는 파일 설명자를 닫으면 핵심 데이터가 나중에 매우 신비하게 충돌합니다. The guard exception gets these problems noticed sooner, and thus makes them easier to debug. 가드 예외는 이러한 문제가 더 일찍 발견되어 디버그하기 쉽게 만듭니다.

Crash reports from newer versions of iOS include human-readable details about the operation that caused the EXC_GUARD exception in the Exception Subtype and Exception Message fields. 최신 버전의 iOS에서 발생하는 오류 보고서에는 Exception Subtype (예외 유형)Exception Message (예외 메시지) 필드에 EXC_GUARD 예외가 발생한 작업에 대한 인간이 읽을 수있는 세부 정보가 포함되어 있습니다. In crash reports from macOS or older versions of iOS, this information is encoded into the first Exception Code as a bitfield which breaks down as follows: macOS 또는 이전 버전의 iOS에서 발생한 오류 보고서에서이 정보는 다음과 같이 세분화 된 비트 필드로 첫 번째 예외 코드 로 인코딩됩니다.

  • [63:61] - Guard Type : The type of the guarded resource. [63:61] - Guard Type : 보호 된 리소스의 유형입니다.값은 0x2자원이 파일 설명자임 나타냅니다.

  • [60:32] - 풍미 : 위반이 유발 된 조건.

    • 첫 번째 (1 << 0)비트가 설정되면 프로세스 close()는 보호 된 파일 설명자를 호출하려고 시도합니다 .

    • 두 번째 경우 (1 << 1)비트가 설정되어, 프로세스는 호출을 시도 dup(), dup2()또는 fcntl()으로 F_DUPFD또는 F_DUPFD_CLOEXEC명령을 지키고 파일 기술자에.

    • 세 번째 (1 << 2)비트가 설정되면 프로세스는 소켓을 통해 보호 된 파일 설명자를 보내려고했습니다.

    • 다섯 번째 (1 << 4)비트가 설정되면 프로세스는 보호 된 파일 설명자에 쓰려고 시도합니다.

  • [31 : 0] - File Descriptor : 프로세스가 수정하려고 시도한 보호 된 파일 설명자.

리소스 제한 [EXC_RESOURCE]

프로세스가 자원 소비 한도를 초과했습니다. 이것은 프로세스가 너무 많은 자원을 사용하고 있다는 OS로부터의 알림입니다. 정확한 자원은 Exception Subtype 필드에 나열됩니다 . 경우 예외 참고 필드가 포함되어 NON-FATAL CONDITION, 프로세스가 충돌 보고서가 생성 된 경우에도 사망하지 않았다.

  • 예외 하위 유형 MEMORY은 프로세스가 시스템에서 부과 한 메모리 제한을 초과했음을 나타냅니다. 이는 과도한 메모리 사용을위한 종료의 전조 일 수 있습니다.

  • 예외 하위 유형 WAKEUPS은 프로세스의 스레드가 초당 너무 많은 시간에 깨어나고 있음을 나타내며 CPU가 자주 깨어나고 배터리 수명을 소모합니다.

    일반적으로 이것은 스레드 간 통신 (일반적으로 peformSelector:onThread:또는을 사용 dispatch_async) 에 의해 발생 합니다. 이는 무의식 중에 발생하는 것보다 훨씬 자주 발생합니다. 이 예외를 유발하는 일종의 통신이 너무 자주 발생하기 때문에 통신이 시작되는 위치를 나타내는 매우 유사한 Backtraces가 있는 여러 배경 스레드가 일반적으로 있습니다 .

기타 예외 유형

일부 오류 보고서에는 16 진수 값 (예 : 00000020)으로 인쇄되는 이름이 지정되지 않은 예외 유형 이 포함될 수 있습니다 . 이러한 오류 보고서 중 하나가 표시되면 예외 코드 필드를 직접 확인하여 자세한 내용을 확인하십시오.

  • 예외 코드 0xbaaaaaad는 로그가 충돌 보고서가 아닌 전체 시스템의 스택 샷임을 나타냅니다. 스택 샷을 찍으려면 측면 버튼과 두 볼륨 버튼을 동시에 누르십시오. 종종 이러한 로그는 사용자가 실수로 생성 한 것이며 오류를 나타내지는 않습니다.

  • 예외 코드 0xbad22222는 VoIP 응용 프로그램이 너무 자주 다시 시작 되었기 때문에 iOS에서 종료되었음을 나타냅니다.

  • 예외 코드 0x8badf00d는 워치 독 시간 초과가 발생하여 응용 프로그램이 iOS에 의해 종료되었음을 나타냅니다. 애플리케이션이 시스템 이벤트를 시작, 종료 또는 응답하는 데 너무 오래 걸렸습니다. 이것의 하나의 공통적 인 원인은 주 스레드에서 동기 네트워킹을하는 것 입니다. 어떤 작업이든지 Thread 0백그라운드 스레드로 이동하거나 다르게 처리해야하므로 메인 스레드를 차단하지 않아야합니다.

  • 예외 코드 0xc00010ff는 앱이 열 이벤트에 응답하여 운영 체제에 의해 종료되었음을 나타냅니다. 이것은 충돌이 발생한 특정 장치 또는 작동 환경에 의한 것일 수 있습니다. 앱을보다 효율적으로 실행하기위한 팁은 Instrument WWDC 세션의 iOS 성능 및 전력 최적화를 참조하십시오 .

  • 예외 코드 0xdead10cc는 응용 프로그램이 일시 중지 중에 파일 잠금 또는 sqlite 데이터베이스 잠금을 유지했기 때문에 응용 프로그램이 OS에 의해 종료되었음을 나타냅니다. 응용 프로그램이 일시 중지 된 파일 이나 sqlite 데이터베이스 에 대한 작업을 수행하는 경우 해당 작업을 완료하고 일시 중단되기 전에 잠금을 해제하려면 추가 백그라운드 실행 시간요청 해야합니다 .

  • 예외 코드 0x2bad45ec는 보안 위반으로 인해 애플리케이션이 iOS에 의해 종료되었음을 나타냅니다. 종료 설명 "보안 모드에서 보안되지 않은 그림을 처리하는 중 프로세스가 감지되었습니다"는 화면 잠금 상태와 같이 허용되지 않을 때 화면에 그려진 응용 프로그램을 나타냅니다. 이 종료가 발생할 때 화면이 꺼 지거나 잠금 화면이 표시되므로 사용자는이 종료를 알지 못할 수 있습니다.

추가 진단 정보

이 섹션에는 해지 유형과 관련된 다음과 같은 추가 진단 정보가 포함됩니다.

  • 응용 프로그램 특정 정보 : 프로세스가 종료되기 직전에 캡처 한 프레임 워크 오류 메시지

  • 커널 메시지 : 코드 서명 문제에 대한 세부 정보

  • Dyld 오류 메시지 : 동적 링커가 생성 한 오류 메시지

macOS Sierra, iOS 10, watchOS 3, tvOS 10에서 시작하여이 정보의 대부분은 이제 예외 정보 아래 Termination Reason 필드에 보고됩니다 .

프로세스가 종료 된 상황을 더 잘 이해하려면이 섹션을 읽어야합니다.

Listing 7 링크 된 프레임 워크를 찾을 수 없어 프로세스가 종료되었을 때 생성 된 오류 보고서의 Application Specific Information 섹션 발췌.

 Dyld Error Message: 오류 메시지 : 
 메시지 : 라이브러리로드되지 않음 : @ rpath / MyCustomFramework.framework / MyCustomFramework 
 Referenced from : /private/var/containers/Bundle/Application/CD9DB546-A449-41A4-A08B-87E57EE11354/TheElements.app/TheElements 
 이유 : 적합한 이미지를 찾을 수 없습니다. 

Listing 8 초기 뷰 컨트롤러를 빠르게로드하지 못해 프로세스가 종료되었을 때 생성 된 오류 보고서의 Application Specific Information 섹션 발췌.

 응용 프로그램 특정 정보 : 
 com.example.apple-samplecode.TheElements는 19.81 초 후에 씬 생성에 실패했습니다 (출시에는 총 제한 시간 20.00 초의 0.19 초 소요) 
 경과 된 전체 CPU 시간 (초) : 7.690 (사용자 7.690, 시스템 0.000), 19 % CPU 
 경과 된 응용 프로그램 CPU 시간 (초) : 0.697, 2 % CPU 

백 트레이시

충돌 보고서의 가장 흥미로운 부분은 프로세스가 종료 된 시점의 각 스레드에 대한 백 트레이스입니다. 이러한 각 추적은 디버거를 사용하여 프로세스를 일시 중지 할 때 표시되는 것과 유사합니다.

Listing 9 완벽하게 상징화 된 충돌 보고서에서 백 트레이스 섹션 발췌.

 스레드 0 이름 : 발송 대기열 : com.apple.main-thread 
 스레드 0 크래시 : 
 0 TheElements 0x000000010006bc20 - [AtomicElementViewController myTransitionDidStop : finished : 컨텍스트 :] (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.m : 55) 
 13 libdyld.dylib 0x000000018dda05b8 시작 + 4 
 주제 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 
 ... ... 

첫 번째 행은 스레드 번호와 현재 실행중인 디스패치 대기열의 식별자를 나열합니다. 나머지 줄은 백 트레이스의 개별 스택 프레임에 대한 세부 정보를 나열합니다. 왼쪽에서 오른쪽으로:

  • 스택 프레임 번호. 스택 프레임은 호출 순서대로 표시됩니다. 여기서 프레임 0은 실행이 중단 된 시점에 실행중인 함수입니다. 프레임 1은 프레임 0에서 함수를 호출 한 함수입니다.

  • 스택 프레임에 대한 실행 기능이 상주하는 바이너리의 이름.

  • 프레임 0의 경우 실행이 중단되었을 때 실행중인 기계 명령어의 주소가 중지됩니다. 나머지 스택 프레임의 경우 제어가 스택 프레임으로 반환 될 때 다음에 실행할 기계 명령어의 주소입니다.

  • In a 안에 symbolic crash report, 스택 프레임에있는 함수의 메소드 이름.

Exceptions 예외

Objective-C의 예외는 런타임에 발견 된 프로그래밍 오류를 나타냅니다. 예를 들어 범위를 벗어난 색인이있는 배열에 액세스하거나 변경 불가능한 객체를 변경하려고하거나 프로토콜의 필수 메소드를 구현하지 않거나 수신기가 인식하지 못합니다.

예외가 포착되지 않으면 캐치되지 않는 예외 핸들러라는 함수에 의해 인터셉트됩니다. 기본 uncaught 예외 처리기는 예외 메시지를 장치의 콘솔에 기록한 다음 프로세스를 종료합니다. 예외 역 추적 만이 마지막 예외 역 추적 섹션 아래에 생성 된 오류 보고서에 작성됩니다 ( 목록 10 참조). . .예외 메시지는 오류 보고서에서 생략됩니다. Last Exception Backtrace 가있는 충돌 보고서를 받으면 예외 를 유발 한 조건을 더 잘 이해하기 위해 원래 장치에서 콘솔 로그를 얻어야합니다.

Listing 10 unsymbolicated crash report의 마지막 예외 역 추적 (backtrace) 섹션의 발췌.

 마지막 예외 Backtrace : 
 (0x18eee41c0 0x18d91c55c 0x18eee3e88 0x18f8ea1a0 0x195013fe4 0x1951acf20 0x18ee03dc4 0x1951ab8f4 0x195458128 0x19545fa20 0x19545fc7c 0x19545ff70 0x194de4594 0x194e94e8c 0x194f47d8c 0x194f39b40 0x194ca92ac 0x18ee917dc 0x18ee8f40c 0x18ee8f89c 0x18edbe048 0x19083f198 0x194d21bd0 0x194d1c908 0x1000ad45c 0x18dda05b8) 

16 진수 주소 만 포함하는 마지막 예외 Backtrace가있는 충돌 로그는 사용 가능한 백 트레이스를 생성하기 위해 심볼로 표시되어야합니다 ( Listing 11 참조). . .

Listing 11 상징적 인 충돌 보고서의 마지막 예외 역 추적 섹션의 발췌. 이 예외는 앱의 스토리 보드에 장면을로드 할 때 발생합니다. 장면의 요소에 대한 연결에 해당하는 IBOutlet이 누락되었습니다.

 마지막 예외 Backtrace : 
 0 CoreFoundation 0x18eee41c0 __exceptionPreprocess + 124 
 1 libobjc.A.dylib 0x18d91c55c objc_exception_throw + 56 
 2 CoreFoundation 0x18eee3e88 - [NSException raise] + 12 
 3 기초 0x18f8ea1a0 - [NSObject (NSKeyValueCoding) setValue : forKey :] + 272 
 4 UIKit 0x195013fe4 - [UIViewController setValue : forKey :] + 104 
 5 UIKit 0x1951acf20 - [UIRuntimeOutletConnection 연결] + 124 
 6 CoreFoundation 0x18ee03dc4 - [NSArray makeObjectsPerformSelector :] + 232 
 7 UIKit 0x1951ab8f4 - [UINib instantiateWithOwner : options :] + 1756 
 8 UIKit 0x195458128 - [UIStoryboard instantiateViewControllerWithIdentifier :] + 196 
 9 UIKit 0x19545fa20 - [UIStoryboardSegueTemplate instantiateOrFindDestinationViewControllerWithSender :] + 92 
 10 UIKit 0x19545fc7c - [UIStoryboardSegueTemplate_perform :] + 56 
 11 UIKit 0x19545ff70 - [UIStoryboardSegueTemplate perform :] + 160 
 12 UIKit 0x194de4594 - [UITableView _selectRowAtIndexPath : 애니메이션 : scrollPosition : notifyDelegate :] + 1352 
 13 UIKit 0x194e94e8c - [UITableView _userSelectRowAtPendingSelectionIndexPath :] + 268 
 14 UIKit 0x194f47d8c _runAfterCACommitDeferredBlocks + 292 
 15 UIKit 0x194f39b40 _cleanUpAfterCAFlushAndRunDeferredBlocks + 560 
 16 UIKit 0x194ca92ac _afterCACommitHandler + 168 
 17 CoreFoundation 0x18ee917dc __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32 
 18 CoreFoundation 0x18ee8f40c __CFRunLoopDoObservers + 372 
 19 CoreFoundation 0x18ee8f89c __CFRunLoopRun + 1024 
 20 CoreFoundation 0x18edbe048 CFRunLoopRunSpecific + 444 
 21 GraphicsServices 0x19083f198 GSEventRunModal + 180 
 22 UIKit 0x194d21bd0 - [UIApplication _run] + 684 
 23 UIKit 0x194d1c908 UIApplicationMain + 208 
 24 TheElements 0x1000ad45c 메인 (main.m : 55) 
 25 libdyld.dylib 0x18dda05b8 시작 + 4 

64 비트 iOS는 "제로 비용"예외 구현을 사용합니다. "zero-cost"시스템에서 모든 함수는 함수에서 예외가 발생할 경우 스택을 unwind하는 방법을 설명하는 추가 데이터를가집니다. unwind 데이터가없는 스택 프레임에서 예외가 발생하면 예외 처리를 진행할 수 없으며 프로세스가 중지됩니다. 예외 핸들러가 스택에서 멀리 떨어져있을 수도 있지만, 프레임에 대한 unwind 데이터가 없으면 예외가 던져진 스택 프레임에서 얻을 수있는 방법이 없습니다. -no_compact_unwind플래그를 지정하면 해당 코드에 대해 unwind 테이블을 얻지 못하므로 해당 함수에서 예외를 throw 할 수 없습니다.

또한 응용 프로그램이나 라이브러리에 일반 C 코드 -funwind-tables를 포함하는 경우 해당 코드의 모든 함수에 대한 unwind 테이블을 포함 하도록 플래그를 지정해야 할 수도 있습니다 .

스레드 상태

이 절에서는 충돌 한 스레드의 스레드 상태를 나열합니다. 이것은 실행 목록이 중지 된 시점의 레지스터 목록입니다. 충돌 보고서를 읽을 때 스레드 상태를 이해할 필요는 없지만이 정보를 사용하여 충돌 상황을 더 잘 이해할 수 있습니다.

Listing 12 ARM64 디바이스의 충돌 보고서에서 Thread State 섹션 발췌.

 스레드 0이 ARM 스레드 상태 (64 비트)와 충돌했습니다. 
 x0 : 0x0000000000000000 x1 : 0x000000019ff776c8 x2 : 0x0000000000000000 x3 : 0x000000019ff776c8 
 x4 : 0x0000000000000000 x5 : 0x0000000000000001 x6 : 0x0000000000000000 x7 : 0x00000000000000d0 
 x8 : 0x0000000100023920 x9 : 0x0000000000000000 x10 : 0x000000019ff7dff0 x11 : 0x0000000c0000000f 
 x12 : 0x000000013e63b4d0 x13 : 0x000001a19ff75009 x14 : 0x0000000000000000 x15 : 0x0000000000000000 
 x16 : 0x0000000187b3f1b9 x17 : 0x0000000181ed488c x18 : 0x0000000000000000 x19 : 0x000000013e544780 
 x20 : 0x000000013fa49560 x21 : 0x0000000000000001 x22 : 0x000000013fc05f90 x23 : 0x000000010001e069 
 x24 : 0x0000000000000000 x25 : 0x000000019ff776c8 x26 : 0xee009ec07c8c24c7 x27 : 0x0000000000000020 
 x28 : 0x0000000000000000 fp : 0x000000016fdf29e0 lr : 0x0000000100017cf8 
 sp : 0x000000016fdf2980 pc : 0x0000000100017d14 cpsr : 0x60000000 

바이너리 이미지

이 절에는 종료시 프로세스에로드 된 2 진 이미지가 나열됩니다.

Listing 13 크래시 보고서의 바이너리 이미지 섹션에서 애플리케이션의 엔트리 발췌

 이진 이미지 : 
 0x100060000 - 0x100073fff TheElements arm64 <2defdbea0c873a52afa458cf14cd169e> /var/containers/Bundle/Application/888C1FA2-3666-4AE2-9E8E-62E2F787DEC1/TheElements.app/TheElements 
 ... ... 

각 줄에는 단일 이진 이미지에 대한 다음 세부 정보가 포함됩니다.

  • 프로세스 내의 이진 이미지의 주소 공간.

  • 바이너리의 바이너리 명 또는 번들 식별자 (macOS 만). macOS의 충돌 보고서에서 이진 파일이 OS의 일부인 경우 a (+)가 앞에 추가됩니다.

  • (macOS 전용) 바이너리의 짧은 버전 문자열 및 번들 버전으로 대시로 구분됩니다.

  • (iOS 전용) 바이너리 이미지의 아키텍처. 바이너리는 지원하는 아키텍처마다 하나씩 여러 "슬라이스"를 포함 할 수 있습니다. 이러한 슬라이스 중 하나만 프로세스에로드됩니다.

  • 바이너리 이미지를 고유하게 식별하는 UUID. 이 값은 바이너리 빌드마다 변경되며 충돌 보고서를 나타낼 때 해당 dSYM 파일 을 찾는 데 사용됩니다 .

  • 디스크상의 바이너리 경로.

메모리 부족 보고서 이해

메모리 부족 상태가 감지되면 iOS의 가상 메모리 시스템은 메모리를 해제하는 응용 프로그램의 협력에 의존합니다. 메모리 부족 알림은 사용중인 메모리 양을 줄이기 위해 실행중인 모든 응용 프로그램과 프로세스에 메모리를 확보하라는 요청으로 전송됩니다. 메모리 부족이 계속되면 시스템이 백그라운드 프로세스를 종료하여 메모리 부족을 완화 할 수 있습니다. 충분한 메모리를 확보 할 수 있으면 응용 프로그램이 계속 실행됩니다. 그렇지 않은 경우 응용 프로그램의 요구 사항을 충족시킬 수있는 메모리가 충분하지 않아 iOS에서 응용 프로그램이 종료되고 메모리 부족 보고서가 생성되어 장치에 저장됩니다.

메모리 부족 보고서의 형식은 응용 프로그램 스레드에 대한 백 트레이스가 없다는 점에서 다른 오류 보고서와 다릅니다. 메모리 부족 보고서는 충돌 보고서 머리글 과 비슷한 머리글로 시작됩니다 . 헤더 다음에는 시스템 전체 메모리 통계를 나열하는 필드 모음이 있습니다. 페이지 크기 필드 의 값을 적어 두십시오 . 저 메모리 보고서의 각 프로세스의 메모리 사용량은 메모리 페이지 수로보고됩니다.

메모리 부족 보고서의 가장 중요한 부분은 프로세스 테이블입니다. 이 테이블은 메모리 부족 보고서가 생성 된 시점의 시스템 데몬을 비롯하여 실행중인 모든 프로세스를 나열합니다. 프로세스가 "폐기"된 경우 이유는 [이유]아래에 나열 됩니다. 프로세스는 다음과 같은 이유로 폐기 될 수 있습니다.

  • [per-process-limit] : 프로세스가 시스템에 부과 된 메모리 제한을 초과했습니다. 상주 메모리에 대한 프로세스 별 제한은 모든 응용 프로그램에 대해 시스템에 의해 설정됩니다. 이 한도를 초과하면 프로세스가 해지 될 수 있습니다.

  • [vm-pageshortage] / [vm-thrashing] / [vm] : 프로세스가 메모리 부족으로 인해 종료되었습니다.

  • [vnode-limit] : 너무 많은 파일이 열려 있습니다.

  • [highwater] : 시스템 데몬이 메모리 사용량의 최고치를 넘었습니다.

  • [제티 슨 (jettisoned)] : 프로세스가 다른 이유로 쫓겨났습니다.

앱 / 확장 프로세스 옆에 이유가 표시되지 않으면 충돌의 원인이 메모리 부족이 아니 었습니다. 자세한 내용 .crash이전 섹션 에서 설명한 파일을 찾으십시오 .

해지시 코드의 어느 부분이 실행되고 있는지 염려하지 말고 메모리 부족 사고가 발생하면 메모리 사용 패턴과 메모리 부족 경고에 대한 응답을 조사해야합니다. 앱의 메모리 문제 찾기 는 누수 계측기를 사용하여 메모리 누수를 발견하는 방법과 할당 계기의 마크 힙 기능을 사용하여 버려진 메모리를 피하는 방법에 대한 자세한 단계를 나열합니다. 메모리 사용 성능 지침 에서는 메모리 사용에 대한 많은 팁뿐만 아니라 메모리 부족 알림에 응답하는 적절한 방법을 설명합니다. 또한 WWDC 2010 세션 인 인스트루먼트를 사용한 고급 메모리 분석 을 확인하는 것이 좋습니다 .

Related Documents 관련된 문서

Instruments 좀비 템플릿을 사용하여 메모리 과다 릴리스 충돌을 수정하는 방법에 대한 자세한 내용은 좀비 추적 템플릿으로 좀비 제거를 참조하십시오 .

응용 프로그램 보관에 대한 자세한 내용은 응용 프로그램 배포 안내서를 참조하십시오 .

충돌 로그 해석에 대한 자세한 내용은 iPhone OS WWDC 2010 세션의 충돌 보고서 이해를 참조하십시오 .



문서 개정 내역


Date 날짜 Notes 노트
2018-01-08 2018-01-08

iTunes Connect 웹 사이트에서 다운로드 한 dSYM의 난독 화 기호에 대한 정보를 추가했습니다. 또한 예외 코드 0x2bad45ec에 대한 설명이 추가되었습니다.

2017-04-03 2017-04-03

크래시 보고서의 이름을 .crash 확장자로 지정해야 Xcode를 사용하여 심볼을 나타낼 수 있음을 분명히했습니다. 0xdeadfa11 예외 코드에 대한 설명을 삭제했습니다 (응용 프로그램을 강제 종료해도 더 이상 충돌 보고서가 생성되지 않음).

2017-02-21

watchOS 앱과 관련된 일부 종료 코드에 대한 정보가 추가되었습니다. 키보드 확장이 SIGQUIT 신호를 수신하는 이유에 대한 정보를 추가했습니다.

2017-01-03

0xdead10cc 예외 코드에 대한 추가 세부 정보 및 해결 방법 제안을 추가했습니다.

2016-09-02

iOS 10에 맞게 업데이트되었습니다. 충돌 보고서 기호화에 대한 토론이 확대되었습니다.

2015-07-21 2015-07-21

Xcode 6에서 업데이트되었습니다. 충돌 보고서에 대한 토론이 확대되었습니다.

2012-12-13

더 많은 예외 코드에 대한 정보를 추가했습니다.

2012-03-28

메모리 부족 오류보고 및 예외 코드에 대한 정보가 추가되었습니다. Xcode 4 용으로 업데이트되었습니다.

2011-03-01 2011-03-01

iOS 4.0 이상 버전의 변경 사항을 반영하여 업데이트되었습니다.

2010-07-06

문서의 버그 수정.

2010-05-18 2010-05-18

iPhone OS 3.2 SDK 및 Xcode 3.2.2의 변경 사항을 반영하여 업데이트되었습니다.

2009-06-01 2009-06-01

.dSYM 파일뿐만 아니라 응용 프로그램 바이너리도 저장할 필요성에 대해 강조했습니다.

2009-04-30

iTunes Connect 크래시 로그 서비스 용으로 업데이트되었습니다.

2009-02-18

응용 프로그램 코드가 기호화되지 않도록하는 문제에 대한 해결 방법을 포함하도록 업데이트되었습니다.

2009-01-29

충돌 보고서를 상징화하고 이해하고 해석하는 방법을 설명하는 개발자를위한 필수 정보를 담은 새 문서입니다.

 

출처

https://developer.apple.com/library/content/technotes/tn2151/_index.html




Header

모든 crash 리포트들은 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 : 이 crash report 의 unique 한 식별자이다.

CrashReporter Key : 장치 별 식별자로, 동일한 장치의 두 보고서에는 동일한 값이 표현된다.

Beta Identifier : 장치와 공읍 업체의 조합에 대한 고유 식별자이다. Testlight 를 통해 배포된 앱에서만 노출된다.

Code Type : 장치의 아키텍쳐로 ARM-64, ARM, x86-64 또는 x86 중 하나이다.

Role : 앱 종료시 프로세스에 할당 된 task_role 을 뜻한다.





Exception Information

이 섹션에서는 충돌의 특성에 대한 정보를 제공하는
Mach Exception Type 및 관련 필드를 나열한다.
모든 crash report 에서 모든 입력란 (Exception Note, Exception Code ..)이 표시되지는 않는다.


처리되지 않은 Objective-C Exception 으로 인해 생성된 Crash Report

Exception Type: EXC_CRASH (SIGABRT)

Exception Codes: 0x0000000000000000, 0x0000000000000000

Exception Note: EXC_CORPSE_NOTIFY

Triggered by Thread: 0


Null 포인터에 값을 대입했기 때문에 생성된 Crash Report


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 Codes : 하나 이상의 64비트 16 진수로 인코딩 된 Exception 에 대한 프로세서 관련정보이다. 다른 필드에서 이를 이용하여 human-readable 한 정보를 추출한다.

Exception Subtype : human-readable 하게 바뀐 예외 코드의 이름

Exception Message : human-readable 하게 바뀐 예외 코드에서 추출한 추가 정보

Exception Note : Exceptoin Subtype 과 관련된 추가 정보로 이 필드에 SIMULATED 가 포함되어 있으면 Crash 는 아니지만 시스템 요청에 의해 종료된 것이다.

Termination Reason : 프로세스가 종료된 이유이다. 

Triggered by Thread : 예외가 발생한 Thread





Exception Type


Bad Memory Access [EXC_BAD_ACCESS // SIGSEGV // SIGBUS] 

프로세스가 유효하지 않은 메모리에 접근하려고 시도했거나
read-only memory 에 쓰기를 하려고하는 등의 memory protection level 에 허용하지 않는 방식으로
메모리에 접근하려고 했음을 의미한다.

Exceptoin Subtype 필드는 오류를 설명하는 kern_return_t 와 
액세스된 메모리 주소를 포함한다.

잘못된 메모리 액세스를 디버깅하기 위한 팁은 아래와 같다.

- objc_msgSend 또는 objc_release가 crash 난 thread backtrace 의 맨 위에 있으면 
프로세스가 할당 해제 된 객체를 메시지로 보내려고 시도했을 수 있다. 
이 crash 를 더 잘 이해하기 위해서는 Zommbie Instrument 를 이용해서 profiling 해보는 것이 좋다.

-  gpus_ReturnNotPermittedKillClient가 crash 난 thread backtrace 의 맨 위에 있으면 
백그라운드에서 OpenGL ES 또는 Metal로 렌더링을 시도했기 때문에 프로세스가 종료된 것이다. 
(https://developer.apple.com/library/content/qa/qa1766/_index.html) 를 참조하여 해결한다.

- Address Sanitizer (https://developer.apple.com/videos/play/wwdc2015/413/) 가 활성화 된 상태에서 앱을 실행한다.
Address Sanitizer 는 컴파일 된 코드에서 메모리 액세스와 관련된 추가 수단을 추가한다. 
Crash 가 발생할 수 있는 코드가 존재하면 xcode 에서 경고를 나타내준다.


Abnormal Exit [EXC_CRASH // SIGABRT] 

프로세스가 비정상적으로 종료되었을 때 나타나는 type 이다.
가장 일반적인 원인으로는 Objective-C/C++ 예외나 abort() 호출이 있다.

또한 App Extension 이 initialize 에 너무 많은 시간이 소요되어
워치독에 의해 종료된 경우 위 type 이 나타날 수 있다.

launch 시 정지로 인해 extension 이 kill 된 경우 crash report 의
Exception Subtype 은 LAUNCH_HANG 으로 노출된다.
Extension 에는 main function 이 없기 때문에 
initializing 에 오랜 시간이 걸리면 안된다.

initialzing 에 오랜 시간이 소요되지 않도록 오랜 시간이 걸리는 job 은 나중으로 미루는 것이 좋다.




Killed [SIGKILL]

시스템의 요청에 따라 프로세스가 종료되었음을 의미한다.
종료 원인을 더 잘 이해하려면 Termination Reason 필드를 확인해야한다.

아래는 Watch App 의 경우 나타날 수 있는 코드들이다.

0xc51bad01 : 백그라운드 작업을 수행하는 동안 너무 많은 CPU 시간을 사용했기 때문에 App 이 종료되었음을 나타낸다.
이 문제를 해결하려면 백그라운드 작업을 수행하는 코드를 보다 효율적으로 만들어 CPU 를 최적화하거나
백그라운드 작업량을 줄여야한다.

0xc51bad02 : 할당된 시간 내에 백그라운드 작업을 완료하지 못해 App 이 종료되었음을 나타낸다.
이 문제를 해결하려면 백그라운드 작업량을 줄여야한다.

0xc51bad03 : 할당 된 시간 내에 백그라운드 작업을 완료하지 못했음을 나타내고, 시스템이 백그라운드 작업을 수행하는데
많은 CPU 시간을 받지 못했을 정도로 전반적으로 바빴을 때 나타낸다.
앱이 백그라운드 작업에서 수행하는 작업량을 줄임으로써 문제를 피할 수는 있지만
앱 코드의 잘못이라기 보단 전체 시스템 로그로 인해 앱이 작업을 완료하지 못했을 가능성이 크다.



Quit [SIGQUIT]

App 의 lifttime 을 관리할 권한이 있는 다른 프로세스의 요청으로 종료되었음을 의미한다.

프로세스가 crash 난 것을 의미하지는 않지만 탐지 가능한 방식으로 오작동했을 가능성이 높다.


iOS 에서는 키보드 앱이 너무 오래 걸리면 키보드 앱이 종료된다.

crash report 에 표시된 Backtraces 가 담당 코드를 가리킬 가능성은 거의 없다.


이 이슈를 더 잘 이해하기 위해선 시작 중 작업의 대부분을 background thread 로 옮기거나

Extension 이 로드된 이후까지 지연시켜야한다.




Trace Trap [EXC_BREAKPOINT // SIGTRAP]

Abnormal Exit 에서 abort () 를 사용하는 것처럼
__builtin_trap() 을 사용했을 때 발생하는 Exception type 이다.

사용자가 디버깅을 위해 호출할 수 있다.
debugger 가 연결되어 있지 않다면 프로세스가 종료되고 crash report 가 생성된다.

하위 수준 라이브러리 (ex. libdispatch) 에서 치명적인 오류가 발생하면
해당 프로세스를 트랩한다.
오류에 대한 추가 정보는 crash report 의 추가 진단 정보 섹션이나 장치 콘솔에 있다.

Swift 코드는 런타임시 예기치 않은 조건이 발생하면 이 예외 유형으로 종료된다.

- Optional 타입이 아닌데 nil 값일 경우
- 강제 형 변환 실패

추가 정보가 장치의 콘솔에 기록되었을 수도 있기 때문에 
Backtraces를보고 예기치 않은 상황이 발생했는지 확인해야한다.

런타임 오류를 적절히 처리하려면 crash 위치의 코드를 수정해야한다. 
(ex. Optional 을 unwrapping 하는 대신 선택적 바인딩을 사용한다.)


Illegal Instruction [EXC_BAD_INSTRUCTION // SIGILL]

프로세스가 불법적이거나 정의되지 않은 명령을 실행하려고 시도했음을 의미한다. 
프로세스가 잘못 구성된 함수 포인터를 통해 잘못된 주소로 점프하려고 시도했을 수 있습니다.

Intel 프로세서에서 ud2 연산 코드는 EXC_BAD_INSTRUCTION 예외를 발생시키지만 
일반적으로 디버깅 목적으로 프로세스를 트랩하는 데 사용된다.

런타임시 예기치 않은 상황이 발생하면 Intel 프로세서의 Swift 코드가 종료시킨다.
자세한 내용은 Trace Trap (트레이스 트랩)을 참조한다.


Resource Limit [EXC_RESOURCE]

프로세스가 resource 소비 한도를 초과했음을 의미한다.
이것은 프로세스가 너무 많은 리소스를 사용하고 있다는 OS로부터의 알림이다. 
정확한 자원은 Exception Subtype 필드에 나열된다. 
Excpetion Note 필드에 NON-FATAL condition 이 포함되어 있으면 
crash report 는 있지만 앱이 종료되지 않았음을 알 수 있다.

Exception subtype 이 MEMORY 이면 앱 프로세스가 시스템에서 부과한 메모리 한계를 넘었음을 나타낸다.
Exception subtype 이 WAKEUPS 이면 프로세스의 스레드가 초당 너무 많이 깨어나고 있음을 의미하며 이는 CPU 를 자주 깨우고 배터리 수명을 소모할 수 있다.
일반적으로 이 에러는 잦은 스레드간 통신 (performSelector:onThread: or dispatch_async) 사용으로 인해 발생한다.


Guarded Resource Violation [EXC_GUARD]

프로세스가 보호된 리소스를 보호하지 않았음을 의미한다.


Other Exception Types

일부 crash report 에는 16 진수 값 (예 : 00000020)으로 이름이 지정되지 않은 예외 유형이 포함될 수 있다. 

이러한 오류 보고서 중 하나가 표시되면 예외 코드 필드를 직접 확인하여 자세한 내용을 확인해야한다.


0xbaaaaaad : Crash 보고서가 아닌 전체 시스템의 스택 샷임을 나타낸다. 스택 샷을 찍으려면 홈 버튼과 모든 볼륨 버튼을 누른다.

종종 이러한 로그는 사용자가 실수로 생성한 것이므로 오류를 나타내지는 않는다.


0xbad22222 : VoIP 앱이 너무 자주 다시 시작 되었기 때문에 iOS에 의해 종료되었음을 나타낸다.


0x8badf00d : watch dog 시간 초과가 발생하여 앱이 iOS 에 의해 종료되었음을 나타낸다. 

앱이 시스템 이벤트를 시작, 종료 또는 응답하는데 너무 오래 걸렸을 경우에 발생한다.

가장 많이 하는 실수로는 Main Thread 에서 synchronous 하게 네트워크 통신을 하는 경우가 있다.

MainThread 에서의 오래 걸리는 작업은 background thread 로 이동하거나 다르게 처리해 main thread block 을 막야아한다.


0xc00010ff : 발열(?) 로 인해 OS 에서 앱을 종료했음을 나타낸다.  이 것은 device 또는 환경에 의한 것일 수 있다.

App 을 보다 효율적으로 실행하기 위해 (https://developer.apple.com/videos/play/wwdc2011/312/) 를 참고한다.


0xdead10cc : 앱이 suspend 된 상태에서 파일 lock 또는 sqlite lock 을 유지했기 때문에 OS 에 의해 종료되었음을 나타낸다.

앱이 suspend 된 상태에서 파일이나 sqlite db 에서 작업을 수행하고 싶다면 

background job 을 등록하여 (beginBackgroundTask:) 해당 작업을 완료하고 잠금을 해제해야한다.

아래와 같이 에러가 발생되었다.

잘되던 빌드가 갑자기 안되면서 아래와 같은 에러가 떴다...

심각도 코드 설명 프로젝트 파일 줄 비표시 오류(Suppression) 상태
오류  "ResolveLibraryProjectImports" 작업에서 예기치 않은 오류가 발생했습니다.
System.IO.FileNotFoundException: Could not load assembly 'MiGong, Version=0.0.0.0, Culture=neutral, PublicKeyToken='. Perhaps it doesn't exist in the Mono for Android profile?
파일 이름: 'MiGong.dll'
   위치: Java.Interop.Tools.Cecil.DirectoryAssemblyResolver.Resolve(AssemblyNameReference reference, ReaderParameters parameters)
   위치: Java.Interop.Tools.Cecil.DirectoryAssemblyResolver.Resolve(String fullName)
   위치: Xamarin.Android.Tasks.ResolveLibraryProjectImports.Extract(DirectoryAssemblyResolver res, ICollection`1 jars, ICollection`1 resolvedResourceDirectories, ICollection`1 resolvedAssetDirectories, ICollection`1 resolvedEnvironments)
   위치: Xamarin.Android.Tasks.ResolveLibraryProjectImports.Execute()
   위치: Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
   위치: Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext() MiGong.Android   

이번에도 비쥬얼스튜디오를 껐다 켜면 되겠거니 했는데

그래도 계속 빌드오류가 발생되었다.;;

아 이건 또 먼가 ㅜㅠ

혹시나 해서 Android 쪽 프로젝트만 재빌드했다...

해결되었다;;;

콘솔앱을 하나 만듭니다.

만들어진 상태에서 해당 프로젝트의 메뉴에서 추가>컨테이너 오케스트레이터 지원 을 클릭합니다.

아래처럼 Docker Compose 를 선택하고

윈도우서버로 서버가 동작중이므로  Windows 를 선택했습니다.

 

아래처럼 Docker-compose 프로젝트가 추가됩니다.

yml 파일을 이용해 먼가 더 추가적이 설정이 가능한데 이는 다음에 더 자세히

살펴봐야겠습니다.

F5 로 실행해보면 아래 처럼

제가 만든 콘솔엡의 이미지가 생성된걸 불수 있습니다. (근데 사이즈가 왜저렇게 크지..;;)

(Docker image 명령어를 파워쉘에서 실행)

아래처럼 중단을 걸면 디버깅도 가능합니다.

 

소스파일

DockerConsoleApp.zip

 

앱을 배포했는데 12.0 버전에서 실행시 오류가 발생해서 반려?가되었다.

iOS 는 신규 버전이 나오면 거기까지 테스트를 해야하는구나;;;

그래도 다행인건 iOS xcode 버전을 올리고

윈도우에서 Visual Studio 를 실행하니 알아서 iOS 의 Xamarin.iOS 도 업데이트 해준다.

 

방법은 아래 링크에 자세히 나와있다.

https://docs.microsoft.com/ko-kr/xamarin/xamarin-forms/platform/wpf

 

주의할 점

1. 프레임워크 대상 버전이 4.7 이상이어야한다.

2. MainWindow.xaml 내용의 처음을 Window -> wpf:FormsApplicationPage 으로 변경해야한다.

3. MainWindow.xaml.cs 에서 상속을 FormsApplicationPage 으로 변경해야한다.

4. 링크에도 나와있듯이 WPF 프로젝트에 설치한 Xamarin.Forms 의 버전과 다른 프로젝트들과 버전을 맞춰야한다.

 

아래는 기본 자마린 솔루션에서 WPF 프로젝트만 추가한 내용이다.

XamarinStudy.z01

XamarinStudy.z02

XamarinStudy.zip

 

아래는 실행한 WPF 결과

 

WebView 에서 JavaScript 실행은 간단히 아래와 같히 펑션을 호출하면 된다.

this.webView.Eval("TestFunction()");

 

하지만 리턴이 있는 JavaSecript funtion 실행결과는 저 형태로는 안된다.

따로 Renderer 를 이용해 구현하는 방법을 소개한다.

 

먼저 .Net Standard 프로젝트에 아래와 같이 WebViewer 를 만든다.

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace Test
{
    public class WebViewer : WebView
    {
        public static BindableProperty EvaluateJavascriptProperty =
        BindableProperty.Create(nameof(EvaluateJavascript), typeof(Func<string, Task<string>>), typeof(WebViewer), null, BindingMode.OneWayToSource);

        public Func<string, Task<string>> EvaluateJavascript
        {
            get { return (Func<string, Task<string>>)GetValue(EvaluateJavascriptProperty); }
            set { SetValue(EvaluateJavascriptProperty, value); }
        }
    }
}

이제 위 항목을 상속받아서 각 기기별로 Renderer 를 생성하자.

 

Android

using System;
using System.Threading;
using System.Threading.Tasks;
using Android.Content;
using Android.Webkit;
using Test;
using Test.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(WebViewer), typeof(WebViewRender))]
namespace Test.Droid
{
    public class WebViewRender : WebViewRenderer
    {
        public WebViewRender(Context context) : base(context)
        { }

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement is WebViewer webView)
            {
                webView.EvaluateJavascript = async (js) =>
                {
                    var reset = new ManualResetEvent(false);
                    var response = string.Empty;
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        Control?.EvaluateJavascript(js, new JavascriptCallback((r) => { response = r; reset.Set(); }));
                    });
                    await Task.Run(() => { reset.WaitOne(); });
                    return response;
                };
            }
        }
    }

    internal class JavascriptCallback : Java.Lang.Object, IValueCallback
    {
        public JavascriptCallback(Action<string> callback)
        {
            _callback = callback;
        }

        private Action<string> _callback;
        public void OnReceiveValue(Java.Lang.Object value)
        {
            _callback?.Invoke(Convert.ToString(value));
        }
    }
}

 

iOS

using System.Threading.Tasks;
using Test;
using Test.iOS;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(WebViewer), typeof(WebViewRender))]
namespace Test.iOS
{
    public class WebViewRender : WebViewRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            if (e.NewElement is WebViewer webView)
            {
                webView.EvaluateJavascript = (js) =>
                {
                    return Task.FromResult(this.EvaluateJavascript(js));
                };
            }
        }
    }
}

 

UWP

using System;
using Test;
using Test.UWP;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;

[assembly: ExportRenderer(typeof(WebViewer), typeof(WebViewRender))]
namespace Test.UWP
{
    public class WebViewRender : WebViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
        {
            base.OnElementChanged(e);
            if (e.NewElement is WebViewer webView)
            {
                webView.EvaluateJavascript = async (js) =>
                {
                    return await Control.InvokeScriptAsync("eval", new[] { js });
                };
            }
        }
    }
}

 

이제 화면에서 아래와 같이 컨트롤을 넣고

<test:WebViewer x:Name="webView" HorizontalOptions="FillAndExpand"  VerticalOptions="FillAndExpand"/>

아래와 같이 코딩하면 function 의 결과 값을 받아올수 있다.

var result = await this.webView.EvaluateJavascript("GetTest();");

 

http://rextester.com/

 

        private static string CRLF = "\r\n";
        private static string boundary = "----" + DateTime.Now.Ticks.ToString("x") + "----";
        private static Stream DataStream = new MemoryStream();
        private static byte[] formData;

        public static void APIExamCafePostMultipart(string tockenkey, string title, string memo, string imageurl)
        {
            DataStream = new MemoryStream();
            string token = tockenkey; // 네이버 로그인 접근 토큰
            string header = "Bearer " + token; // Bearer 다음에 공백 추가
            string clubid = cafeid; // 카페의 고유 ID값
            string menuid = menuID; // 메뉴ID값
            string headid = headID; // 말머리

            string url = "https://openapi.naver.com/v1/cafe/" + clubid + "/menu/" + menuid + "/articles";
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.ContentType = "multipart/form-data; boundary=" + boundary;
            request.Headers.Add("X-Naver-Client-Id", clientID); // 등록한 어플리케이션 Client ID
            request.Headers.Add("X-Naver-Client-Secret", ScreatID); // 등록한 어플리케이션 Client Secret
            request.Headers.Add("Authorization", header);
            buildParam("subject", title); // 제목
            buildParam("content", memo); // 본문
            buildParam("headid", headid); // 말머리
            buildFileParam("image[0]", imageurl); // 파일 [0]
            //buildFileParam("image[1]", "C:\\test2.jpg"); // 파일 [1]
            buildByteParam(); // Byte Array 생성
            Stream stream = request.GetRequestStream();
            stream.Write(formData, 0, formData.Length); // request 전송
            stream.Close();
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StreamReader reader = new StreamReader(response.GetResponseStream());
            string text = reader.ReadToEnd();
            stream.Close();
            response.Close();
            reader.Close();
            Console.WriteLine(text);
        }

 

SMSConvey 어플을 좀 업그레이드 하려고 하는데 갑자기 아래와 같은 에러가 났다.

Detected problems with app native libraries(please consult log for details): libmonosgen-64bit-2.0.so: unauthorized access to "/system/lib64/libsqlite.so"

오레오 업데이트 하고 나서 에러가 발생된것 같은데

찾아보니 7.0 부터 발생한 내용이라고 하던데.. 일단 내가 7.0 일때 테스트 할때는 저런 에러가 발생되지 않았다.

SQLite 사용시 발생되는 에러로 해결방법은

Nuget 패키지 관리자에서 "sqlite-net" 을 제거하고 "sqlite-net-pcl" 을 설치하면 된다.

 

**추가 (아래 방식으로 완전히 해결됨)

아래와 같이 package 를 설치하고

 

아래 두파일을 삭제합니다.

 

 

참고

https://forums.xamarin.com/discussion/78234/android-libmonosgen-library-sqlite-problems-with-app-native-libraries

+ Recent posts

티스토리 툴바