#include ////////////////////////////////////////////////////////////////////////// // // »ç¿ë¿¹: // // #include "selfdump.h" // // winmain() // { // ... // // ´ë·« Ãʱ⿡... // CSelfDump::RegisterExectionFilter(); // <- ÄÚµå·Î ½ÇÇà // .. // } // // ȤÀº // // CApp theApp; // ... // CSelfDump g_cSelfDump(); // <- Àü¿ª º¯¼ö·Î ½ÇÇà // .. // // ==> ¸¸¾à, TestApp.exe¿¡¼­ Crash°¡ ¹ß»ýÇϸé, // (ÆÄ¶ó¹ÌÅ͸¦ default °ªÀ¸·Î À§ ÄÚµå¿Í °°ÀÌ ÁöÁ¤ÇßÀ»¶§), // // * TestApp.exe Path¿¡ Temp Æú´õ°¡ ÀÖ´Â °æ¿ì, ¹Ì´Ï ´ýÇÁÀÎ TestApp_yyyymmddhhmmssmmm.dmp°¡ »ý¼ºµÈ´Ù. // * TestApp.exe Path¿¡ Temp Æú´õ°¡ ¾ø´Â °æ¿ì, ´ýÇÁ¸¦ ³²±âÁö ¾Ê´Â´Ù. // * TestApp_*.dmpÀÇ Total ÆÄÀÏ Å©±â°¡ 1MB¸¦ ³Ñ¾î°¡¸é, °¡Àå ¿¾³¯²¯À» Áö¿ö¼­ ´ýÇÁ¸¦ ¸¸µé¾î Å©±â¸¦ À¯ÁöÇÑ´Ù. // * TestApp.exe PathÀÇ Temp Æú´õ¿¡ CrashDmp.log ÆÄÀÏ¿¡ ¿À·ù »çÇ×µéÀ» ±â·ÏÇÑ´Ù. // * XP/VistaÀÎ °æ¿ì, ±âÁ¸ÀÇ µð¹ö°Å·Îµµ ¿¬°áÀÌ µÈ´Ù. (drwtsn32, Problem Reports and Solutions Áö¿ø) // // (¾Ë¸²) minidump »ý¼ºÀ̹ǷÎ, !analyze -v Á¤µµ·Î »ç¿ëµÉ ¼ö ÀÖ´Ù. // (¾Ë¸²) TestApp.exe°¡ User°èÁ¤¿¡¼­ ½ÇÇàµÉ ¼ö ÀÖÀ¸¹Ç·Î, Temp Æú´õ´Â everyone 777 ±ÇÇÑÀÌ Àִ°ÍÀÌ ÁÁÀ» °ÍÀÌ´Ù. // (¾Ë¸²) CSelfDump ÇÔ¼ö±ºÀº Thread Safe º¸ÀåÀÌ ¾ø´Ù. µû¶ó¼­, .exe ½ÇÇà ÃʱâÈ­¶§ µÇµµ·Ï ´Ü Çѹø¸¸ È£ÃâÇϵµ·Ï ÇÑ´Ù. // (¾Ë¸²) dbghelp.dllÀ» »ç¿ëÇϴµ¥, ½ÇÇà .exeÀÇ module path ´ÙÀ½ system32 path ¼ø¼­·Î LoadLibrary¸¦ ½ÃµµÇÑ´Ù. // ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // // Parameter : // // CSelfDump::CSelfDump(...) / CSelfDump::RegisterExectionFilter(...) // ÀÇ Argument¸¦ ¼³¸íÇÑ´Ù. // // * lpszDumpPreFixName : ´ýÇÁÆÄÀÏÀÇ À̸§À» ÁöÁ¤ÇÑ´Ù. ÁöÁ¤µÇÁö ¾Ê´Â °æ¿ì, ½ÇÇà .exeÀÇ ÆÄÀϸíÀÌ µÈ´Ù. // ex) "abc"·Î ÁöÁ¤ÇÏ´Â °æ¿ì, abc_yyyymmddhhmmssmmm.dmp ÆÄÀϸíÀ¸·Î °­Á¦ ÁöÁ¤µÈ´Ù. // // * nMiniDumpType : ´ýÇÁÆÄÀÏÀÇ Å¸ÀÔ ÁöÁ¤. ±âº»°ªÀº MiniDumpNormalÀÌ´Ù. // **) ŸÀÔÀº http://msdn.microsoft.com/en-us/library/ms680519(VS.85).aspx ¿¡¼­ Âü°íÇϽÿÀ. // // * dwDumpCapacityBytes : PreFixNameÀ¸·Î ¸¸µé¾îÁø ´ýÇÁÆÄÀϵéÀÌ À¯ÁöµÉ ÆÄÀÏ Å©±â. ±âº»°ªÀº 1048576(1MB)ÀÌ´Ù. // **) ´ýÇÁ¸¦ ¸¸µé±â Àü¿¡ Å©±â¸¦ È®ÀÎÇÏ¿©, ³Ñ¾î°¡´Â °æ¿ì °¡Àå ¿¾³¯°ÍÀ» Â÷·Ê·Î Áö¿ö¼­ Å©±â¸¦ ÀÏÁ¤ÇÏ°Ô À¯ÁöÇÑ´Ù. // // * lpszDumpPath : ´ýÇÁÆÄÀÏÀ» »ý¼ºÇÒ Path. ±âº»°ªÀº .exeÀÇ Path ÇϺÎÀÇ Temp Æú´õÀÌ´Ù. // ex) ±âº»°ªÀÎ °æ¿ì, C:\ttt\abc.exe´Â C:\ttt\temp\abc_~~~~.dmp·Î ÀúÀåµÈ´Ù) // // * pfnCallback / pfnUserData : ´ýÇÁÆÄÀÏÀ» ¸¸µé±â Àü¿¡ È£Ãâ¹ÞÀ» ¼ö ÀÖ´Â callbackÀ» µî·Ï. ±âº»°ªÀº NULL // **) callback È£Ãâ¹Þ¾Æ UI¸¦ ¶ç¿ö ÁÙ ¼ö ÀÖ´Ù. FALSE¸¦ ¸®ÅÏÇÏ¸é ´ýÇÁ¸¦ ³²±âÁö ¾Ê´Â´Ù. // ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // // Tool : // // * CSelfDump::SetMiniDumpTypeWhenExist(...) // **) nMiniDumpTypeÀ» ·¹Áö½ºÆ®¸® °ªÀ¸·Î ¼¼ÆÃÇÑ´Ù. (·¹Áö½ºÆ®¸® °ªÀÌ Àִ°æ¿ì¸¸ ÇØ´ç) // ex) CSelfDump::RegisterExectionFilter(..., MiniDumpScanMemory, ...); // CSelfDump::SetMiniDumpTypeWhenExist(TEXT("Sofware\....\Tmp", TEXT("minidumptype")); // ÀÎ °æ¿ì, ¸¸¾à ·¹Áö½ºÆ®¸®¿¡ °ªÀÌ ÀÖ´Ù¸é, MiniDumpScanMemory°ª¿¡¼­ ·¹Áö½ºÆ®¸® °ªÀ¸·Î º¯°æµÈ´Ù. // ¸¸¾à, ÇØ´ç °ªÀÌ (DWORD)-1ÀÎ °æ¿ì¿¡´Â, ´ýÇÁ¸¦ ³²±âÁö ¾Êµµ·Ï ¿¹¿Ü 󸮵Ǿú´Ù. // ////////////////////////////////////////////////////////////////////////// // dbghelp.dll::MinuDumpWriteDump(...)ÀÇ prototype typedef BOOL (WINAPI *LPFN_MinuDumpWriteDump) (HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam); // Crash ¹ß»ý¶§ È£ÃâµÇ´Â CallbackÀÇ Prototype // FALSE¸¦ ¸®ÅÏÇϸé, ´ýÇÁ¸¦ ³²±âÁö ¾Ê´Â´Ù. typedef BOOL (*pfnCbOnCrash) (IN LPVOID lpUserData); // Capacity¿¡ ¸ÂÃç ÆÄÀÏÀ» »èÁ¦Çϰí write dump ÇϹǷÎ, Total ¿ë·®Àº ÃÖ´ë (1MB + ¸¶Áö¸· Dump File Å©±â) °¡ µÉ¼ö ÀÖ´Ù. #define DEFAULT_DUMP_CAPACITY 1048576 // 1MB // ´ýÇÁ ÆÄÀÏ manage¸¦ À§ÇØ, ÇѲ¨¹ø¿¡ »èÁ¦µÉ ÆÄÀÏ °³¼ö #define MAX_DEL_TRY_MANAGE 32 #define MAX_PATH_SELFDUMP 1024 class CSelfDump { public: CSelfDump(IN LPCTSTR lpszDumpPreFixName = NULL, IN MINIDUMP_TYPE nMiniDumpType = MiniDumpNormal, IN DWORD dwDumpCapacityBytes = DEFAULT_DUMP_CAPACITY, IN LPCTSTR lpszDumpPath = NULL, IN pfnCbOnCrash pfnCallback = NULL, IN LPVOID lpUserData = NULL); virtual ~CSelfDump(); public: static BOOL RegisterExceptionFilter (IN LPCTSTR lpszDumpPreFixName = NULL, IN MINIDUMP_TYPE nMiniDumpType = MiniDumpNormal, IN DWORD dwDumpCapacityBytes = DEFAULT_DUMP_CAPACITY, IN LPCTSTR lpszDumpPath = NULL, IN pfnCbOnCrash pfnCallback = NULL, IN LPVOID lpUserData = NULL); static VOID SetMiniDumpTypeWhenExist (IN LPCTSTR lpszRegKeyPath, IN LPCTSTR lpszValueName); private: static LONG WINAPI CbTopLevelExceptionFilter(struct _EXCEPTION_POINTERS *pExceptionInfo); static VOID WriteLogFile (IN LPCTSTR lpszPath, IN LPCTSTR lpszDumpFileFullPathName, IN PSYSTEMTIME pstTimeOccur, IN LPCTSTR lpszDumpPrefixName, IN BOOL bWriteDumpSuccess); // Utility private: static DWORD GetDefaultDumpPreFixName(OUT LPTSTR lpszDefaultDumpPreFixName, IN DWORD dwCchDefaultDumpPreFixName); static DWORD GetDefaultModuleTempPath(OUT LPTSTR lpszPath, IN DWORD dwCchPath); static HMODULE LoadLibrary_DbgHelp (VOID); static HMODULE LoadLibraryFromSystem (IN LPCTSTR lpFileName); static BOOL ManageCapacity (IN LPCTSTR lpszPath, IN LPCTSTR lpszDumpPreFixName, IN DWORD dwDumpCapacityBytes); static BOOL GetDumpFileFullPathName (IN LPCTSTR lpszPath, IN LPCTSTR lpszDumpPreFixName, OUT LPTSTR lpszDumpFileFullPathName, IN DWORD dwCchDumpFileFullPathName, OUT PSYSTEMTIME pstTime); static DWORD GetFilesSize (IN LPCTSTR lpszFindFileName, OUT LPTSTR lpszEarlyFileName, IN DWORD dwCchEarlyFileName); };