[테스트 중 발생한 크래시의 분석/디버깅 후기]
테스트 방송중에 시청자 한 분의 클라이언트가 크래시했다. 일단 덤프 파일을 전달 받았다.
덤프를 분석하고 직접적인 원인은 금방 찾았다. 그런데 왜 이런 일이 일어나는지 처음엔 알 수가 없었다. 논리적으론 문제가 없어보이는데.
그때 상황을 설명해달라고 일단 메일은 보냈는데 언제까지 기다릴 수는 없다. 크래시한 플레이어의 화면은 아니지만 내 쪽에서도 어느 정도 관찰은 하고 있는 상황이니까 녹화된 영상에 실마리가 있을것 같았다.
녹화된 영상을 살펴보고 무기가 없는 상태에서 사망 후 부활하는 사이에 크래시했다고 추측했다.
손에 들고 있는 무기가 없으면 서버에서 탄환 개수 업데이트 패킷을 보내면 안되는데 어떤 경우에는 보내는것 같다. 물론 항상 발생하지는 않는다.
몇 가지를 더 테스트 해보고 무기를 들고 있는 상태에서 복셀 편집모드로 바꾸고 인스턴스맵에 진입하면 현재 탄환은 최대치, 들고있는 무기와 탄창은 무효한 값이 된다는 사실을 알아냈다.
1) 사망하면 OffShoot()함수가 호출되는데 이때 잔탄수가 유효하면 클라이언트에 탄환수 업데이트 패킷을 보낸다.
2) 무기를 들지 않았으므로 클라/서버 모드 탄창과 현재 무기 시리얼이 무효한 값이다.
- 사망하면 OffShoot()함수가 호출되는데 이때 잔탄수가 유효하면 클라이언트에 탄환수 업데이트 패킷을 보낸다.
- 무기를 들지 않았으므로 클라/서버 모드 탄창과 현재 무기 시리얼이 무효한 값이다.
- 그러나 방금까지 무기를 들고 있다가 복셀편집모드로 바꾼 상태에서 인스턴스맵에 진입하면 잔탄수는 유효범위 내에서 max가 된다.
- 전송함수에서 잔탄수가 유효한지만 체크하고 현재 탄창과 무기가 유효한지를 체크하지 않는다. 따라서 무기와 탄창이 무효한 값이지만 잔탄수 업데이트 패킷을 클라이언트에 보낸다.
- 클라이언트 역시 이 상황에서 탄창과 무기가 nullptr이기 때문에 탄창 포인터의 잔탄수 변수를 억세스하려고 할때 크래시한다
해당 버그는 클라/서버 양쪽 다 수정해서 처리했다.
테스트할 때 영상 찍어두면 정말 도움이 많이 된다. 이걸로 잡기 힘든 버그를 몇 개나 잡았다.