2013年6月25日 星期二

指定應用程式 Crash Dump 的儲存位置

在 Windows XP 作業系統下,應用程式 Crash 時會產生一種副檔名為 dmp 的檔案,內容記載著執行檔的記憶體資料及 StackTrace 等資訊可用來 Debug。

但有時會發現應用程式在 Crash 時並不會產生 dmp 檔案,其實要說有沒有產生我自己也不是很確定,可能是有產生,只是存放的位置我沒找到而已,原因不明當時沒有仔細查,不過不重要,因為到了 Windows Vista 之後這個情況更明顯了,似乎要做點什麼才能讓作業系統產生 Dump 檔案,MSDN 上的說明也的確是這麼說的,所以這裡記錄一下讓作業系統產生 dmp 檔案,且可以指定檔案產生後存放位置的方法,方法很容易,寫機碼即可,假設我的應用程式執行檔名稱為 MyApp.exe 以下示範當 Crash 時將 Dump 檔案產生出來並存放在指定位置的方式

HKEY hKey(0);
DWORD disp;
HKEY hKeyCreate(0);
if(ERROR_SUCCESS == ::RegCreateKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows\\Windows Error Reporting\\LocalDumps\\MyApp.exe"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_WOW64_64KEY, NULL, &hKey, &disp))
{
DWORD dwValue(1);
CString strFolderPath(_T("C:\\Users\\Ascii\\AppData\\Local\\MyApp\\"));
RegSetValueEx(hKey, _T("DumpType"), NULL, REG_DWORD, (BYTE*)&dwValue, sizeof(DWORD));
RegSetValueEx(hKey, _T("DumpFolder"), NULL, REG_SZ, (BYTE *)(LPCTSTR)strFolderPath, (strFolderPath.GetLength() + 1) * 2);
}
RegCloseKey(hKey);

只要這些機碼被正常寫入,之後當 MyApp.exe 發生 Crash 時,就可以到上述的指定資料夾內找到一個檔案名稱結構為 "應用程式名稱.exe.奇怪的數字.dmp" 的檔案,例如 MyApp.exe.7024.dmp

上頭範例寫的 DumpFolder 很明顯的就是期望儲存的路徑,而 DumpType 是指產生 Mini Dump 檔案,相關資訊可以參考這裡:Collecting User-Mode Dumps

0:Custom dump
1:Mini dump
2:Full dump

此外需特別注意的是在 RegCreateKey 時我多下了一個參數為 KEY_WOW64_64KEY,原因可以參考這篇:32-bits、64-bits 作業系統的 Registry 注意事項

知道這個方法除了對 Windows 桌面應用程式有用處之外,其實在 Windows 8 底下的 Windows Store App 也是可以用這招拿到 Crash Dump 的,如果你是用 C++ 在撰寫 Store App,那麼這個 dmp 檔案可以讓你用傳統的 WinDbg 來查到 Crash 的程式碼位置。

但如果是使用 C# 等語言,因為這些語言還會被經過翻譯且是運行在 CLR 之上的,所以 WinDbg 拿到的資訊是被 Windows Error Reporting 處理過的位置,非實際上發生 UnhandledException 的位置,就是用 WinDbg 看不出什麼線索的意思啦,目前我還不知道該怎麼解讀 以 C# 所撰寫的 Store App 產生出來的 dmp 檔案,手邊的 Windows Phone 及 Windows RT 專案只有先透過其他的方法收集 UnhandledException 資訊來抓蟲,目前是使用一套叫 HockeyApp 的套件,使用上很簡單,可自行參考 HockeyApp 官網,目前官網有提供 Windows Phone 及 Windows RT 的 SDK 供下載使用。

沒有留言:

張貼留言