В средах Windows
(XP
и Win 7
):
- Каков наилучший способ автоматического создания аварийного дампа, сгенерированного при сбое процессов в системе?
- Может ли пакет установщика (MSI) сделать это?
В средах Windows
(XP
и Win 7
):
Один из лучших способов иметь автоматический дамп для любого/конкретного процесса в Windows - это настроить набор записей в реестре. Я попробовал следующее в Windows 7 64 бит.
Откройте файл notepad.exe, вставьте следующую запись и сохраните ее как "EnableDump.reg". Вы можете указать любое ваше имя.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps]
"DumpFolder"=hex(2):44,00,3a,00,5c,00,64,00,75,00,6d,00,70,00,00,00
"DumpCount"=dword:00000010
"DumpType"=dword:00000002
"CustomDumpFlags"=dword:00000000
Дважды щелкните "EnableDump.reg" и выберите "Да". Я дал папке дампа как "d:\dump". Вы можете изменить его в любую папку.
Попробуйте выполнить аварийное приложение, Windows отобразит диалоговое окно с ошибкой. Выберите "Закрыть программу". После этого вы увидите дамп в сконфигурированной папке. Имя файла дампа будет .exe..dmp.
Подробнее см. ссылку ниже.
http://msdn.microsoft.com/en-us/library/bb787181(VS.85).aspx
Windows XP: Следующие шаги включают автоматические аварийные свалки:
1) Open a command prompt, running as administrator
2) Run drwtsn32 -i. This will install Doctor Watson as the default debugger when something crashes
3) Click Ok
4) From the command prompt, run drwtsn32
5) Set the Crash Dump path to your favorite directory, or leave the default.
6) Set the Crash Dump Type to mini. Note that under some circumstances, we may ask you for a full crash dump.
7) Make sure the Dump All Thread Contexts and Create Crash Dump File options are selected.
8) Click Ok
9) If a user.dmp file already exists in the Crash Dump path, delete it.
Windows 7: Местоположение:
C:\Users[Current User when app crashed]\AppData\Local\Microsoft\Windows\WER\ReportArchive
Ниже приведена улучшенная версия от другого Ответа:
Наличие собственной структуры создания дампов, которая автоматически создает дамп процесса при обнаружении любого необработанного исключения, позволит избежать необходимости установки WinDbg
для клиентов.
При запуске приложения используйте SetUnhandledExceptionFilter(...)
API SetUnhandledExceptionFilter(...)
для регистрации обратного вызова (т. SetUnhandledExceptionFilter(...)
Обработчик исключений уровня приложения). Теперь зарегистрированная функция обратного вызова вызывается всякий раз, когда есть какое-либо исключение, которое не обрабатывается. Затем вы можете создать дамп процесса с помощью MiniDumpWriteDump(...)
из DbgHelp.dll
.
#ifndef CRASH_REPORTER_H
#define CRASH_REPORTER_H
//Exclude rarely used content from the Windows headers.
#ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# undef WIN32_LEAN_AND_MEAN
#else
# include <windows.h>
#endif
#include <tchar.h>
#include <DbgHelp.h>
class CrashReporter {
public:
inline CrashReporter() { Register(); }
inline ~CrashReporter() { Unregister(); }
inline static void Register() {
if(m_lastExceptionFilter != NULL) {
fprintf(stdout, "CrashReporter: is already registered\n");
fflush(stdout);
}
SetErrorMode(SEM_FAILCRITICALERRORS);
//ensures UnHandledExceptionFilter is called before App dies.
m_lastExceptionFilter = SetUnhandledExceptionFilter(UnHandledExceptionFilter);
}
inline static void Unregister() {
SetUnhandledExceptionFilter(m_lastExceptionFilter);
}
private:
static LPTOP_LEVEL_EXCEPTION_FILTER m_lastExceptionFilter;
static LONG WINAPI UnHandledExceptionFilter(_EXCEPTION_POINTERS *);
};
#endif // CRASH_REPORTER_H
#include "crash-report.h"
#include <stdio.h>
LPTOP_LEVEL_EXCEPTION_FILTER CrashReporter::m_lastExceptionFilter = NULL;
typedef BOOL (WINAPI *MiniDumpWriteDumpFunc)(HANDLE hProcess, DWORD ProcessId
, HANDLE hFile
, MINIDUMP_TYPE DumpType
, const MINIDUMP_EXCEPTION_INFORMATION *ExceptionInfo
, const MINIDUMP_USER_STREAM_INFORMATION *UserStreamInfo
, const MINIDUMP_CALLBACK_INFORMATION *Callback
);
LONG WINAPI CrashReporter::UnHandledExceptionFilter(struct _EXCEPTION_POINTERS *exceptionPtr)
{
//we load DbgHelp.dll dynamically, to support Windows 2000
HMODULE hModule = ::LoadLibraryA("DbgHelp.dll");
if (hModule) {
MiniDumpWriteDumpFunc dumpFunc = reinterpret_cast<MiniDumpWriteDumpFunc>(
::GetProcAddress(hModule, "MiniDumpWriteDump")
);
if (dumpFunc) {
//fetch system time for dump-file name
SYSTEMTIME SystemTime;
::GetLocalTime(&SystemTime);
//choose proper path for dump-file
wchar_t dumpFilePath[MAX_PATH] = {0};
_snwprintf_s(dumpFilePath, MAX_PATH, L"crash_%04d-%d-%02d_%d-%02d-%02d.dmp"
, SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay
, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond
);
//create and open the dump-file
HANDLE hFile = ::CreateFileW( dumpFilePath, GENERIC_WRITE
, FILE_SHARE_WRITE
, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_HIDDEN
, NULL
);
if (hFile != INVALID_HANDLE_VALUE) {
_MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
exceptionInfo.ThreadId = GetCurrentThreadId();
exceptionInfo.ExceptionPointers = exceptionPtr;
exceptionInfo.ClientPointers = NULL;
//at last write crash-dump to file
bool ok = dumpFunc(::GetCurrentProcess(), ::GetCurrentProcessId()
, hFile, MiniDumpNormal
, &exceptionInfo, NULL, NULL
);
//dump-data is written, and we can close the file
CloseHandle(hFile);
if (ok) {
//Return from UnhandledExceptionFilter and execute the associated exception handler.
// This usually results in process termination.
return EXCEPTION_EXECUTE_HANDLER;
}
}
}
}
//Proceed with normal execution of UnhandledExceptionFilter.
// That means obeying the SetErrorMode flags,
// or invoking the Application Error pop-up message box.
return EXCEPTION_CONTINUE_SEARCH;
}
#include "3rdParty/crash-report.h"
int main(int argc, char *argv[])
{
CrashReporter crashReporter;
(void)crashReporter; //prevents unused warnings
// [application main loop should be here]
return 0;
}