fix crashlog to actually build (doesnt work on macos yet)

This commit is contained in:
altalk23 2023-06-08 19:22:51 +03:00
parent 9c3759b398
commit fd3fd9536e
4 changed files with 45 additions and 32 deletions
loader/src

View file

@ -35,7 +35,7 @@ static void printMods(std::stringstream& stream) {
}
}
void crashlog::writeCrashlog(geode::Mod* faultyMod, std::string const& info, std::string const& stacktrace, std::string const& registers) {
std::string crashlog::writeCrashlog(geode::Mod* faultyMod, std::string const& info, std::string const& stacktrace, std::string const& registers) {
// make sure crashlog directory exists
(void)utils::file::createDirectoryAll(crashlog::getCrashLogDirectory());
@ -75,11 +75,6 @@ void crashlog::writeCrashlog(geode::Mod* faultyMod, std::string const& info, std
file << "\n== Installed Mods ==\n";
printMods(file);
// show message box on debug mode
#ifdef GEODE_DEBUG
MessageBoxA(nullptr, file.str().c_str(), "Geode Crashed", MB_ICONERROR);
#endif
// save actual file
std::ofstream actualFile;
actualFile.open(
@ -87,4 +82,6 @@ void crashlog::writeCrashlog(geode::Mod* faultyMod, std::string const& info, std
);
actualFile << file.rdbuf() << std::flush;
actualFile.close();
return file.str();
}

View file

@ -25,5 +25,5 @@ namespace crashlog {
*/
ghc::filesystem::path GEODE_DLL getCrashLogDirectory();
void GEODE_DLL writeCrashlog(geode::Mod* faultyMod, std::string const& info, std::string const& stacktrace, std::string const& registers);
std::string GEODE_DLL writeCrashlog(geode::Mod* faultyMod, std::string const& info, std::string const& stacktrace, std::string const& registers);
}

View file

@ -4,7 +4,7 @@
#include <array>
#include <ghc/fs_fwd.hpp>
#include <execinfo.h>
#import <Foundation/Foundation.h>
// https://gist.github.com/jvranish/4441299
@ -48,58 +48,70 @@ static std::string getInfo(int sig, siginfo_t* siginfo, ucontext_t* context, Mod
void* address = reinterpret_cast<void*>(context->uc_mcontext->__ss.__rip);
stream // << "Faulty Lib: " << getModuleName(handleFromAddress(address), true) << "\n"
<< "Faulty Mod: " << (faultyMod ? faultyMod->getID() : "<Unknown>") << "\n"
<< "Signal Code: " << std::hex << sig << " (" << getSignalCodeString(sig, siginfo) << ")" << std::dec << "\n"
<< "Signal Code: " << std::hex << sig << " (" << getSignalCodeString(sig, siginfo) << ")" << std::dec << "\n";
return stream.str();
}
extern "C" void signalHandler(int signal, siginfo_t* signal_info, void* vcontext) {
auto context = reinterpret_cast<ucontext_t*>(vcontext);
auto array = std::array<void*, 20>();
auto size = backtrace(array.data(), 20);
static constexpr size_t frameSize = 64;
#ifdef __APPLE__
auto array = std::array<void*, frameSize>();
auto size = backtrace(array.data(), frameSize);
// for some reason this is needed, dont ask me why
array[2] = reinterpret_cast<void*>(context->uc_mcontext->__ss.__rip);
#else
array[1] = reinterpret_cast<void*>(context->uc_mcontext.gregs[REG_RIP]);
#endif
if (size < 20) {
if (size < frameSize) {
array[size] = nullptr;
}
auto messages = backtrace_symbols(array.data(), size);
if (size < 20) {
if (size < frameSize) {
messages[size] = nullptr;
}
ServerLoop::get()->m_panicBacktrace.store(messages);
ServerLoop::get()->m_signalExit.notify();
ServerLoop::get()->m_signalFinish.wait();
free(messages);
std::abort();
}
static bool s_lastLaunchCrashed;
bool crashlog::setupPlatformHandler() {
struct sigaction action;
action.sa_sigaction = signalHandler;
action.sa_flags = SA_SIGINFO;
sigemptyset(&action.sa_mask);
sigaction(SIGSEGV, &action, nullptr);
// I'd rather not track interrupt lol
// sigaction(SIGINT, &action, nullptr);
sigaction(SIGFPE, &action, nullptr);
sigaction(SIGILL, &action, nullptr);
sigaction(SIGTERM, &action, nullptr);
sigaction(SIGABRT, &action, nullptr);
auto lastCrashedFile = crashlog::getCrashLogDirectory() / "last-crashed";
if (ghc::filesystem::exists(lastCrashedFile)) {
s_lastLaunchCrashed = true;
try {
ghc::filesystem::remove(lastCrashedFile);
}
catch (...) {
}
}
return true;
}
bool crashlog::didLastLaunchCrash() {
return false;
return s_lastLaunchCrashed;
}
ghc::filesystem::path crashlog::getCrashLogDirectory() {
std::array<char, 1024> path;
CFStringGetCString(
(CFStringRef)NSHomeDirectory(), path.data(), path.size(), kCFStringEncodingUTF8
);
auto crashlogDir =
ghc::filesystem::path(path.data()) / "Library" / "Logs" / "DiagnosticReports";
return crashlogDir.string();
return dirs::getGeodeDir() / "crashlogs";
}
#endif

View file

@ -215,8 +215,12 @@ static LONG WINAPI exceptionHandler(LPEXCEPTION_POINTERS info) {
auto faultyMod = modFromAddress(info->ExceptionRecord->ExceptionAddress);
crashlog::writeCrashlog(faultyMod, getInfo(info, faultyMod), getStacktrace(info->ContextRecord), getRegisters(info->ContextRecord));
auto text = crashlog::writeCrashlog(faultyMod, getInfo(info, faultyMod), getStacktrace(info->ContextRecord), getRegisters(info->ContextRecord));
// show message box on debug mode
#ifdef GEODE_DEBUG
MessageBoxA(nullptr, text.c_str(), "Geode Crashed", MB_ICONERROR);
#endif
return EXCEPTION_CONTINUE_SEARCH;
}