VC++ MiniDumpWriteDump 保存程序的DUMP调试文件信息,类似于 Linux 下面的 core 调试信息文件。

创建DUMP信息的函数实现:

static void CreateMiniDump(PEXCEPTION_POINTERS pep, LPCTSTR strFileName)
{
	HANDLE hFile = CreateFile(strFileName, GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

	if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
	{
		MINIDUMP_EXCEPTION_INFORMATION mdei;
		mdei.ThreadId = GetCurrentThreadId();
		mdei.ExceptionPointers = pep;
		mdei.ClientPointers = NULL;

		MINIDUMP_CALLBACK_INFORMATION mci;
		mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)MiniDumpCallback;
		mci.CallbackParam = 0;

		::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hFile, MiniDumpWithFullMemory, (pep != 0) ? &mdei : 0, NULL, &mci);

		CloseHandle(hFile);
	}
}

static BOOL CALLBACK MiniDumpCallback(PVOID pParam, const PMINIDUMP_CALLBACK_INPUT pInput, PMINIDUMP_CALLBACK_OUTPUT pOutput)
{
	if (pInput == 0 || pOutput == 0)
		return FALSE;

	switch (pInput->CallbackType)
	{
	case ModuleCallback:
		if (pOutput->ModuleWriteFlags & ModuleWriteDataSeg)
			if (!IsDataSectionNeeded(pInput->Module.FullPath))
				pOutput->ModuleWriteFlags &= (~ModuleWriteDataSeg);
	case IncludeModuleCallback:
	case IncludeThreadCallback:
	case ThreadCallback:
	case ThreadExCallback:
		return TRUE;
	default:;
	}

	return FALSE;
}

static BOOL IsDataSectionNeeded(const WCHAR* pModuleName)
{
	if (pModuleName == 0)
	{
		return FALSE;
	}

	WCHAR szFileName[_MAX_FNAME] = L"";
	//_wsplitpath(pModuleName, NULL, NULL, szFileName, NULL);
	_wsplitpath_s(pModuleName, NULL, 0, NULL, 0, szFileName, _MAX_FNAME, NULL, 0);

	//if (wcsicmp(szFileName, L"ntdll") == 0)
	if (_wcsicmp(szFileName, L"ntdll") == 0)
		return TRUE;

	return FALSE;
}

WIN32K结构化异常筛选器函数实现:类似 catch when 的语法效果。

int __stdcall sehCrashFilter(DWORD code, LPEXCEPTION_POINTERS lpEP)
{
	time_t t = time(nullptr);
	tm tm_;
	localtime_s(&tm_, &t);

	TCHAR szModuleName[MAX_PATH];
	GetModuleFileName(NULL, szModuleName, MAX_PATH);
	WCHAR szFileName[_MAX_FNAME] = L"";
	_wsplitpath_s(szModuleName, NULL, 0, NULL, 0, szFileName, _MAX_FNAME, NULL, 0);


	WCHAR szBuffer[MAX_PATH] = { 0 };
	wsprintf(szBuffer, L"%s thread[%u]_%d-%02d-%02d_%02d-%02d-%02d.txt", szFileName, GetCurrentThreadId(), tm_.tm_year + 1900, tm_.tm_mon + 1, tm_.tm_mday, tm_.tm_hour, tm_.tm_min, tm_.tm_sec);
	StackWalkerToFile sw;
	if (sw.OpenFile(szBuffer))
	{
		sw.ShowCallstack(GetCurrentThread(), lpEP->ContextRecord);
	}

	wsprintf(szBuffer, L"%s thread[%u]_%d-%02d-%02d_%02d-%02d-%02d.dmp", szFileName, GetCurrentThreadId(), tm_.tm_year + 1900, tm_.tm_mon + 1, tm_.tm_mday, tm_.tm_hour, tm_.tm_min, tm_.tm_sec);
	CreateMiniDump(lpEP, szBuffer);

	return EXCEPTION_EXECUTE_HANDLER;
}

例子程式:

#ifdef _MSC_VER
void CommonService::seh_proccess(NetworkRouteHeader* header)
{
    __try
    {
        c_proccess(header);
    }
    __except (sehCrashFilter(GetExceptionCode(), GetExceptionInformation()))
    {
        printf("%s seh exception\n", m_serviceName.c_str());
    }
}
#endif

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值