유니티 개발 중 Access Violation 충돌로 인한 에디터 종료 문제(5.6 Kinect 개발 중에 발생한 문제)


5.6.0f3 버전의 유니티 엔진에서 키넥트 V2(Kinect V2 이하 키넥트)를 이용해서 개발하는 도중에 유니티 에디터 상에서 게임 테스트를 하기 위해서 플레이 버튼을 눌렀을 때 유니티 엔진이 Unity Bug Reporter 창을 띄우고 뻗어버리는 일이 발생했다.



다음의 내용이 개발하기 위해 세팅되어 있는 것들이었다.


Unity 5.6.0f3

Microsoft Kinect SDK 2.0

Visual Studio Community 2017

Kinect Examples with MS-SDK v2


버그 발생하기 이전에 수정한 사항은 많지 않았기 때문에 갑자기 발생한 버그라서 버그의 원인을 짐작하기가 쉽지 않았다.



유니티 엔진은 crash.dmp 파일과 error.log 파일 하나만 남겨놓고 뻗은 상태였고, 로그 내용을 기반으로 구글링도 해보았으나 외국의 개발자들 역시 Access Violation 문제로 고통받고 있을뿐 별다른 해결책은 찾을 수 없었다(그리고 Access Violation 문제라는 것만 같고 개발 세팅이나 문제가 발생하는 시점 역시 달라서 크게 참고가 되지 않았다). 외국 개발자들의 이야기 중에 그나마 도움이 되었던 것은 이 문제가 유니티 에디터에서만 발생하고 빌드한 실행 파일에서는 발생하지 않는다는 것이었다.



Unity Editor [version: Unity 5.6.0f3_497a0f351392]

mono.dll caused an Access Violation (0xc0000005)
  in module mono.dll at 0033:abc51985.

Error occurred at 2017-06-14_092816.
C:\Program Files\Unity\Editor\Unity.exe, run by PC.
44% memory in use.
8114 MB physical memory [4468 MB free].
14258 MB paging file [9523 MB free].
134217728 MB user address space [134214674 MB free].
Read from location 320f7000 caused an access violation.

Context:
RDI:    0x00000000  RSI: 0x3209d87b  RAX:   0x00000001
RBX:    0x0002cbc2  RCX: 0x00000000  RDX:   0x0392dc0d
RIP:    0xabc51985  RBP: 0x00000000  SegCs: 0x00000033
EFlags: 0x00010202  RSP: 0x005fcb70  SegSs: 0x0000002b
R8:     0x00054d0d  R9:  0x00000000  R10:   0x0002cbc2
R11:    0x00000000  R12: 0x00000000  R13:   0x00000080
R14:    0x000003ff  R15: 0x00002400

Bytes at CS:EIP:
66 46 39 2c 56 73 9f 41 ff c0 ff c3 49 ff c2 eb

Stack:
0x005fcb70: 0000000b 00000000 3989ae80 00000000 ...........9....

.

.

.

0x005feb60: 00000000 ffffffff 00000042 00007fff ........B.......

Module 1
C:\Program Files\Unity\Editor\OpenRL_pthread.dll
Image Base: 0x80000000  Image Size: 0x0000f000
File Size:  50200       File Time:  2017-03-30_143322
Version:
   Company:    Open Source Software community LGPL
   Product:    POSIX Threads for Windows LPGL
   FileDesc:   MS C 32 bit
   FileVer:    2.9.0.0
   ProdVer:    2.9.0.0

Module 2
C:\Program Files\Unity\Editor\OpenRL.dll
Image Base: 0x80000000  Image Size: 0x00c28000
File Size:  12627992    File Time:  2017-03-30_143322
Version:
   Company:    Imagination Technologies, Inc.
   Product:    OpenRL™
   FileDesc:   OpenRL™ Library
   FileVer:    1.5.100.10
   ProdVer:    1.5.100.10

Module 3
C:\WINDOWS\SYSTEM32\MSVCR100.dll
Image Base: 0x53a80000  Image Size: 0x000d2000
File Size:  829264      File Time:  2011-02-19_005232
Version:
   Company:    Microsoft Corporation
   Product:    Microsoft® Visual Studio® 2010
   FileDesc:   Microsoft® C Runtime Library
   FileVer:    10.0.40219.1
   ProdVer:    10.0.40219.1

Module 4
C:\WINDOWS\SYSTEM32\MSVCP100.dll
Image Base: 0x53b60000  Image Size: 0x00098000
File Size:  608080      File Time:  2011-02-19_225156
Version:
   Company:    Microsoft Corporation
   Product:    Microsoft® Visual Studio® 2010
   FileDesc:   Microsoft® C Runtime Library
   FileVer:    10.0.40219.1
   ProdVer:    10.0.40219.1


== [end of error.log] ==


에러 로그나 Dump 파일을 봤을 때, 문제는 mono.dll에서 발생하는 것으로 보였다. 하지만 당장 개발이 급했기 때문에 덤프 파일을 분석하지는 못했고 당장의 문제의 원인을 파악하고, 문제를 배제한 뒤에 개발을 다시 시작하기 위해서 프로젝트를 새로 만들어서 리소스와 스크립트를 옮기는 작업을 했다. 하지만 프로젝트를 새로 만들어서 내용물을 옮기는 것만으로는 문제가 해결되지 않았고, 결국 문제가 발생하는 지점을 찾기 위해서 오브젝트에 붙은 컴포넌트를 하나씩 꺼보고 스크립트를 블럭 단위로 주석 처리하는 방식으로 문제 지점을 찾기 위해 작업했다.


이 작업을 진행하는 도중의 대부분은 오브젝트에 붙은 컴포넌트를 제거하거나 스크립트를 주석처리하고 플레이해 본뒤에 충돌이 발생하는지 확인하는 것이었다. 그러던 중에 발견한 사항은 다음과 같았다.


1. Kinect Examples with MS-SDK v2 에셋에서 제공하는 스크립트를 오브젝트에 붙인 컴포넌트를 게임 씬에서 모두 제거하면 충돌이 발생하지 않는다.

2. Kinect Examples with MS-SDK v2 에셋에서 제공하는 스크립트를 오브젝트에 붙인 컴포넌트를 제거하지 않더라도 내가 작성한 스크립트 중에서 특정 블럭을 주석 처리하면 충돌이 발생하지 않는다.


키넥트 개발을 계속해야하기 때문에 1번은 전혀 해결책이 될 수가 없었고 2번의 방법으로 주석 처리했을 때, 충돌이 발생하지 않는 부분을 찾기 위해 해당 코드 블럭을 한줄한줄씩 주석 처리해보면서 플레이 버튼을 눌러보는 수 밖에 없었다.


그러던 도중에 단 한 줄을 주석 처리했을 때, 충돌이 발생하지 않는다는 것을 발견할 수 있었다.



그 문제의 원인은 어이없게도 Debug.Log("업"); 이라는 코드였다. 이 한 줄을 주석 처리하면 더 이상 문제는 발생하지 않았다. 그리고 "업"이 아니라 다른 글자를 사용해도 문제가 해결되었고, 가끔은 다른 로그 내용도 문제를 발생시키기도 했으며, 혹은 Debug.Log("업");이라고 해도 또 다른 특정한 위치에서는 문제가 없이 작동했다.


키넥트가 필요하지 않은 테스트일 때는 Kinect Manager 스크립트를 제외하고, 키넥트가 필요한 시점에는 Log를 주의해서 사용해야 했다.


임시방편으로 문제를 우회해서 지나가는 방법은 발견했으나 근본적인 해결책을 찾지 못했다. 추측해보건데 로그를 남기는 작업은 파일에 관여하는데 그 작업 중 어느 부분이 Kinect Examples with MS-SDK가 제공하는 Kinect Manager 스크립트가 처리하는 부분과 충돌이 발생하는 것으로 보인다.



주변 분들이 원인으로 추정되는 몇가지를 이야기 해주었는데, 하나는 키넥트 스레드가 처리하는 부분에서 메인 스레드와 충돌을 일으킨 것이 아닌가 하는 것이고 다른 하나는 특정 문자열에서만 이 현상을 일으키기 때문에 문자열 인코딩 방식이 이런 문제를 발생시킬 수도 있다는 것이었다.

반응형

+ Recent posts