64비트에서 덤프파일이 남겨지지 않습니다.

프로그래밍 일반에 관한 포럼입니다.

Moderator: 류광

Locked
paranoiase
Posts: 5
Joined: 2009-10-21 11:37

64비트에서 덤프파일이 남겨지지 않습니다.

Post by paranoiase »

경고 메시지를 남길 때 덤프파일을 함께 남기도록 작업을 해 놓았습니다.

Code: Select all

LONG WINAPI WriteDumpFile(_EXCEPTION_POINTERS *pException)
{

	// 예외 정보가 있으면 함께 남기고, 정보가 없으면 함께 남기지 않는다
	if( pException )
	{
		if( MiniDumpWriteDump( hProcess, dwProcessID, hFile, eDumpType, &sExceptionInfo, &sUserInfo, NULL) )
		{
			return true;
		}
	}
	else
	{
		PMINIDUMP_EXCEPTION_INFORMATION ssExceptionInfo;
		ssExceptionInfo = NULL;

		if( MiniDumpWriteDump( hProcess, dwProcessID, hFile, m_eDumpType, ssExceptionInfo, NULL, NULL) )
		{
			return true;
		}
	}

	return false
}
예외가 일어났을 경우 SetUnhandledExceptionFilter로 핸들러를 등록해서 덤프파일을 남기고,
예외가 일어나지 않은 경우에도 WriteDumpFile(NULL);과 같은 방식으로 함수를 호출해서 강제로 덤프를 남기는 방식을 사용하고 있었습니다.

문제는, 이게 32비트(Windows XP)에서는 잘 동작하는데, 64비트(Windows Server 2008)에서는 잘 동작하지 않네요.
예외가 일어났을 경우는 덤프파일이 생깁니다만, 예외가 일어나지 않은 상황에서 강제로 덤프를 남기면 파일은 생성되지만 콜스택 정보가 남겨지지 않습니다.
심지어는 Windows Server 2008에서 32비트(Win32)로 빌드하면 제대로 동작하는데, 64비트(x64)로 빌드하면 제대로 동작하지 않네요.

덕분에 일주일간 골머리를 썩고 있습니다 ㅠㅠ


OS는 Windows Server 2008이고 x64를 이용하고 있습니다.
혹시 해결 방법을 아시는 분은 조언 부탁드립니다~~
블루
Posts: 80
Joined: 2007-10-04 10:56

Post by 블루 »

2008은 아니지만, Vista x64를 쓰는데, 양쪽 경우 모두 잘 되네요...
type은 MiniDumpWithFullMemory로 썼고요..

2008용 dbghelp쪽 버그일 수도 있겠지만.. 그보다는 parameter들을 한번 체크해보심이..
paranoiase
Posts: 5
Joined: 2009-10-21 11:37

Post by paranoiase »

블루 wrote:2008은 아니지만, Vista x64를 쓰는데, 양쪽 경우 모두 잘 되네요...
type은 MiniDumpWithFullMemory로 썼고요..

2008용 dbghelp쪽 버그일 수도 있겠지만.. 그보다는 parameter들을 한번 체크해보심이..

답변 감사드립니다.
아는 분이 Vista x64를 사용하고 계셔서 그 컴퓨터에서 테스트를 해 봤는데, 마찬가지로 콜스택이 제대로 표시되지 않네요. ㅠㅠ
Type도 MiniDumpWithFullMemory를 사용해 보았으나 마찬가지였습니다.

프로젝트 옵션의 문제가 아닐까 했습니다만, 확인해보니 MachineX86 / MachineX64만 제외하면 동일합니다.


아무래도 덤프파일 구현 방식에서 일어나는 문제가 아닐까 하네요.
혹시 참고할만한 구현 방식이나 소스코드를 알 수 없을까요? 잘 부탁드립니다. _(__)_
블루
Posts: 80
Joined: 2007-10-04 10:56

Post by 블루 »

음.. 올려달라시니 올려드리지만, 보시다시피 별거 없습니다...
혹시나해서 다시 테스트 해봤으나, 역시 잘 되네요.. Vista x64 Debug 모드로 테스트 했고요.


덤프:

Code: Select all

void Dump( LPCSTR filePath, MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *info ) throw()
{
	HRESULT hr;
	CAtlFile file;
	BOOL dumpResult;

	// create file
	if( FAILED(hr=file.Create(filePath, GENERIC_WRITE, 0, CREATE_ALWAYS)) )
	{
		LOG( "failed to create dump file.");
		return;
	}

	dumpResult = MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), file, type, info, NULL, NULL );

	if( !dumpResult )
	{
		LOG( "failed to create minidump." );
		return;
	}
}
호출:

Code: Select all

Dump( "c:\\test.dmp", MiniDumpWithFullMemory, NULL );
paranoiase
Posts: 5
Joined: 2009-10-21 11:37

Post by paranoiase »

아아... 코드를 똑같이 베껴서 테스트 해 봤는데도 안 되네요.
뭔가 프로그램 설치를 잘못했나...도저히 알 수가 없네요 ㅠㅠ

Code: Select all

#include <windows.h>
#include <dbghelp.h>
#include <stdio.h>
#include <string>
#include <atlfile.h>
#include <tchar.h>

#pragma comment(lib, "dbghelp.lib")


void Dump( LPCTSTR filePath, MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *info ) throw()
{
	   HRESULT hr;
	   CAtlFile file;
	   BOOL dumpResult;

	   // create file
	   if( FAILED(hr=file.Create(filePath, GENERIC_WRITE, 0, CREATE_ALWAYS)) )
	   {
//	   	   LOG( "failed to create dump file.");
	   	   return;
	   }

	   dumpResult = MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), file, type, info, NULL, NULL );

	   if( !dumpResult )
	   {
//	   	   LOG( "failed to create minidump." );
	   	   return;
	   }
}


int _tmain(int, _TCHAR*[])
{
	Dump( _T("c:\\test.dmp"), MiniDumpWithFullMemory, NULL );

	return 0;
}

프로그램 문제일까요? 저는 Visual Studio 2005를 사용하고 있습니다.

서비스팩은
Microsoft? Visual Studio? 2005 Team Suite 서비스 팩 1 과
Windows Vista용 Visual Studio 2005 서비스 팩 1.

그리고 SDK는 Microsoft Windows SDK for Windows Server 2008 and .NET Framework 3.5를 사용 중입니다.
블루
Posts: 80
Joined: 2007-10-04 10:56

Post by 블루 »

Visual Studio 2008 Professional SP1 입니다. Platform SDK는 2008에 기본으로 들어있는 거고요..

어쩌면 dump남기는쪽에 문제가 있는 것이 아니라 dump file을 Visual Studio 2005에서 제대로 읾지 못하는 것일지도 모르겠네요..

생성된 dump file을 VS2008에서 한번 load해 보세요..
paranoiase
Posts: 5
Joined: 2009-10-21 11:37

Post by paranoiase »

답변 감사드립니다. _(__)_

Visual Sudio 2008 SP1을 깔고 Vista x64에서 빌드해봤습니다만 역시나 마찬가지였습니다.
정말 뭐가 문제인지 전혀 모르겠네요 ㅠㅠ
paranoiase
Posts: 5
Joined: 2009-10-21 11:37

자답입니다.

Post by paranoiase »

원인은 발견하지 못했지만,
강제로 예외를 일으켜서 덤프를 남긴 후, try-catch로 무시하고 넘어가는 방식으로 하니까 x64에서도 잘 되네요.

Code: Select all

#include <windows.h>
#include <dbghelp.h>
#include <stdio.h>
#include <string>
#include <atlfile.h>
#include <tchar.h>

#pragma comment(lib, "dbghelp.lib")


LONG WINAPI Dump(_EXCEPTION_POINTERS *info)
{
		HRESULT hr;
		CAtlFile file;
		BOOL dumpResult;

		MINIDUMP_EXCEPTION_INFORMATION sExceptionInfo;
		sExceptionInfo.ThreadId = GetCurrentThreadId();
		sExceptionInfo.ExceptionPointers = info;
		sExceptionInfo.ClientPointers = FALSE;

		// create file
		if( FAILED(hr=file.Create(_T("c:\\test.dmp"), GENERIC_WRITE, 0, CREATE_ALWAYS)) )
		{
//			LOG( "failed to create dump file.");
			return -1;
		}

		dumpResult = MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), file, MiniDumpWithFullMemory, info ? &sExceptionInfo : NULL, NULL, NULL );

		if( !dumpResult )
		{
//			LOG( "failed to create minidump." );
			return -1;
		}

		return 0;
}


int _tmain(int, _TCHAR*[])
{
	__try
	{
		TCHAR* p = NULL; // 오류 발생
		_tcscpy(p, _T("ABCDEFG")); // 오류 발생
	}
	__except(Dump(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER)
	{
	}

	return 0;
}

좀 찜찜하고 뒤가 구린 방법이지만(-_-;) 일단은 해결점을 찾아서 다행입니다.
Locked