Unity는 게임이나 에디터 프로세스 분석이나 라이브 디버깅 작업을 Windows에서 하기 쉽도록 몇몇 기능을 제공합니다.
우선 명료성을 기준으로 디버깅을 구분할 수 있습니다. Unity에는 두 개의 디버깅 타입이 있으며, 각각 C++ 디버깅과 C# 관리 디버깅이라고 합니다. IL2CPP를 지원하는 플랫폼의 경우에는 네이티브 디버깅만 있지만, 빠른 반복을 위해 에디터에서 관리 디버깅을 사용할 수도 있습니다.
네이티브 디버깅은 exe나 dll과 같은 관련 바이너리 파일의 심볼인 pdb 파일을 통해 작동합니다.
Windows에서는 일반 .NET 관리 심볼은 pdb 파일에 저장되지만, Mono를 사용하는 경우 mdb 파일에 저장됩니다.
Unity는 http://symbolserver.unity3d.com/에서 심볼 스토어를 운영합니다. Microsoft 심볼 스토어와 같이, 이 서버 URL을 windbg나 VS2012 이후 버전에서 자동 심볼 해결 및 다운로도 용도로 활용할 수 있습니다.
심볼 스토어를 windbg에 추가하려면 .sympath 커맨드를 사용하면 됩니다.
.sympath+ SRV*c:\\symbols-cache*http://symbolserver.unity3d.com/
이제 위의 커맨드를 분석할 것입니다.
.sympath+
+를 추가하면 존재하는 심볼 경로를 유지한 채 심볼 스토어 룩업을 추가합니다.
SRV*c:\symbols-cache
SRV는 데이터를 가져오는 외부 서버를 지정합니다. 반면 c:\symbols는 다운로드된 심볼을 임시 저장하는 로컬 경로를 지정하며, 다운로드를 실행하기 전에 필요한 심볼이 없는지 이 경로를 먼저 확인합니다.
*http://symbolserver.unity3d.com/
데이터를 가져올 심볼 스토어 경로입니다.
Note VS2010 and earlier do not function with http server symbol stores
1. Tools -> Options로 이동합니다.
2. 디버깅 섹션을 확장한 후 Symbols를 선택합니다.
3. 캐시 디렉토리를 지정하지 않은 경우 지정합니다.
4. http://symbolserver.unity3d.com/의 “심볼 파일 (.pdb) 위치”를 추가합니다.
라이브 디버깅은 정상적으로 실행 중이거나 예외 오류가 발생한 프로세스에 디버거를 부착하는 경우입니다. 디버거가 상황을 파악할 수 있으려면 심볼이 빌드에 포함되어야 하며 위의 과정을 통해 이루어집니다. 또한 게임 실행 가능 파일은 게임 이름에 따라 명명되므로, 만일 실행 가능 파일의 이름을 변경하여 디버거가 접근할 수 없으면 디버거가 올바른 pdb 파일을 검색할 때 문제가 발생할 수 있습니다.
Windows에서 Microsoft는 애플리케이션 크래시가 발생하는 경우 자동으로 Dr Watson이나 Microsoft에 오류를 보고하도록 설정합니다. 하지만 Visual Studio나 windbg가 설치되어 있는 경우, Microsoft는 유능한 개발자들이 크래시 디버그를 할 수 있는 기능을 제공합니다. 아래의 레지스트리 파일 콘텐츠를 설치하면 편리하게 설치할 수 있습니다.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug]
"Auto"="1"
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug]
"Auto"="1"
여기에 아래 행을 추가하여 에디터 디버깅을 가능하게 해야 합니다.
Unity.exe -dbgbreak
만일 자동 크래시 처리가 설정된 경우 Unity를 실행한 후 즉시 디버거가 연결되도록 할 것입니다.
Windows는 .dmp나 .mdmp와 같은 크래시 덤프 파일을 분석할 수 있는 기능을 제공합니다. 크래시 덤프 타입에 따라 데이터 스택이 있거나 전체 프로세스 메모리가 파일에 있을 수 있습니다. 콘텐츠에 따라 크래시가 발생한 이유를 분석할 수 있는 가능성이 있습니다. 대부분의 경우에는 분석이 가능한 스택이 존재합니다. 물론 분석을 하려면 그 스택이 유효해야 합니다.
덤프 파일을 분석하려면 Visual Studio나 windbg를 로드해야 합니다. Visual Studio는 익숙해서 사용하기는 편리하지만 windbg에 비해 기능이 제한되어 있습니다.
NullReferenceException는 보통 아래와 같은 형태를 가집니다.
1b45558c()
> mono.dll!malloc(unsigned int size=12) Line 163 + 0x5f bytes C
mono.dll!g_hash_table_insert_replace(_GHashTable * hash=0x065c3960, void * key=0x0018cba4, void * value=0x0018cb8c, int replace=457528232) Line 204 + 0x7 bytes C
mono.dll!mono_jit_runtime_invoke(_MonoMethod * method=0x242bf8b0, void * obj=0x065c3960, void ** params=0x0018cba4, MonoObject * * exc=0x0018cb8c) Line 4889 + 0xc bytes C
이 예외는 malloc이나 mono에서 발생하는 크래시가 아니라, 아래 경우 둘 중 하나인 NullReferenceException입니다. * VS 디버거가 식별한 경우 * 사용자 플레이어에서 처리되지 않아 플레이어가 종료된 경우
앞의 예제를 다시 들어보겠습니다.
1b45558c()
> mono.dll!malloc(unsigned int size=12) Line 163 + 0x5f bytes C
mono.dll!g_hash_table_insert_replace(_GHashTable * hash=0x065c3960, void * key=0x0018cba4, void * value=0x0018cb8c, int replace=457528232) Line 204 + 0x7 bytes C
mono.dll!mono_jit_runtime_invoke(_MonoMethod * method=0x242bf8b0, void * obj=0x065c3960, void ** params=0x0018cba4, MonoObject * * exc=0x0018cb8c) Line 4889 + 0xc bytes C
정보가 없는 행은 관리 프레임입니다. 하지만 관리 스택 정보를 얻을 방법이 있습니다. mono는 스택 프레임의 주소를 수용한 후 정보와 함께 char*를 리턴하는 mono_pmip 빌트인 함수가 있습니다. mono_pmip를 Visual Studio에서 바로 호출하려면 아래의 행을 추가해야 합니다.
?(char*)mono_pmip((void*)0x1b45558c)
0x26a296c0 “ Tiles:OnPostRender () + 0x1e4 (1B4553A8 1B4555DC) [065C6BD0 - Unity Child Domain]”`
Note: This only works where mono.dll symbols are properly loaded.
Sometimes there are cases where application doesn’t crash with the debugger attached. Or application crashes on a remote device, where debugger is not available. You can still get useful information, if you can get the dump file. Here are simple steps how to do it.
Note: These steps work on Windows Standalone, Windows Store Apps and Windows Universal Apps (when running in Desktop)