Lyn
조회 수 25796 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

두번째 방법으로는 CRT의 예외 핸들러에서 UnhandledExceptionFilter로 데이터를 넘겨서 생성하는 방법인데요...
이는 안정적이고 정석적이지만 치명적인 단점으로 CRT에서 던지는 예외가 하나가 아니라는겁니다... 


어쨋든 코드를 보면


#include <Windows.h>
#include <DbgHelp.h>
#include <cstdio>
#include <string>

using namespace std;

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

LONG __stdcall TopLvFilter(PEXCEPTION_POINTERS pExceptionPointer)
{
	MINIDUMP_EXCEPTION_INFORMATION MinidumpExceptionInformation;
	std::wstring DumpFileName = L"dmpfile.dmp";

	MinidumpExceptionInformation.ThreadId = ::GetCurrentThreadId();
	MinidumpExceptionInformation.ExceptionPointers = pExceptionPointer;
	MinidumpExceptionInformation.ClientPointers = FALSE;

	if (DumpFileName.empty() == true)
	{
		::TerminateProcess(::GetCurrentProcess(), 0);
	}

	HANDLE hDumpFile = ::CreateFile(DumpFileName.c_str(),
		GENERIC_WRITE,
		FILE_SHARE_WRITE,
		nullptr,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL, nullptr);

	MiniDumpWriteDump(GetCurrentProcess(),
		GetCurrentProcessId(),
		hDumpFile,
		MiniDumpNormal,
		&MinidumpExceptionInformation,
		nullptr,
		nullptr);

	::TerminateProcess(::GetCurrentProcess(), 0);

	return 0;
}
void InvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved)
{
	EXCEPTION_POINTERS ExceptionPointer;
	EXCEPTION_RECORD ExceptionRecord;
	_CONTEXT ContextRecord;

	ZeroMemory(&ContextRecord, sizeof(ContextRecord));
	RtlCaptureContext(&ContextRecord);

	ZeroMemory(&ExceptionRecord, sizeof(EXCEPTION_RECORD));
	ExceptionRecord.ExceptionCode = STATUS_INVALID_CRUNTIME_PARAMETER;	
	ExceptionRecord.ExceptionAddress = (PVOID)ContextRecord.Eip;
		
	ExceptionPointer.ExceptionRecord = &ExceptionRecord;
	ExceptionPointer.ContextRecord = &ContextRecord;

	TopLvFilter(&ExceptionPointer);
}
void main()
{
	SetUnhandledExceptionFilter(TopLvFilter);
	_set_invalid_parameter_handler(InvalidParameterHandler);
	atoi(nullptr);	 
}



구조는 간단합니다. RtlCaptureContext 를 이용해서 현재 쓰래드의 Context를 캡쳐 해 오고, 익셉션 코드와 현재 코드가 실행중인 위치를 넘겨 주면 되는데요..
x86 시스템에서 현재 실행중인 위치는 Eip 레지스터에 있기 때문에 캡쳐해온 Context에서 Eip를 
ExceptionAddress로 넘겨 주면 됩니다.


이 방식은 안정적이고 백신이 오진을 할 가능성도 없고 Windows 8 에서도 아무 문제 없이 작동 하지만 ... 위에서 말한것처럼 예외가 이거 하나가 아니라는게 문제가 됩니다.
예를들어 메모리 할당 예외는 _set_invalid_parameter_handler 로 처리 할 수 없습니다. 하지만 어차피 몇개 안되기도 하고 (...) 그냥 몇개 더 만들어주면 될 문제지요.


정말 골때려 지는건 3rd party 에서 SetUnhandledExceptionFilter 를 호출해서 자기껄로 만들어버리는 라이브러리가 있다는겁니다 =_=; 적은 내안에만 있는게 아닌거죠...그래서 첫번째 방법과 두번째 방법을 모두 적용해 두는게 좋다고 생각 합니다


TAG •
?

List of Articles
번호 제목 글쓴이 날짜 조회 수
57 Visual Studio 2013 새로 추가된 기능 둘러보기 file Lyn 2013.10.28 19816
56 Microsoft C++ MVP 리워드를 개봉 해 보았습니다. 3 file Lyn 2013.10.11 51038
55 MS SQL Server 2012 언인스톨시 Rsfx Driver 의존성으로 인해 언인스톨이 되지 않는 경우 Lyn 2013.10.09 19905
54 Visual C++ 2013 RC 추가기능 1. Raw String Literal 3 file Lyn 2013.10.07 15726
53 Microsoft VC++ MVP를 받았습니다.... file Lyn 2013.10.02 15121
52 서버를 Windows 2012 R2로 교체 하였습니다. 1 Lyn 2013.09.29 22081
51 VS2013 RC 설치해봄 file Lyn 2013.09.28 14018
50 현재 MSDN Download Page file Lyn 2013.09.23 19525
49 boost::icl::interval_map 원하는대로 변경해서 사용해보기 file Lyn 2013.09.23 22193
48 MSDN 에 릴리즈된 MS 제품들입니다. 1 file Lyn 2013.09.10 20525
» C Runtime Library Exception Dump 남기기 두번째 방법 Lyn 2013.06.25 25796
46 C Runtime Library Exception Dump 남기기 첫번째방법 Lyn 2013.06.11 33020
45 Visual Studio 2012 Update2 Offline 설치 1 Lyn 2013.04.11 23447
44 C++11 표준 라이브러리 확장 (cbegin, cend) Lyn 2012.10.04 34443
43 C++11 표준 라이브러리 확장 (string) 3 file Lyn 2012.09.10 28156
42 대기하는 쓰래드 모두 깨우기 (Java의 notifyAll) Lyn 2012.09.04 37884
41 C++ 템플릿 상속에서 베이스 클래스의 멤버에 접근하는 경우의 문제 1 file Lyn 2012.08.29 30170
40 [윈도8] 윈도8 구경1 1 file Lyn 2012.08.17 26509
39 C++ string&형 인자에 기본값 주기 Lyn 2012.07.24 25859
38 [작성중] 윈도우 32bit, 64bit 프로그래밍시 주의할점 2 Lyn 2012.07.16 27593
Board Pagination Prev 1 ... 2 3 4 5 6 7 ... 8 Next
/ 8