yuchi's Development Home


으아...일주일전쯤에 발견해서 날 미치게했던 그 버그를 잡았다.

총 쏠때 캐릭터가 사라졌다가 사격을 멈추면 다시 나타나는 버그.

VS2010의 v100컴파일러에서 VS2013의 v120컴파일러로 버전을 올리고 난 후 나타난 버그이고 반복된 테스트로 v120컴파일러로 컴파일한 바이너리에서만 나타는 버그라는 결론을 얻었었다.

릴리즈 풀 옵티마이즈 상태에서만 나온다.마침 VS2013은 Update 2 rc버전이다. 즉 VS2013의 v120컴파일러의 옵티마이저 쪽에 버그가 있다고 생각했다.

일단 그때도 Character.cpp의 OnShootingProcess()함수쪽이 옵티마이즈 되면 문제가 생긴다고는 추측했었다.
거기까진 좋았는데 컴파일러 버그라고 생각한건 역시 바보같았다.

사실 계속 찜찜하긴 했지. 풀옵티마이즈라고 해도 컴파일러 버그로 잘못된 코드를 생성하는 경우는 정말 흔치 않다.
게다가 십수개의 DLL을 이미 v120컴파일러로 컴파일했고 그놈들을 서버에서 사용하는데 3개 서버의 프로세스가 일주일동안 전혀 문제없이 돌고 있다.
이상하잖아.

정식 Update 2가 발표되면 확인해 볼 수 있겠지...라고 일단 고민을 좀 미뤄뒀었다.

오늘 아침에 기다리던 Visual Studio 2013 Update 2가 정식으로 릴리즈 됐다. 바로 설치하고 리빌드했다.

신의 도우심인지 그 잘 나오지도 않던 버그가 딱 처음 실행하자마자 나오더라.
거의 직감했다. '이거 컴파일러 버그 아니겠구나.'

VS2013 Update 2로 빌드해서도 동일한 문제가 발생하니 하루종일 찜찜해서 다른 일을 할 수 없었다. 그러고보니 몇 일 전 일이 생각났다.

몇 개월 전에 지금 개발중인 게임을 WinRT 기반으로도 포팅을 했었다. 
Windows 8.0 타겟이었고 Visual Studio 2012의 v110컴파일러를 사용했었다. Update 2 rc버전이 나오기 전에는 VS2013에서 arm용 빌드를 하면 컴파일러가 무한 루프에 빠졌다. 그래서 계속 VS2012의 V110컴파일러를 사용해서 Windows 8.0타겟으로 빌드했었다.

그런데 몇 일전 누가 좀 보여달라기에 실행을 해보니 안돌더라. 다시 빌드를 하니 빌드가 안되더라. 할 수 없이 Windows 8.1타겟으로 하고 VS2013의 v120컴파일러로 싹 리빌드했다. Update 2 rc이후로 arm빌드 컴파일 문제는 해결되었으므로 무난히 8.1로 이전했다.
x86/x64/arm용으로 빌드를 만들었고 arm빌드를 서피스 RT에 올려서 작동을 확인했다.

그리고 그 다음날 자랑스럽게 보여줬는데 예의 그 버그가 튀어나왔다. 총 쏘면 캐릭터가 사라지는 버그. 그땐 그냥 '아 역시 컴파일러에 버그가 있어서 arm용 빌드에서도 같은 버그가 나타나는가보다.'라고 생각했다.
역시 어리석었다.

다시 오늘로 돌아와서. 그 서피스RT에서 재현됐던 버그를 떠올리고 나니 서피스RT에선 계속 재현이 가능할지도 모른다는 생각이 들었다.

서피스RT를 꺼내다가 테스트를 해봤다. 
놀랍게도!!! 그 재현하기 어렵던 버그가 항상 나타난다. 
WinRT용 게임을 서피스 프로와 PC에서 x86/x64로도 돌려봤으나 재현되지 않았다. 그런데 ARM용 릴리즈 빌드에선 언제나 재현이 됐다.

오오오오!!! 이제 잡을 수 있다!!!

좀 속도가 느려서 짜증나긴 하지만.
서피스 RT를 리모트 디버깅하면서 버그를 찾기 시작.

우선 가장 의심되는 Character.cpp코드를 처음부터 끝까지 #pragma optimize( "gpsy",off),#pragma optimize( "gpsy",on)로 감쌌다.
옵티마이즈 완전히 끄는거다.
역시 이렇게 하면 문제 안생김.

2분검색의 원리를 이용해서 절반씩 영역을 좁혀나갔다.
최종적으로 문제되는 함수 2개를 찾아냈다.
역시 최초에 추측했던대로 OnShootingProcess()와 OnShootingProcessGun()이네.

OnShootingProcessGun()하나만 옵티마이즈를 꺼놓고 보니 캐릭터가 사라지지는 않는데 사격할때 캐릭터가 90도 돌아간다. 어라? 
코드를 살펴보니 사격시 히트포인트에 맞춰서 캐릭터 방향을 돌려주는 코드가 있다. 여기에 PI/2가 들어간다는건데. 허공에 쏴서 히트 포인트가 없을때도 PI/2가 들어가네. 그럴리가. 
디버거로 확인해보니 히트 포인트의 Float3 변수에 비정상 float값이 들어가 있다.

으아!

뭔지 알았다.
히트 포인트를 저장하는 Flaot3변수를 초기화 하지 않은 것은 틀림없다. 코드 흐름상 초기화 하지 않은 상태로 각도를 구하는 함수로 전달되는 것도 맞다. 그런데 왜 디버그 모드에서 문제가 생기지 않았을까?

디버그 빌드에선 스택을 0xcccccccc로 채운 탓에 항상 일정한 값이 들어가있었고 이게 각도를 구하는 함수에 들어가면 거의 0에 가까운 값을 만들어냈던 것이다.
어차피 제대로 된 값은 아니었는데 0에 가까워서 몰랐지.

릴리즈에선 이 변수에 무슨 값이 들어갈지 알수 없고 실행할때마다 매번 다른 값이 들어가서 버그 재현이 힘들었던 것이다.
어떤땐 0에 가깝게 나오고 그렇지 않을땐 라디안값으로 쓸 수 없는 얼토당토한 값이 나와서 그 값으로 캐릭터 회전을 시키고 나면 캐릭터 사라짐 현상으로 연결되는 것이다.

이 초기화 되지 않은 float3값이 x86/x64에선 매번 다르게 채워졌고 ARM빌드에선 버그를 재현할 수 있는 꽤 일정한 값으로 채워졌었던 모양이다.

float3변수에 {0,0,0}을 넣는 것으로 버그는 수정됐고 릴리즈,디버그에 상관없이 완전히 정상작동하게 되었다.

어휴...
진짜 다행이다. 여러가지가 맞물려서 기적적으로 버그를 잡았다.

1. 초기에 캐릭터 사라짐 버그를 눈으로 확인하지 않았다면 서비스 시작할때까지도 버그를 잡을 수 없었을 것이다.

2. 오늘 아침 Visual Studio 2013 Update 2가 릴리즈되지 않았다면 여전히 컴파일러 버그라고 믿고 있었을지 모르겠다.

3. 서피스RT에서 돌리기 위해서 VS2013으로 빌드를 하지 않았다면 버그를 잡을 수 없었을 것이다.

4. 서피스RT의 arm빌드에서 버그가 재현되지 않았다면 버그를 잡을 수 없었을 것이다.

아아 이것은 신의 도우심인가.
돈은 못벌어도 버그 땜에 쪽팔리진 말라는...

우우 오늘은 발 뻗고 자겠다.

댓글 '3'

오잉

2014.06.29 19:28:58
*.7.237.118

저도 예전에 로컬변수 초기화 안해서 비슷한 경험 했었는데요. 원인을 특정하기도 어렵고 현상이 일정하지 않아 엉뚱한 편견을 갖게 되더라구요.

디버깅 방법에서 포스가 느껴집니다. 디버깅할때 편견을 없애는건 정말 어려운 일인 것 같아요.

여치

2014.07.01 08:59:04
*.168.0.1

디버깅할때 편견을 없애는전 정말 어렵죠. 경험이 많이 쌓여도 쉽지 않은것 같습니다.

Drake

2016.10.16 05:57:04
*.49.41.71

의심은 건전한 것입니다만, 컴파일러를 의심하는건 도가 지나치다구요.

파일 첨부

여기에 파일을 끌어 놓거나 파일 첨부 버튼을 클릭하세요.

파일 크기 제한 : 0MB (허용 확장자 : *.*)

0개 첨부 됨 ( / )
List of Articles
번호 제목 글쓴이 날짜 조회 수
201 제가 필요해서 만든 OneDrivePlayer가 윈스토어에 올라갔네요. [2] 여치 2014-08-23 1553
» 기적같은 디버깅. 컴파일러 버그? 역시나 그럴리가. [3] 여치 2014-05-14 1637
199 초간단 SIMD(Single Instruction Multiple Data)최적화 성능 테스트 file 여치 2014-04-10 2869
198 진행중인 프로젝트 Visual Studio 2010 -> Visual Studio 2013으로 이전 [2] 여치 2014-04-10 2518
197 Windows Phone 8과 PC간 네트워크 플레이 여치 2013-11-22 1210
196 Windows Phone 8로 게임포팅 중 생긴 난관 - Windows Phone 8 에서 App당 사용 가능한 최대 메모리 file 여치 2013-11-21 2206
195 윈폰8 포팅 중단. file 여치 2013-11-19 741
194 Windows Phone 8로 게임 포팅중 #2 여치 2013-11-18 759
193 Windows Phone에 게임 포팅중. 여치 2013-11-17 746
192 현재까지 느낀 Windows Phone 8용 게임 개발에 있어서의 장애물. [2] 여치 2013-11-07 1259
191 Windows Phone 8 디바이스를 몇 일 사용해보고 알게 된 것들. 여치 2013-11-01 723
190 Surface RT에서 유선랜 사용하기 여치 2013-10-26 1400
189 win8 sdk에서 ddraw.lib 위치 여치 2013-09-11 1380
188 TFS에서 Get Latest Version해도 갱신할 파일 없다고 나올 때 여치 2013-08-31 1557
187 dx9 debug 런타임이 활성화 안될 때 여치 2013-08-25 3917
186 인디게임 FEZ 개발자 필 피쉬, 최근 일본 게임에 대한 평가 - 그리고 내 생각 [2] 여치 2013-07-31 2372
185 The database principal owns a schema in the database, and cannot be dropped 여치 2013-05-23 4496
184 Using Windows 8* WinRT API from desktop applications 여치 2013-03-10 9410
183 WinRT 디바이스 디버깅에서 DEP0100 : Deployment failed due to a Developer Licensing issue에러를 만났을때 여치 2013-03-04 13418
182 계속되는 MS의 삽질에 대한 생각. [3] 여치 2013-02-15 12027
天安門大屠殺 六四天安門事件 反右派鬥爭 大躍進政策 文化大革命 六四天安門事件 The Tiananmen Square protests of 1989 天安門大屠殺 The Tiananmen Square Massacre 反右派鬥爭 The Anti-Rightist Struggle 大躍進政策 The Great Leap Forward 文化大革命 The Great Proletarian Cultural Revolution 人權 Human Rights 民運 Democratization 自由 Freedom 獨立 Independence 多黨制 Multi-party system 民主 言論 思想 反共 反革命 抗議 運動 騷亂 暴亂 騷擾 擾亂 抗暴 平反 維權 示威游行 法輪功 Falun Dafa 李洪志 法輪大法 大法弟子 強制斷種 強制堕胎 民族淨化 人體實驗 胡耀邦 趙紫陽 魏京生 王丹 還政於民 和平演變 激流中國 北京之春 大紀元時報 九評論共産黨 獨裁 專制 壓制 統一 監視 鎮壓 迫害 侵略 掠奪 破壞 拷問 屠殺 肅清 活摘器官 障テ社會 誘拐 買賣人口 遊進 走私 毒品 賣淫 春畫 賭博 六合彩 台灣 臺灣 Taiwan Formosa 中華民國 Republic of China 西藏 土伯特 唐古特 Tibet 達償ワ喇嘛 Dalai Lama 新疆維吾爾自治區 The Xinjiang Uyghur Autonomous Region free tibet



XE Login

天安門大屠殺 六四天安門事件 反右派鬥爭 大躍進政策 文化大革命 六四天安門事件 The Tiananmen Square protests of 1989 天安門大屠殺 The Tiananmen Square Massacre 反右派鬥爭 The Anti-Rightist Struggle 大躍進政策 The Great Leap Forward 文化大革命 The Great Proletarian Cultural Revolution 人權 Human Rights 民運 Democratization 自由 Freedom 獨立 Independence 多黨制 Multi-party system 民主 言論 思想 反共 反革命 抗議 運動 騷亂 暴亂 騷擾 擾亂 抗暴 平反 維權 示威游行 法輪功 Falun Dafa 李洪志 法輪大法 大法弟子 強制斷種 強制堕胎 民族淨化 人體實驗 胡耀邦 趙紫陽 魏京生 王丹 還政於民 和平演變 激流中國 北京之春 大紀元時報 九評論共産黨 獨裁 專制 壓制 統一 監視 鎮壓 迫害 侵略 掠奪 破壞 拷問 屠殺 肅清 活摘器官 障テ社會 誘拐 買賣人口 遊進 走私 毒品 賣淫 春畫 賭博 六合彩 台灣 臺灣 Taiwan Formosa 中華民國 Republic of China 西藏 土伯特 唐古特 Tibet 達償ワ喇嘛 Dalai Lama 新疆維吾爾自治區 The Xinjiang Uyghur Autonomous Region free tibet