Выпустили мы программу в продажу,у кого-то крашит у кого-то нет. У разработчика - нет,но у некоторых юзеров - да. Как мне записывать\получать логи крашей их? Язык с++ То есть типо так, произошел краш,создается файл туда идет запись стека,адреса где был краш и т.д
Вот перевод ответа How to write a sample code that will crash and produce dump file? с комментариями и дополнениями:
#include <csignal>
#include <Windows.h>
#include <Dbghelp.h>
#include <crtdbg.h>
// Путь к программе. Инициализируется на старте.
static wchar_t appPath[MAX_PATH];
// Функция, которая пишет дамп в файл |fileName|.
static bool make_dump(EXCEPTION_POINTERS* e, const wchar_t* fileName) {
// Грузим системную библиотеку создания дампов.
// Возможно её не будет в системе, тогда надо положить её рядом с программой.
auto hDbgHelp = LoadLibraryW(L"dbghelp.dll");
if (!hDbgHelp)
return false;
auto pMiniDumpWriteDump =
(decltype(&MiniDumpWriteDump))GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
if (!pMiniDumpWriteDump)
return false;
// Открываем файл.
HANDLE hFile = ::CreateFileW(fileName, GENERIC_WRITE, FILE_SHARE_READ, 0,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE || hFile == nullptr)
return false;
MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
exceptionInfo.ThreadId = ::GetCurrentThreadId();
exceptionInfo.ExceptionPointers = e;
exceptionInfo.ClientPointers = FALSE;
const DWORD DUMP_FLAGS = MiniDumpWithDataSegs | MiniDumpWithPrivateReadWriteMemory;
// Пишем дамп в файл.
BOOL dumped = pMiniDumpWriteDump(::GetCurrentProcess(),
::GetCurrentProcessId(),
hFile,
MINIDUMP_TYPE(DUMP_FLAGS),
e ? &exceptionInfo : NULL,
NULL,
NULL);
// Если не удалось сделать дамп - пишем ошибку.
if (!dumped) {
DWORD err = GetLastError();
DWORD written;
::WriteFile(hFile, &err, 4, &written, 0);
}
::CloseHandle(hFile);
return true;
}
// Старый обработчик исключений.
static LPTOP_LEVEL_EXCEPTION_FILTER s_oldEH;
// Наш обработчик исключений.
static LONG CALLBACK unhandled_exception_handler(EXCEPTION_POINTERS* e) {
// Формируем имя файла.
SYSTEMTIME t;
GetSystemTime(&t);
static wchar_t fileName[1024];
wsprintfW(fileName, L"%s\\dump_%d%02d%02d_%02d%02d%02d.dmp", appPath,
t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
// Пишем дамп в файл.
auto dumpOk = make_dump(e, fileName);
// Если он не записался, передаем исключение дальше.
if (!dumpOk)
return s_oldEH ? s_oldEH(e) : EXCEPTION_CONTINUE_SEARCH;
// Показываем пользователю куда записался дамп.
static wchar_t buf[1024];
wsprintfW(buf,
L"Application will be closed due to a fatal error.\r\n"
L"Crash dump was saved to\r\n%s",
fileName);
MessageBox(nullptr, buf, nullptr, MB_ICONERROR | MB_OK);
// Убиваем процесс.
::TerminateProcess(::GetCurrentProcess(), 5);
return 0;
}
// Обработка |abort()|.
static void abort_handler(int) {
::RaiseException(0x00BAD00A, 0, 0, NULL);
}
// Обработка вызова pure virtual функции.
static void purecall_handler() {
::RaiseException(0x00BAD00C, 0, 0, NULL);
}
// Еще какие-то ошибки CRT.
static int crt_report_handler(int reportType, wchar_t*, int* pRet) {
if (reportType == _CRT_WARN) {
if (pRet)
*pRet = 0;
return 0;
}
::RaiseException(0x00BAD00E, 0, 0, NULL);
return 0;
}
// Функция инициализации.
static void init() {
// Сохраняем путь к .exe , на случай если креш не даст его получить потом.
::GetModuleFileNameW(GetModuleHandle(nullptr), appPath, MAX_PATH);
// Обрезаем до папки.
*wcsrchr(appPath, L'\\') = '\0';
// Устанавливаем обработчики.
s_oldEH = ::SetUnhandledExceptionFilter(unhandled_exception_handler);
::_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
::signal(SIGABRT, abort_handler);
::_set_purecall_handler(purecall_handler);
_CrtSetReportHookW2(_CRT_RPTHOOK_INSTALL, crt_report_handler);
(void)&crt_report_handler;
}
// Инициализируемся до main()
bool g_crashdump_initialized = (init(), false);
А вообще просто используйте crashpad.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Как вернуть неизвестный заранее тип переменной шаблона при помощи ключевого слова auto ?
У меня класс наследуется от QWidgetВ этом классе я создал grid_layout и меню классы
Необходимо получить список всех установленных приложений на удаленном компьютереКласс WMI Win32_Pdoduct показывает только программы установленные...