CUDA사용시 MiniDumpWriteDump()실패

게임 클라이언트에서 크래시 발생시 덤프파일을 생성하도록 해놨다. 데스크탑버전은 적용이 되어있는데 UWP는 적용이 안되어있어서 UWP에도 적용하려고 데스크탑버전의 덤프생성 코드를 테스트했다.
그런데 문제 발생. 어라? 근데 덤프 생성에 문제가 있다. 덤프파일은 만들어졌지만 정상적으로 디버거에서 읽히지 않는다. MiniDumpWriteDump()함수가 실패하네? 해당 에러값으로 이틀동안 구글링을 해봐도 도움되는 답이 없다.

테스트를 하다보니 64비트에서만, MiniDumpWithFullMemory플래그를 줄 경우만 발생하는걸 알게 됐다.

’64비트는 뭐가 다르지?’

서버 코드에서도 덤프를 생성하게 되어있으므로 서버의 64비트 프로세스에서 같은 코드로 덤프를 떠보니 잘 된다. 그럼 64비트라 문제가 발생하는건 아니네.

‘클라이언트 64비트일 경우엔 뭐가 다르지?’
‘아! CUDA! CUDA쓴다.’

그렇다. CUDA. CUDA8.0부터 32비트는 아예 지원을 안한다. 현재 CUDA 9.1을 사용하고 있기 때문에 64비트에서만 CUDA를 사용한다.

혹시나 해서 CUDA관련 DLL을 로드하지 않고 덤프를 떠보니 잘 작동한다. MiniDumpWithFullMemory 플래그를 줘도 정상적으로 작동한다.

그런데 좀 이상하다. 8년전에 Windows 7시절에 그래픽 디자이너들한테 맵툴 만들어줬을때 CUDA도 지원했었고 그 자리에서 덤프도 뜰 수 있게 해놨었다. 그땐 잘 작동했는데?
그 해답은 아마도 CUDA 6.0부터 들어간 Unified Memory 시스템에 있을것이다. 물론 이건 추측이다.

예전에는 cudaMallocHost()와 cudaMalloc()으로 메모리를 따로 할당하고 관리했었다. host메모리는 시스템 메모리이고 host안붙은건 GPU메모리이다. 이때만 해도 메모리를 할당하면 그 즉시 commit되었다.
그런데 unified memory 시스템에서 cudaMallocManaged()를 호출하면 시스템 메모리도 그 즉시 commit되지 않는다. 고의로 page fault를 일으키도록 되어있다. page fault가 일어나면 그때 메모리를 commit하고 짝으로 이루어진 GPU메모리에 대해서 갱신할 타이밍도 이때 결정한다.
내 생각엔 풀메모리덤프가 실패하는건 이거랑 관련있는것 같다.
내 프로세스에서 할당한 메모리지만 실제 관리는 cuda런타임이나 nvidia 드라이버쪽에서 하고 있어서 문제가 되는것 같다.결과적으로 덤프를 뜰때 commit되지 않은 메모리에 억세스하려고 했거나 권한 문제가 생기는걸로 추측한다.

원인을 알았으니 마음이 편하다. 해결책은 뭐 특별한건 없다.
일단 CUDA는 클라이언트에서만 사용하고 있고, 클라이언트 배포판의 덤프파일은 풀메모리 덤프를 하지 않으니 큰 문제는 아니다. 다만 CUDA사용시에도 풀메모리덤프에 준하는 수준으로 메모리 정보를 얻을 수 있는 플래그 조합은 찾아봐야할것 같다. 어쨌든 디버깅시엔 필요하니까.

추가:
좀더 테스트해봤는데 역시 CUDA관련 DLL이 로드되고나면 접근에 실패하는 메모리가 존재하게 되는게 맞다. MiniDumpIgnoreInaccessibleMemory플래그를 지정하면 접근에 실패한 메모리는 무시하고 접근에 성공한 메모리에 대해서만 덤프를 뜰 수 있다.
CUDA사용시 풀메모리 덤프가 필요하다면 MiniDumpWriteDump()함수 호출할때 MiniDumpWithFullMemory에 추가로 MiniDumpIgnoreInaccessibleMemory 플래그를 함께 설정하도록 한다.

MINIDUMP_TYPE	miniDumpType = MINIDUMP_TYPE(MiniDumpWithFullMemory | MiniDumpIgnoreInaccessibleMemory);
BOOL bDumpResult = MiniDumpWriteDump(g_hProcess,
			g_dwProcessID,
			hFile,
			miniDumpType,
			pExceptionInfo,
			nullptr,
			nullptr
		);

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

w

%s에 연결하는 중