mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-20 05:04:53 -04:00
minidump integration
This commit is contained in:
parent
96eaeb4851
commit
b459f2010e
9 changed files with 130 additions and 21 deletions
|
@ -22,7 +22,7 @@ if(NOT STEAMWORKS_SDK_DIR)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
add_compile_options(/W4 /EHa /DNOMINMAX /D_CRT_SECURE_NO_WARNINGS /J)
|
add_compile_options(/W4 /EHsc /DNOMINMAX /D_CRT_SECURE_NO_WARNINGS /J)
|
||||||
set(STANDARD_LIBRARIES "")
|
set(STANDARD_LIBRARIES "")
|
||||||
else()
|
else()
|
||||||
add_compile_options(-Wall -Wextra -Werror -Wno-unused-result -Wno-unused-parameter -Wno-unused-value -Wno-extern-c-compat -funsigned-char)
|
add_compile_options(-Wall -Wextra -Werror -Wno-unused-result -Wno-unused-parameter -Wno-unused-value -Wno-extern-c-compat -funsigned-char)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "../platform/error.h"
|
#include "../platform/error.h"
|
||||||
#include "../platform/platform.h"
|
#include "../platform/platform.h"
|
||||||
|
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#define console_max_characters 120
|
#define console_max_characters 120
|
||||||
#define console_max_lines 300
|
#define console_max_lines 300
|
||||||
|
@ -89,6 +90,8 @@ void show_flags(int number,char **flags,char nums)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void spell_group_invis()
|
void spell_group_invis()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -245,6 +248,11 @@ static void console_add_line(const char *line) {
|
||||||
console_add_line_s(line, strlen(line));
|
console_add_line_s(line, strlen(line));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void crash_task(va_list lst) {
|
||||||
|
char *c = (char *)0x1;
|
||||||
|
*c = 1;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *cmd_buffer;
|
char *cmd_buffer;
|
||||||
const char *command;
|
const char *command;
|
||||||
|
@ -645,6 +653,13 @@ static int process_with_params(const char *cmd, const char *args) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (istrcmp(cmd, "crash") == 0) {
|
if (istrcmp(cmd, "crash") == 0) {
|
||||||
|
if (istrcmp(args,"seh") == 0) {
|
||||||
|
char *c = (char *)(args - (uintptr_t)args);
|
||||||
|
*c = 'x';
|
||||||
|
}
|
||||||
|
else if (istrcmp(args, "task") == 0) {
|
||||||
|
add_task(65536,crash_task);
|
||||||
|
}
|
||||||
throw_exception(args);
|
throw_exception(args);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ if(WIN32)
|
||||||
target_sources(skeldal_platform PRIVATE
|
target_sources(skeldal_platform PRIVATE
|
||||||
windows/save_folder.cpp
|
windows/save_folder.cpp
|
||||||
windows/map_file.cpp
|
windows/map_file.cpp
|
||||||
|
windows/minidump.cpp
|
||||||
)
|
)
|
||||||
add_executable(skeldal WIN32)
|
add_executable(skeldal WIN32)
|
||||||
target_sources(skeldal PRIVATE
|
target_sources(skeldal PRIVATE
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "legacy_coroutines.h"
|
#include "legacy_coroutines.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "seh.h"
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
@ -116,7 +117,7 @@ static void broadcast_message(EVENT_MSG *msg) {
|
||||||
clean_task_table();
|
clean_task_table();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void crash_task_exception() {
|
/*static void crash_task_exception() {
|
||||||
try {
|
try {
|
||||||
throw;
|
throw;
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
|
@ -125,7 +126,7 @@ static void crash_task_exception() {
|
||||||
display_error("Unhandled exception in task %d: unknown/crash",q_current_task());
|
display_error("Unhandled exception in task %d: unknown/crash",q_current_task());
|
||||||
}
|
}
|
||||||
abort();
|
abort();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
int add_task(int stack,TaskerFunctionName fcname,...) {
|
int add_task(int stack,TaskerFunctionName fcname,...) {
|
||||||
|
@ -135,14 +136,12 @@ int add_task(int stack,TaskerFunctionName fcname,...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fcname);
|
va_start(args, fcname);
|
||||||
new_task->thr = std::thread([&]{
|
new_task->thr = std::thread([&]{
|
||||||
|
SEH_MONITOR_BEGIN {
|
||||||
new_task->resume_flag.wait(false);
|
new_task->resume_flag.wait(false);
|
||||||
new_task->resume_flag = false;
|
new_task->resume_flag = false;
|
||||||
try {
|
|
||||||
fcname(args);
|
fcname(args);
|
||||||
clean_up_current_task();
|
clean_up_current_task();
|
||||||
} catch (...) {
|
}SEH_MONITOR_END;
|
||||||
crash_task_exception();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
switch_to_task(new_task);
|
switch_to_task(new_task);
|
||||||
return id;
|
return id;
|
||||||
|
|
|
@ -2,9 +2,11 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
#ifndef _SKELDAL_PLATFORM_HEADER_
|
#ifndef _SKELDAL_PLATFORM_HEADER_
|
||||||
#define _SKELDAL_PLATFORM_HEADER_
|
#define _SKELDAL_PLATFORM_HEADER_
|
||||||
|
|
||||||
|
|
||||||
#define BGSWITCHBIT 0x8000
|
#define BGSWITCHBIT 0x8000
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -124,6 +126,16 @@ typedef int (*LIST_FILES_CALLBACK)(const char *, LIST_FILE_TYPE , size_t, void *
|
||||||
int list_files(const char *directory, int type, LIST_FILES_CALLBACK cb, void *ctx);
|
int list_files(const char *directory, int type, LIST_FILES_CALLBACK cb, void *ctx);
|
||||||
|
|
||||||
|
|
||||||
|
#define WM_RELOADMAP (WM_APP+215)
|
||||||
|
#define E_RELOADMAP 40
|
||||||
|
|
||||||
|
typedef struct _ReloadMapInfo {
|
||||||
|
const char *fname;
|
||||||
|
int sektor;
|
||||||
|
} ReloadMapInfo;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -135,14 +147,4 @@ void init_joystick(const INI_CONFIG_SECTION *section);
|
||||||
char is_joystick_used();
|
char is_joystick_used();
|
||||||
char is_joystick_enabled();
|
char is_joystick_enabled();
|
||||||
|
|
||||||
#define WM_RELOADMAP (WM_APP+215)
|
|
||||||
#define E_RELOADMAP 40
|
|
||||||
|
|
||||||
typedef struct _ReloadMapInfo {
|
|
||||||
const char *fname;
|
|
||||||
int sektor;
|
|
||||||
} ReloadMapInfo;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
10
platform/seh.h
Normal file
10
platform/seh.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "windows/minidump.h"
|
||||||
|
#define SEH_MONITOR_BEGIN __try
|
||||||
|
#define SEH_MONITOR_END __except(GenerateMinidumpAndExit(GetExceptionInformation())) {}
|
||||||
|
#else
|
||||||
|
#define SEH_TRY
|
||||||
|
#define SEH_CATCH
|
||||||
|
#endif
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "../getopt.h"
|
#include "../getopt.h"
|
||||||
#include "../platform.h"
|
#include "../platform.h"
|
||||||
#include "../error.h"
|
#include "../error.h"
|
||||||
|
#include "../seh.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -108,6 +109,10 @@ int __stdcall WinMain(HINSTANCE,HINSTANCE ,LPSTR, INT) {
|
||||||
argv[i][need-1] = 0;
|
argv[i][need-1] = 0;
|
||||||
}
|
}
|
||||||
GlobalFree(szArglist);
|
GlobalFree(szArglist);
|
||||||
return main(argc, argv);
|
int r = -256;
|
||||||
|
SEH_MONITOR_BEGIN {
|
||||||
|
r = main(argc, argv);
|
||||||
|
} SEH_MONITOR_END;
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
73
platform/windows/minidump.cpp
Normal file
73
platform/windows/minidump.cpp
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#include "minidump.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <version.h>
|
||||||
|
|
||||||
|
#include <dbghelp.h>
|
||||||
|
#pragma comment(lib, "dbghelp.lib")
|
||||||
|
|
||||||
|
|
||||||
|
DWORD WINAPI MessageBoxThread(LPVOID ptr) {
|
||||||
|
const wchar_t *txt = reinterpret_cast<const wchar_t *>(ptr);
|
||||||
|
return MessageBoxW(NULL, txt, L"SKELDAL", MB_OK|MB_ICONEXCLAMATION|MB_SYSTEMMODAL|MB_APPLMODAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MessageBoxAndExit(const wchar_t *msg, const wchar_t *fname) {
|
||||||
|
DWORD tid;
|
||||||
|
HANDLE h = CreateThread(NULL, 0, MessageBoxThread, const_cast<wchar_t *>(msg), 0, &tid);
|
||||||
|
WaitForSingleObject(h, INFINITE);
|
||||||
|
if (fname != nullptr) {
|
||||||
|
STARTUPINFOW si = { sizeof(si) };
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
|
||||||
|
wchar_t command[MAX_PATH + 20];
|
||||||
|
swprintf_s(command, L"explorer.exe /select,\"%s\"", fname);
|
||||||
|
if (CreateProcessW(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ExitProcess(256);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LONG WINAPI GenerateMinidumpAndExit(EXCEPTION_POINTERS* pExceptionInfo) {
|
||||||
|
wchar_t path[MAX_PATH];
|
||||||
|
_wfullpath(path, L"crash-" SKELDAL_VERSION ".dmp", _countof(path));
|
||||||
|
HANDLE hFile = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
|
||||||
|
if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE)) {
|
||||||
|
MINIDUMP_EXCEPTION_INFORMATION mdei;
|
||||||
|
mdei.ThreadId = GetCurrentThreadId();
|
||||||
|
mdei.ExceptionPointers = pExceptionInfo;
|
||||||
|
mdei.ClientPointers = FALSE;
|
||||||
|
|
||||||
|
BOOL ret = MiniDumpWriteDump(
|
||||||
|
GetCurrentProcess(),
|
||||||
|
GetCurrentProcessId(),
|
||||||
|
hFile,
|
||||||
|
static_cast<MINIDUMP_TYPE>(MiniDumpWithDataSegs | MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory),
|
||||||
|
&mdei,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
CloseHandle(hFile);
|
||||||
|
if (ret) {
|
||||||
|
wchar_t msg[MAX_PATH*2];
|
||||||
|
swprintf_s(msg,L"Application crashed. The crash report has been stored to the file:\r\n\r\n%s\r\n\r\nPress OK to browse file in explorer",path);
|
||||||
|
MessageBoxAndExit(msg,path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
DWORD error = GetLastError();
|
||||||
|
wchar_t msg[MAX_PATH*2];
|
||||||
|
swprintf_s(msg,L"Application crashed. Failed to write crash report to the file:\r\n\r\n%s\r\nError: %X", path, error);
|
||||||
|
MessageBoxAndExit(msg,path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
4
platform/windows/minidump.h
Normal file
4
platform/windows/minidump.h
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
LONG WINAPI GenerateMinidumpAndExit(EXCEPTION_POINTERS* pExceptionInfo);
|
Loading…
Add table
Add a link
Reference in a new issue