123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- #include "StdAfx.h"
- #include "AutoDmp.h"
- #include <string>
- #include <sstream>
- //-----------------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文件生成相关--------------------------------------------
|