mirror of
https://github.com/geode-sdk/geode.git
synced 2025-04-10 03:55:43 -04:00
Make terminate cause a crash instead for the crashlog and stacktrace
This commit is contained in:
parent
69bcab649e
commit
33e12646b8
2 changed files with 38 additions and 9 deletions
loader
|
@ -9,6 +9,22 @@ namespace geode {
|
|||
}
|
||||
|
||||
namespace geode::utils {
|
||||
#ifdef GEODE_IS_WINDOWS
|
||||
static constexpr size_t GEODE_TERMINATE_EXCEPTION_CODE = 0x4000;
|
||||
static constexpr size_t GEODE_UNREACHABLE_EXCEPTION_CODE = 0x4001;
|
||||
|
||||
static constexpr bool isGeodeExceptionCode(size_t code) {
|
||||
return GEODE_TERMINATE_EXCEPTION_CODE <= code && code <= GEODE_UNREACHABLE_EXCEPTION_CODE;
|
||||
}
|
||||
#else
|
||||
static constexpr size_t GEODE_TERMINATE_EXCEPTION_CODE = 0;
|
||||
static constexpr size_t GEODE_UNREACHABLE_EXCEPTION_CODE = 0;
|
||||
|
||||
static constexpr bool isGeodeExceptionCode(size_t code) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
// This needs to do stuff with `Mod*` which is not included in the file
|
||||
GEODE_DLL std::string fmtTerminateError(const char* reason, Mod* mod, std::source_location loc);
|
||||
|
@ -19,12 +35,11 @@ namespace geode::utils {
|
|||
void terminate(
|
||||
std::string const& reason,
|
||||
Mod* mod = getMod(),
|
||||
std::source_location loc = std::source_location::current()
|
||||
std::source_location loc = std::source_location::current(),
|
||||
size_t platformCode = GEODE_TERMINATE_EXCEPTION_CODE
|
||||
) {
|
||||
auto fullError = detail::fmtTerminateError(reason.c_str(), mod, loc);
|
||||
|
||||
// Add the error to the logfile
|
||||
log::error("{}", fullError);
|
||||
log::error("{}", detail::fmtTerminateError(reason.c_str(), mod, loc));
|
||||
|
||||
#ifdef GEODE_IS_WINDOWS
|
||||
// If a debugger is attached, start debugging
|
||||
|
@ -32,10 +47,14 @@ namespace geode::utils {
|
|||
OutputDebugStringA(reason.c_str());
|
||||
DebugBreak();
|
||||
}
|
||||
// Otherwise just terminate
|
||||
// Otherwise terminate by raising an exception (which is caught by the crashlog handler)
|
||||
else {
|
||||
MessageBoxA(nullptr, "A Mod Crashed", fullError.c_str(), MB_ICONERROR);
|
||||
std::terminate();
|
||||
std::array<const void*, 2> errorList { static_cast<const void*>(reason.c_str()), mod };
|
||||
RaiseException(
|
||||
platformCode,
|
||||
EXCEPTION_NONCONTINUABLE,
|
||||
2, reinterpret_cast<ULONG_PTR*>(errorList.data())
|
||||
);
|
||||
}
|
||||
#else
|
||||
std::terminate();
|
||||
|
@ -49,6 +68,6 @@ namespace geode::utils {
|
|||
Mod* mod = getMod(),
|
||||
std::source_location loc = std::source_location::current()
|
||||
) {
|
||||
return terminate(reason + " (Unreachable code path)", mod, loc);
|
||||
terminate(reason, mod, loc, GEODE_UNREACHABLE_EXCEPTION_CODE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <DbgHelp.h>
|
||||
#include <Geode/utils/casts.hpp>
|
||||
#include <Geode/utils/file.hpp>
|
||||
#include <Geode/utils/terminate.hpp>
|
||||
#include <Windows.h>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
|
@ -66,6 +67,8 @@ static char const* getExceptionCodeString(DWORD code) {
|
|||
EXP_STR(EXCEPTION_FLT_INVALID_OPERATION);
|
||||
EXP_STR(EXCEPTION_FLT_OVERFLOW);
|
||||
EXP_STR(EXCEPTION_INT_DIVIDE_BY_ZERO);
|
||||
EXP_STR(GEODE_TERMINATE_EXCEPTION_CODE);
|
||||
EXP_STR(GEODE_UNREACHABLE_EXCEPTION_CODE);
|
||||
default: return "<Unknown>";
|
||||
}
|
||||
#undef EXP_STR
|
||||
|
@ -267,7 +270,14 @@ static std::string getInfo(LPEXCEPTION_POINTERS info, Mod* faultyMod) {
|
|||
}
|
||||
|
||||
stream << "Faulty Mod: " << (faultyMod ? faultyMod->getID() : "<Unknown>") << "\n";
|
||||
} else {
|
||||
}
|
||||
else if (isGeodeExceptionCode(info->ExceptionRecord->ExceptionCode)) {
|
||||
stream
|
||||
<< "A mod has deliberately asked the game to crash.\n"
|
||||
<< "Reason: " << reinterpret_cast<const char*>(info->ExceptionRecord->ExceptionInformation[0]) << "\n"
|
||||
<< "Faulty Mod: " << reinterpret_cast<Mod*>(info->ExceptionRecord->ExceptionInformation[1])->getID() << "\n";
|
||||
}
|
||||
else {
|
||||
stream << "Faulty Module: "
|
||||
<< getModuleName(handleFromAddress(info->ExceptionRecord->ExceptionAddress), true)
|
||||
<< "\n"
|
||||
|
|
Loading…
Add table
Reference in a new issue