
void GetCurModulePath(TCHAR* ptcPath,int iLen,LPVOID addr)
{
MEMORY_BASIC_INFORMATION mbi = {0};
if(FALSE == ::VirtualQuery( addr, &mbi, sizeof(mbi)))
return;
UINT_PTR h_module = (UINT_PTR)mbi.AllocationBase;
::GetModuleFileName((HMODULE)h_module, ptcPath, iLen);
return;
}

void EI2Str(TCHAR* ptcInfo,int iInfoLen,ULONG_PTR* Info,int iCount)
{
int i = 0;
TCHAR* p1 = ptcInfo;
for(i = 0; i < iCount; i++)
{
_stprintf(p1,_T("%08X "),Info[i]);
p1 += 9;
}
}


LONG WINAPI CleanToolExceptionFun(struct _EXCEPTION_POINTERS* pei)
{
STACKFRAME sf;
CONTEXT context;
TCHAR tcPath[2048] = {0};
TCHAR tcInfo[10240] = {0};
TCHAR tcExcep[20480] = {0};
GetCurModulePath(tcPath,2048,pei->ExceptionRecord->ExceptionAddress);
EI2Str(tcInfo,10240,pei->ExceptionRecord->ExceptionInformation,pei->ExceptionRecord->NumberParameters);
_stprintf(tcExcep,_T("程序遇到未知异常,具体信息如下: 代码:0x%08X 标志:0x%08X 地址:0x%08X ")
_T("参数:%d %s 模块:%s 堆栈信息如下: "),
pei->ExceptionRecord->ExceptionCode,pei->ExceptionRecord->ExceptionFlags,pei->ExceptionRecord->ExceptionAddress,
pei->ExceptionRecord->NumberParameters,tcInfo,tcPath);

memset(tcInfo,0,sizeof(tcInfo));
memset( &sf, 0, sizeof(STACKFRAME));
memcpy(&context,pei->ContextRecord,sizeof(CONTEXT));

sf.AddrPC.Offset = context.Eip;
sf.AddrPC.Mode = AddrModeFlat;
sf.AddrStack.Offset = context.Esp;
sf.AddrStack.Mode = AddrModeFlat;
sf.AddrFrame.Offset = context.Ebp;
sf.AddrFrame.Mode = AddrModeFlat;

DWORD machineType = IMAGE_FILE_MACHINE_I386;
HANDLE hProcess = GetCurrentProcess();
HANDLE hThread = GetCurrentThread();
SymInitialize(hProcess,NULL,TRUE);

for( ; ; )
{
if( !StackWalk(machineType, hProcess, hThread, &sf, &context, 0, SymFunctionTableAccess, SymGetModuleBase, 0 ) )
{
break;
}

if( sf.AddrFrame.Offset == 0 )
{
break;
}
BYTE symbolBuffer[ sizeof( SYMBOL_INFO ) + 1024 ];
PSYMBOL_INFO pSymbol = ( PSYMBOL_INFO ) symbolBuffer;

pSymbol->SizeOfStruct = sizeof( symbolBuffer );
pSymbol->MaxNameLen = 1024;
_stprintf(tcPath,_T("sf.AddrPC.Offset:0x%08X "),sf.AddrPC.Offset);
_tcscat(tcExcep,tcPath);
memset(tcPath,0,sizeof(tcPath));
DWORD64 symDisplacement = 0;
if( SymFromAddr( hProcess, sf.AddrPC.Offset, 0, pSymbol ) )
{
_stprintf(tcPath,_T("Function : %s "), pSymbol->Name );
}
else
{
}
_tcscat(tcExcep,tcPath);

IMAGEHLP_LINE lineInfo = { sizeof(IMAGEHLP_LINE) };
DWORD dwLineDisplacement;

memset(tcPath,0,sizeof(tcPath));
if( SymGetLineFromAddr( hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo ) )
{
_stprintf(tcPath,_T( "[Source File : %S] [Source Line : %u] "), lineInfo.FileName,lineInfo.LineNumber );
}
else
{
}
_tcscat(tcExcep,tcPath);
}

SymCleanup(hProcess);

//AfxMessageBox(tcExcep);
CDlgExceptionInfo dlg(tcExcep);
dlg.DoModal();
return EXCEPTION_EXECUTE_HA
然后在程序代码的任何开始的地方调用
SetUnhandledExceptionFilter(CleanToolExceptionFun);