#include "StdAfx.h" #include "AutoDmp.h" #include #include //-----------------dmp文件生成相关-------------------------------------------- using namespace std; #define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS (0x00000004) #define MiniDumpWithThreadInfo 0x1000 typedef BOOL(WINAPI *PGetModuleHandleEx)(DWORD dwFlags, LPCTSTR lpModuleName, HMODULE *phModule); string GetProcessDirectoryDump() { string ret = ""; char szFilename[MAX_PATH] = { 0 }; DWORD res = GetModuleFileNameA(0, szFilename, MAX_PATH); if (res == 0) { return ret; } string fullpath = szFilename; string::size_type firstHit = fullpath.find_last_of('\\'); if (firstHit == string::npos || firstHit == 0) { return ret; } ret = fullpath.substr(0, firstHit);//kick last \ return ret; } VOID CreateDump(struct _EXCEPTION_POINTERS *pExceptionPointers) { //收集信息 string strBuild; unsigned int ret1 = 0; HANDLE hDumpFile; std::stringstream strm; strm << "Build: " << __DATE__ << " " << __TIME__; strm >> strBuild; //strBuild.Format(L"Build: %s %s", __DATE__, __TIME__); string strError; HMODULE hModule; char szModuleName[MAX_PATH] = { 0 }; GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)pExceptionPointers->ExceptionRecord->ExceptionAddress, &hModule); GetModuleFileName(hModule, szModuleName, ARRAYSIZE(szModuleName)); strm.clear(); strm << szModuleName << ", " << pExceptionPointers->ExceptionRecord->ExceptionCode << ", " << pExceptionPointers->ExceptionRecord->ExceptionFlags << ", " << pExceptionPointers->ExceptionRecord->ExceptionAddress; strm >> strError; //生成 mini crash dump BOOL bMiniDumpSuccessful; DWORD dwBufferSize = MAX_PATH; SYSTEMTIME stLocalTime; MINIDUMP_EXCEPTION_INFORMATION ExpParam; GetLocalTime(&stLocalTime); char szFileName[MAX_PATH] = { 0 }; sprintf_s(szFileName, MAX_PATH, "%04d%02d%02d-%02d%02d%02d-ProcessID[%ld]-ThreadID[%ld].dmp", stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond, GetCurrentProcessId(), GetCurrentThreadId()); std::string strDmppath = GetProcessDirectoryDump(); strDmppath += string("\\"); strDmppath.append(szFileName); hDumpFile = CreateFile(strDmppath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0); MINIDUMP_USER_STREAM UserStream[2]; MINIDUMP_USER_STREAM_INFORMATION UserInfo; UserInfo.UserStreamCount = 1; UserInfo.UserStreamArray = UserStream; UserStream[0].Type = CommentStreamA; UserStream[0].BufferSize = strBuild.size(); UserStream[0].Buffer = (PVOID)strBuild.c_str(); UserStream[1].Type = CommentStreamA; UserStream[1].BufferSize = strError.size(); UserStream[1].Buffer = (PVOID)strError.c_str(); ExpParam.ThreadId = GetCurrentThreadId(); ExpParam.ExceptionPointers = pExceptionPointers; ExpParam.ClientPointers = TRUE; MINIDUMP_TYPE MiniDumpWithDataSegs = (MINIDUMP_TYPE)(MiniDumpNormal | MiniDumpWithHandleData | MiniDumpWithUnloadedModules | MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory | MiniDumpWithProcessThreadData | MiniDumpWithThreadInfo); bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpWithDataSegs, &ExpParam, &UserInfo, NULL); return; } LONG WINAPI AutoDmp::NewUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *lpExceptionInfo) { CreateDump(lpExceptionInfo); return EXCEPTION_EXECUTE_HANDLER; } AutoDmp::AutoDmp() { SetUnhandledExceptionFilter(NewUnhandledExceptionFilter); } AutoDmp::~AutoDmp() { } //dmp生成参考资料 //http://www.sjsjw.com/kf_other/article/031086ABA018049.asp //在win7 64bit + vs2008 + sdk v7.0的环境下编译Detours //http://blog.csdn.net/genesisbible/article/details/6771988 //下载编译好的Detours //http://download.csdn.net/download/staver102/7648875 //DMP文件的使用: //把dmp文件和exe, pdb文件放在同一目录下, 然后用编译器(如vc)打开, 然后开始调试就会中断到刚才中断的地方. //使用符号服务器 //您可以使用符号服务器自动下载用于调试 Visual Studio .NET 项目的正确符号。 //Microsoft 在 http://msdl.microsoft.com/download/symbols 上为开发人员维护了一个公共符号服务器。 //此服务器为各种操作系统(Windows NT 4.0、Windows 2000、Windows XP 和 Windows Server 2003)、MDAC、IIS、ISA 和 .NET Framework 提供符号。 // //另外,您也可以将本地符号服务器安装在 Intranet 上或本地计算机上。 //要使用符号服务器,必须在项目中指定正确的服务器路径。 // //设置符号服务器的路径 //1.在 Visual Studio 中打开该项目。 //2.在“解决方案资源管理器”视图中选择解决方案的名称。 //3.从“项目”菜单中选择“设置启动项目”。 //4.在“解决方案 <项目> 属性页”对话框中,打开“通用属性”文件夹,单击“调试符号文件”。 //5.在“在这些路径中搜索符号文件”框中创建新的行,方法是双击空的新行或单击“新建行”按钮。 //6.在新行中输入符号服务器的路径。 //若要使用 Microsoft 公共符号服务器,请输入: //srv*c:\cache*http://msdl.microsoft.com/download/symbols; //若要使用 Intranet 符号服务器,请输入: //srv*\\server\path\symbols; //若要使用本地计算机上的符号服务器,请输入: //c:\path\symbols; //7.不要单击“检查项”按钮。 //8.单击“确定”按钮。 //9.将 symsrv.dll 从 Visual Studio .NET 安装盘复制到 C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE。 //-----------------dmp文件生成相关--------------------------------------------