Stacktraces with dwarf symbols #280
+1
-3
@@ -25,7 +25,7 @@ toolchain_64 := x86_64-w64-mingw32-
|
||||
|
||||
gitrev := $(shell git rev-parse HEAD)
|
||||
cppflags := -I src -I src/main -I src/test -DGITREV=$(gitrev)
|
||||
cflags := -O2 -pipe -ffunction-sections -fdata-sections \
|
||||
cflags := -g -O2 -pipe -ffunction-sections -fdata-sections \
|
||||
-Wall -std=c99 -DPSAPI_VERSION=1
|
||||
cflags_release := -Werror
|
||||
ldflags := -Wl,--gc-sections -static-libgcc
|
||||
@@ -240,7 +240,6 @@ $$(dll_$1_$2_$3) $$(implib_$1_$2_$3): $$(obj_$1_$2_$3) $$(abslib_$1_$2_$3) \
|
||||
$(V)$$(toolchain_$1)gcc -shared \
|
||||
-o $$(dll_$1_$2_$3) -Wl,--out-implib,$$(implib_$1_$2_$3) \
|
||||
-Wl,--start-group $$^ -Wl,--end-group $$(ldflags_$3)
|
||||
$(V)$$(toolchain_$1)strip $$(dll_$1_$2_$3)
|
||||
$(V)$$(toolchain_$1)ranlib $$(implib_$1_$2_$3)
|
||||
|
||||
endef
|
||||
@@ -257,7 +256,6 @@ $$(exe_$1_$2_$3): $$(obj_$1_$2_$3) $$(abslib_$1_$2_$3) $$(absdpl_$1_$2_$3) \
|
||||
| $$(bindir_$1_$2)
|
||||
$(V)echo ... $$@
|
||||
$(V)$$(toolchain_$1)gcc -o $$@ $$^ $$(ldflags_$3)
|
||||
$(V)$$(toolchain_$1)strip $$@
|
||||
|
||||
endef
|
||||
|
||||
|
||||
@@ -257,6 +257,7 @@ $(zipdir)/iidx-09-to-12.zip: \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
build/bin/indep-32/inject.exe \
|
||||
dist/dwarfstack/32/dwarfstack.dll \
|
||||
dist/iidx/config.bat \
|
||||
dist/iidx/gamestart-09.bat \
|
||||
dist/iidx/gamestart-10.bat \
|
||||
@@ -282,6 +283,7 @@ $(zipdir)/iidx-13.zip: \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
build/bin/indep-32/inject.exe \
|
||||
dist/dwarfstack/32/dwarfstack.dll \
|
||||
dist/iidx/config.bat \
|
||||
dist/iidx/gamestart-13.bat \
|
||||
dist/iidx/iidxhook-13.conf \
|
||||
@@ -298,6 +300,7 @@ $(zipdir)/iidx-14-to-17.zip: \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
build/bin/indep-32/inject.exe \
|
||||
dist/dwarfstack/32/dwarfstack.dll \
|
||||
dist/iidx/config.bat \
|
||||
dist/iidx/gamestart-14.bat \
|
||||
dist/iidx/gamestart-15.bat \
|
||||
@@ -485,6 +488,7 @@ $(zipdir)/jb-01.zip: \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/jbio.dll \
|
||||
dist/dwarfstack/32/dwarfstack.dll \
|
||||
dist/jb/config.bat \
|
||||
dist/jb/gamestart-01.bat \
|
||||
dist/jb/jbhook-01.conf \
|
||||
@@ -499,6 +503,7 @@ $(zipdir)/jb-02.zip: \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/jbio.dll \
|
||||
dist/dwarfstack/32/dwarfstack.dll \
|
||||
dist/jb/config.bat \
|
||||
dist/jb/gamestart-02.bat \
|
||||
dist/jb/jbhook-02.conf \
|
||||
@@ -659,6 +664,7 @@ $(zipdir)/ddr-12-us.zip: \
|
||||
build/bin/indep-32/ddrio-smx.dll \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
dist/dwarfstack/32/dwarfstack.dll \
|
||||
dist/ddr/config.bat \
|
||||
dist/ddr/gamestart-12-us.bat \
|
||||
dist/ddr/gamestart-12-eu.bat \
|
||||
@@ -776,6 +782,7 @@ $(zipdir)/popn-15-to-18.zip: \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/popnio.dll \
|
||||
build/bin/indep-32/ezusb2-popn-shim.dll \
|
||||
dist/dwarfstack/32/dwarfstack.dll \
|
||||
dist/popn/config.bat \
|
||||
dist/popn/gamestart-15.bat \
|
||||
dist/popn/gamestart-16.bat \
|
||||
@@ -807,6 +814,7 @@ $(BUILDDIR)/tests.zip: \
|
||||
build/bin/indep-32/iidxhook-util-config-gfx-test.exe \
|
||||
build/bin/indep-32/iidxhook-util-config-misc-test.exe \
|
||||
build/bin/indep-32/iidxhook-util-config-sec-test.exe \
|
||||
dist/dwarfstack/32/dwarfstack.dll \
|
||||
build/bin/indep-32/inject.exe \
|
||||
build/bin/indep-32/security-id-test.exe \
|
||||
build/bin/indep-32/security-mcode-test.exe \
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
+1
@@ -0,0 +1 @@
|
||||
Version/release: https://github.com/ssbssa/dwarfstack/releases/tag/2.2
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2019 Hannes Domani
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __DWARFSTACK_H__
|
||||
#define __DWARFSTACK_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#if defined(DWST_STATIC)
|
||||
#define EXPORT
|
||||
#elif defined(DWST_SHARED)
|
||||
#define EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// dwstCallback(): callback function
|
||||
// addr: stack address
|
||||
// filename: source file location
|
||||
// lineno: line number
|
||||
// funcname: function name
|
||||
// context: user-provided pointer (callbackContext)
|
||||
// columnno: column number
|
||||
typedef void dwstCallback(
|
||||
uint64_t addr,const char *filename,int lineno,const char *funcname,
|
||||
void *context,int columnno );
|
||||
|
||||
typedef void dwstCallbackW(
|
||||
uint64_t addr,const wchar_t *filename,int lineno,const char *funcname,
|
||||
void *context,int columnno );
|
||||
|
||||
// special values for lineno:
|
||||
|
||||
// DWST_BASE_ADDR: inform about the used image base address
|
||||
// (important in case it's not the same as the preferred image base address)
|
||||
// addr: used image base address
|
||||
// filename: executable location
|
||||
#define DWST_BASE_ADDR 0
|
||||
|
||||
// DWST_NO_DBG_SYM: no debug information available
|
||||
// addr: stack address
|
||||
// filename: executable location
|
||||
#define DWST_NO_DBG_SYM -1
|
||||
|
||||
// DWST_NO_SRC_FILE: no source file information available
|
||||
// addr: stack address
|
||||
// filename: executable location
|
||||
#define DWST_NO_SRC_FILE -2
|
||||
|
||||
// DWST_NOT_FOUND: no information available (invalid address?)
|
||||
// addr: stack address
|
||||
// filename: executable location
|
||||
#define DWST_NOT_FOUND -3
|
||||
|
||||
|
||||
// dwstOfFile(): stack information of file
|
||||
// name: executable location
|
||||
// imageBase: used image base address
|
||||
// addr: stack addresses
|
||||
// count: number of addresses
|
||||
// callbackFunc: callback function
|
||||
// callbackContext: user-provided pointer (context)
|
||||
// (for example see examples/addr2line/)
|
||||
EXPORT int dwstOfFile(
|
||||
const char *name,uint64_t imageBase,
|
||||
uint64_t *addr,int count,
|
||||
dwstCallback *callbackFunc,void *callbackContext );
|
||||
|
||||
EXPORT int dwstOfFileW(
|
||||
const wchar_t *name,uint64_t imageBase,
|
||||
uint64_t *addr,int count,
|
||||
dwstCallbackW *callbackFunc,void *callbackContext );
|
||||
|
||||
|
||||
// dwstOfProcess(): stack information of current process
|
||||
// addr: stack addresses
|
||||
// count: number of addresses
|
||||
// callbackFunc: callback function
|
||||
// callbackContext: user-provided pointer (context)
|
||||
EXPORT int dwstOfProcess(
|
||||
uintptr_t *addr,int count,
|
||||
dwstCallback *callbackFunc,void *callbackContext );
|
||||
|
||||
EXPORT int dwstOfProcessW(
|
||||
uintptr_t *addr,int count,
|
||||
dwstCallbackW *callbackFunc,void *callbackContext );
|
||||
|
||||
|
||||
// dwstOfLocation(): stack information of current location
|
||||
// callbackFunc: callback function
|
||||
// callbackContext: user-provided pointer (context)
|
||||
// (for example see examples/location/)
|
||||
EXPORT int dwstOfLocation(
|
||||
dwstCallback *callbackFunc,void *callbackContext );
|
||||
|
||||
EXPORT int dwstOfLocationW(
|
||||
dwstCallbackW *callbackFunc,void *callbackContext );
|
||||
|
||||
|
||||
// dwstOfException(): stack information of exception
|
||||
// context: ContextRecord of exception
|
||||
// callbackFunc: callback function
|
||||
// callbackContext: user-provided pointer (context)
|
||||
// (for example see examples/exception/)
|
||||
EXPORT int dwstOfException(
|
||||
void *context,
|
||||
dwstCallback *callbackFunc,void *callbackContext );
|
||||
|
||||
EXPORT int dwstOfExceptionW(
|
||||
void *context,
|
||||
dwstCallbackW *callbackFunc,void *callbackContext );
|
||||
|
||||
|
||||
// dwstExceptionDialog(): show dialog on unhandled exception
|
||||
// extraInfo: extra information shown in dialog
|
||||
// (for example see examples/exception-dialog/)
|
||||
EXPORT void dwstExceptionDialog(
|
||||
const char *extraInfo );
|
||||
|
||||
EXPORT void dwstExceptionDialogW(
|
||||
const wchar_t *extraInfo );
|
||||
|
||||
|
||||
#ifndef DWST_STATIC
|
||||
// dwstDemangle(): demangle gcc style c++ symbols
|
||||
// mangled: mangled name
|
||||
// demangled: demangled name
|
||||
// length: size of demangled buffer
|
||||
EXPORT size_t dwstDemangle(
|
||||
const char *mangled,
|
||||
char *demangled,size_t length );
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
LIBRARY dwarfstack
|
||||
|
||||
EXPORTS
|
||||
dwstOfFile @ 441
|
||||
dwstOfFileW @ 443
|
||||
dwstOfProcess @ 446
|
||||
dwstOfProcessW @ 448
|
||||
dwstOfLocation @ 444
|
||||
dwstOfLocationW @ 445
|
||||
dwstOfException @ 438
|
||||
dwstOfExceptionW @ 440
|
||||
dwstExceptionDialog @ 436
|
||||
dwstExceptionDialogW @ 437
|
||||
@@ -0,0 +1,13 @@
|
||||
LIBRARY dwarfstack
|
||||
|
||||
EXPORTS
|
||||
dwstOfFile @ 441
|
||||
dwstOfFileW @ 443
|
||||
dwstOfProcess @ 446
|
||||
dwstOfProcessW @ 448
|
||||
dwstOfLocation @ 444
|
||||
dwstOfLocationW @ 445
|
||||
dwstOfException @ 438
|
||||
dwstOfExceptionW @ 440
|
||||
dwstExceptionDialog @ 436
|
||||
dwstExceptionDialogW @ 437
|
||||
@@ -1,11 +1,14 @@
|
||||
exes += inject
|
||||
imps += dwarfstack
|
||||
|
||||
ldflags_inject := \
|
||||
-mconsole \
|
||||
-lpsapi \
|
||||
-ldbghelp \
|
||||
|
||||
libs_inject := \
|
||||
util \
|
||||
dwarfstack \
|
||||
|
||||
src_inject := \
|
||||
main.c \
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
#include "inject/debugger.h"
|
||||
#include "inject/logger.h"
|
||||
|
||||
#include "util/debug.h"
|
||||
#include "util/log.h"
|
||||
#include "util/mem.h"
|
||||
#include "util/proc.h"
|
||||
#include "util/signal.h"
|
||||
#include "util/str.h"
|
||||
|
||||
#define MM_ALLOCATION_GRANULARITY 0x10000
|
||||
@@ -271,7 +271,7 @@ static uint32_t debugger_loop()
|
||||
"EXCEPTION_DEBUG_EVENT(pid %ld, tid %ld): x%s 0x%p",
|
||||
de.dwProcessId,
|
||||
de.dwThreadId,
|
||||
signal_exception_code_to_str(
|
||||
debug_exception_code_to_str(
|
||||
de.u.Exception.ExceptionRecord.ExceptionCode),
|
||||
de.u.Exception.ExceptionRecord.ExceptionAddress);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "inject/version.h"
|
||||
|
||||
#include "util/cmdline.h"
|
||||
#include "util/debug.h"
|
||||
#include "util/log.h"
|
||||
#include "util/mem.h"
|
||||
#include "util/os.h"
|
||||
@@ -166,6 +167,7 @@ int main(int argc, char **argv)
|
||||
|
||||
os_version_log();
|
||||
|
||||
debug_init();
|
||||
signal_exception_handler_init();
|
||||
// Cleanup remote process on CTRL+C
|
||||
signal_register_shutdown_handler(signal_shutdown_handler);
|
||||
|
||||
@@ -5,6 +5,7 @@ src_util := \
|
||||
cmdline.c \
|
||||
crc.c \
|
||||
crypto.c \
|
||||
debug.c \
|
||||
fs.c \
|
||||
hex.c \
|
||||
iobuf.c \
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
#define LOG_MODULE "util-debug"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "imports/dwarfstack.h"
|
||||
|
||||
#include "util/debug.h"
|
||||
#include "util/log.h"
|
||||
|
||||
#define EX_DESC(name) \
|
||||
case EXCEPTION_##name: \
|
||||
desc = " (" #name ")"; \
|
||||
break
|
||||
|
||||
static void _debug_stacktrace_printer(
|
||||
uint64_t addr,
|
||||
const char *filename,
|
||||
int lineno,
|
||||
const char *funcname,
|
||||
void *context,
|
||||
int columnno)
|
||||
{
|
||||
int *count;
|
||||
const char *delim;
|
||||
void *ptr;
|
||||
char buffer[512];
|
||||
char *buffer_ptr;
|
||||
|
||||
count = context;
|
||||
delim = strrchr(filename, '/');
|
||||
|
||||
if (delim) {
|
||||
filename = delim + 1;
|
||||
}
|
||||
|
||||
delim = strrchr(filename, '\\');
|
||||
|
||||
if (delim) {
|
||||
filename = delim + 1;
|
||||
}
|
||||
|
||||
ptr = (void *) (uintptr_t) addr;
|
||||
|
||||
switch (lineno) {
|
||||
case DWST_BASE_ADDR:
|
||||
log_exception_handler("base address: 0x%p (%s)", ptr, filename);
|
||||
break;
|
||||
|
||||
case DWST_NOT_FOUND:
|
||||
case DWST_NO_DBG_SYM:
|
||||
case DWST_NO_SRC_FILE:
|
||||
log_exception_handler(
|
||||
" stack %02d: 0x%p (%s)", (*count)++, ptr, filename);
|
||||
break;
|
||||
|
||||
default:
|
||||
buffer_ptr = buffer;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
if (ptr) {
|
||||
buffer_ptr += sprintf(
|
||||
buffer_ptr, " stack %02d: 0x%p", (*count)++, ptr);
|
||||
} else {
|
||||
buffer_ptr += sprintf(
|
||||
buffer_ptr,
|
||||
" %*s",
|
||||
(int) sizeof(void *) * 2,
|
||||
"");
|
||||
}
|
||||
|
||||
buffer_ptr += sprintf(buffer_ptr, " (%s:%d", filename, lineno);
|
||||
|
||||
if (columnno > 0) {
|
||||
buffer_ptr += sprintf(buffer_ptr, ":%d", columnno);
|
||||
}
|
||||
|
||||
buffer_ptr += sprintf(buffer_ptr, ")");
|
||||
|
||||
if (funcname) {
|
||||
buffer_ptr += sprintf(buffer_ptr, " [%s]", funcname);
|
||||
}
|
||||
|
||||
log_exception_handler(buffer);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static LONG WINAPI _debug_unhandled_exception_filter(LPEXCEPTION_POINTERS ep)
|
||||
{
|
||||
DWORD code;
|
||||
const char *desc;
|
||||
ULONG_PTR flag;
|
||||
ULONG_PTR addr;
|
||||
int count;
|
||||
|
||||
log_exception_handler(
|
||||
"==========================================================");
|
||||
log_exception_handler(
|
||||
"The application has crashed due to an unhandled exception!");
|
||||
|
||||
code = ep->ExceptionRecord->ExceptionCode;
|
||||
desc = debug_exception_code_to_str(code);
|
||||
|
||||
log_exception_handler("code: 0x%08lX", code);
|
||||
log_exception_handler("desc: %s", desc);
|
||||
|
||||
if (code == EXCEPTION_ACCESS_VIOLATION &&
|
||||
ep->ExceptionRecord->NumberParameters == 2) {
|
||||
flag = ep->ExceptionRecord->ExceptionInformation[0];
|
||||
addr = ep->ExceptionRecord->ExceptionInformation[1];
|
||||
|
||||
log_exception_handler(
|
||||
"%s violation at 0x%p",
|
||||
flag == 8 ? "data execution prevention" :
|
||||
(flag ? "write access" : "read access"),
|
||||
(void *) addr);
|
||||
}
|
||||
|
||||
log_exception_handler("stacktrace:");
|
||||
|
||||
count = 0;
|
||||
|
||||
dwstOfException(ep->ContextRecord, &_debug_stacktrace_printer, &count);
|
||||
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
void debug_init()
|
||||
{
|
||||
SetUnhandledExceptionFilter(_debug_unhandled_exception_filter);
|
||||
|
||||
log_info("Initialized");
|
||||
}
|
||||
|
||||
void debug_print_stacktrace()
|
||||
{
|
||||
int count;
|
||||
|
||||
count = 0;
|
||||
|
||||
log_exception_handler(
|
||||
"==========================================================");
|
||||
log_exception_handler("Debug stacktrace");
|
||||
|
||||
dwstOfLocation(&_debug_stacktrace_printer, &count);
|
||||
}
|
||||
|
||||
const char *debug_exception_code_to_str(DWORD code)
|
||||
{
|
||||
const char *desc = "";
|
||||
|
||||
switch (code) {
|
||||
EX_DESC(ACCESS_VIOLATION);
|
||||
EX_DESC(ARRAY_BOUNDS_EXCEEDED);
|
||||
EX_DESC(BREAKPOINT);
|
||||
EX_DESC(DATATYPE_MISALIGNMENT);
|
||||
EX_DESC(FLT_DENORMAL_OPERAND);
|
||||
EX_DESC(FLT_DIVIDE_BY_ZERO);
|
||||
EX_DESC(FLT_INEXACT_RESULT);
|
||||
EX_DESC(FLT_INVALID_OPERATION);
|
||||
EX_DESC(FLT_OVERFLOW);
|
||||
EX_DESC(FLT_STACK_CHECK);
|
||||
EX_DESC(FLT_UNDERFLOW);
|
||||
EX_DESC(ILLEGAL_INSTRUCTION);
|
||||
EX_DESC(IN_PAGE_ERROR);
|
||||
EX_DESC(INT_DIVIDE_BY_ZERO);
|
||||
EX_DESC(INT_OVERFLOW);
|
||||
EX_DESC(INVALID_DISPOSITION);
|
||||
EX_DESC(NONCONTINUABLE_EXCEPTION);
|
||||
EX_DESC(PRIV_INSTRUCTION);
|
||||
EX_DESC(SINGLE_STEP);
|
||||
EX_DESC(STACK_OVERFLOW);
|
||||
case DBG_CONTROL_C:
|
||||
return "DBG_CONTROL_C";
|
||||
default:
|
||||
log_warning("Unknown exception code: %lX", code);
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
return desc;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef UTIL_DEBUG_H
|
||||
#define UTIL_DEBUG_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
void debug_init();
|
||||
void debug_print_stacktrace();
|
||||
const char *debug_exception_code_to_str(DWORD code);
|
||||
|
||||
#endif
|
||||
@@ -64,6 +64,15 @@ static void log_builtin_format(
|
||||
}
|
||||
}
|
||||
|
||||
void log_exception_handler(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
log_builtin_format(LOG_LEVEL_FATAL, LOG_MODULE, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void log_assert_body(const char *file, int line, const char *function)
|
||||
{
|
||||
log_impl_fatal("assert", "%s:%d: function `%s'", file, line, function);
|
||||
|
||||
@@ -66,6 +66,7 @@ enum log_level {
|
||||
LOG_LEVEL_MISC = 3,
|
||||
};
|
||||
|
||||
void log_exception_handler(const char *fmt, ...);
|
||||
void log_assert_body(const char *file, int line, const char *function);
|
||||
void log_to_external(
|
||||
log_formatter_t misc,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <unistd.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "util/hex.h"
|
||||
#include "util/log.h"
|
||||
@@ -45,40 +44,9 @@ static BOOL WINAPI console_ctrl_handler(DWORD dwCtrlType)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static LONG WINAPI
|
||||
unhandled_exception_filter(struct _EXCEPTION_POINTERS *ExceptionInfo)
|
||||
{
|
||||
// no exception info provided
|
||||
if (ExceptionInfo != NULL) {
|
||||
struct _EXCEPTION_RECORD *ExceptionRecord =
|
||||
ExceptionInfo->ExceptionRecord;
|
||||
|
||||
log_warning(
|
||||
"Exception raised: %s",
|
||||
signal_exception_code_to_str(ExceptionRecord->ExceptionCode));
|
||||
|
||||
struct _EXCEPTION_RECORD *record_cause =
|
||||
ExceptionRecord->ExceptionRecord;
|
||||
|
||||
while (record_cause != NULL) {
|
||||
log_warning(
|
||||
"Caused by: %s",
|
||||
signal_exception_code_to_str(record_cause->ExceptionCode));
|
||||
record_cause = record_cause->ExceptionRecord;
|
||||
}
|
||||
|
||||
// TODO print stacktrace
|
||||
|
||||
log_fatal("End exception handler");
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
void signal_exception_handler_init()
|
||||
{
|
||||
SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
|
||||
SetUnhandledExceptionFilter(unhandled_exception_filter);
|
||||
|
||||
log_info("Initialized");
|
||||
}
|
||||
@@ -88,55 +56,4 @@ void signal_register_shutdown_handler(signal_shutdown_handler_t handler)
|
||||
shutdown_handler = handler;
|
||||
|
||||
log_misc("Registered shutdown handler");
|
||||
}
|
||||
|
||||
const char *signal_exception_code_to_str(DWORD code)
|
||||
{
|
||||
switch (code) {
|
||||
case EXCEPTION_ACCESS_VIOLATION:
|
||||
return "EXCEPTION_ACCESS_VIOLATION";
|
||||
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
|
||||
return "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
|
||||
case EXCEPTION_BREAKPOINT:
|
||||
return "EXCEPTION_BREAKPOINT";
|
||||
case EXCEPTION_DATATYPE_MISALIGNMENT:
|
||||
return "EXCEPTION_DATATYPE_MISALIGNMENT";
|
||||
case EXCEPTION_FLT_DENORMAL_OPERAND:
|
||||
return "EXCEPTION_FLT_DENORMAL_OPERAND";
|
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
||||
return "EXCEPTION_FLT_DIVIDE_BY_ZERO";
|
||||
case EXCEPTION_FLT_INEXACT_RESULT:
|
||||
return "EXCEPTION_FLT_INEXACT_RESULT";
|
||||
case EXCEPTION_FLT_INVALID_OPERATION:
|
||||
return "EXCEPTION_FLT_INVALID_OPERATION";
|
||||
case EXCEPTION_FLT_OVERFLOW:
|
||||
return "EXCEPTION_FLT_OVERFLOW";
|
||||
case EXCEPTION_FLT_STACK_CHECK:
|
||||
return "EXCEPTION_FLT_STACK_CHECK";
|
||||
case EXCEPTION_FLT_UNDERFLOW:
|
||||
return "EXCEPTION_FLT_UNDERFLOW";
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||
return "EXCEPTION_ILLEGAL_INSTRUCTION";
|
||||
case EXCEPTION_IN_PAGE_ERROR:
|
||||
return "EXCEPTION_IN_PAGE_ERROR";
|
||||
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
||||
return "EXCEPTION_INT_DIVIDE_BY_ZERO";
|
||||
case EXCEPTION_INT_OVERFLOW:
|
||||
return "EXCEPTION_INT_OVERFLOW";
|
||||
case EXCEPTION_INVALID_DISPOSITION:
|
||||
return "EXCEPTION_INVALID_DISPOSITION";
|
||||
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
|
||||
return "EXCEPTION_NONCONTINUABLE_EXCEPTION";
|
||||
case EXCEPTION_PRIV_INSTRUCTION:
|
||||
return "EXCEPTION_PRIV_INSTRUCTION";
|
||||
case EXCEPTION_SINGLE_STEP:
|
||||
return "EXCEPTION_SINGLE_STEP";
|
||||
case EXCEPTION_STACK_OVERFLOW:
|
||||
return "EXCEPTION_STACK_OVERFLOW";
|
||||
case DBG_CONTROL_C:
|
||||
return "DBG_CONTROL_C";
|
||||
default:
|
||||
log_warning("Unknown exception code: %lX", code);
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user