2018년 3월 28일 수요일

크래시 발생 원인 - 메시지 처리

사용하던 코어 코드 중에 간헐적으로 크래시가 발생하는 경우 발생

메시지 큐 방식으로 여러 메시지큐에 동일한 메시지를 던진 상태에서
아래와 같은 코드형태로 처리가 되는 중이었음

 1: auto count = ::InterlockedDecrement64(&pMsg->wait_count);
 2: if(count)
 3: {
 4:    WaitForSingleObject(pMsg->Handle);
 5: }
 6: else
 7: {
 8:    Process(pMsg);
 9:    SAFE_DELETE(pMsg);
10: }

크래시가 발생하는 구간은 형광색 구간이었는데
count = 1 인 상태였다

왜 죽었을까?

원인은 컨태스트 스위칭이 발생하면서
A, B 스레드가 있다고 할때
A에서 2라인을 체크 if 문 안으로 진입 컨테스트 스위칭 발생
B에서 9라인 처리
pMsg는 파기된 상태. 다시 컨테스트 스위칭
A 4라인에서 pMsg는 뎅글링 포인트가 되면서 크래시가 발생


어떻게보면 가장 기초적인 실수중에 하나인데 이 문제로 엄청난 스트레스와 코어 코드의 신뢰를 잃는 큰 손실을 봤다