summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--libultraship/libultraship/CMakeLists.txt7
-rw-r--r--libultraship/libultraship/CrashHandler.cpp172
-rw-r--r--libultraship/libultraship/CrashHandler.h18
-rw-r--r--soh/include/functions.h2
-rw-r--r--soh/include/segment_symbols.h12
-rw-r--r--soh/soh/OTRGlobals.h2
-rw-r--r--soh/src/code/fault.c2
-rw-r--r--soh/src/code/main.c12
9 files changed, 218 insertions, 11 deletions
diff --git a/.gitignore b/.gitignore
index 1df76208d..98fe2b637 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@ __pycache__/
.idea/
cmake-build-debug
venv/
+.cache/
# Project-specific ignores
build/
@@ -410,6 +411,7 @@ oot.otr
*.sav
shipofharkinian.ini
shipofharkinian.json
+imgui.ini
# Switch Stuff
diff --git a/libultraship/libultraship/CMakeLists.txt b/libultraship/libultraship/CMakeLists.txt
index b59993660..aec229bfb 100644
--- a/libultraship/libultraship/CMakeLists.txt
+++ b/libultraship/libultraship/CMakeLists.txt
@@ -334,6 +334,12 @@ set(Source_Files__Resources__mpq
)
source_group("Source Files\\Resources\\mpq" FILES ${Source_Files__Resources__mpq})
+set(Source_Files__Crash_Handler
+ "CrashHandler.cpp"
+ "CrashHandler.h"
+)
+source_group("Source Files\\Crash Handler" FILES ${Source_Files__Crash_Handler})
+
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(Source_Files__Darwin
"OSXFolderManager.mm"
@@ -388,6 +394,7 @@ set(ALL_FILES
${Source_Files__Resources__Factories}
${Source_Files__Resources__Files}
${Source_Files__Resources__mpq}
+ ${Source_Files__Crash_Handler}
${Source_Files__Darwin}
${Source_Files__NintendoSwitch}
${Source_Files__CafeOS}
diff --git a/libultraship/libultraship/CrashHandler.cpp b/libultraship/libultraship/CrashHandler.cpp
new file mode 100644
index 000000000..f8d66beab
--- /dev/null
+++ b/libultraship/libultraship/CrashHandler.cpp
@@ -0,0 +1,172 @@
+#include "spdlog/spdlog.h"
+#include "Utils/StringHelper.h"
+#include "CrashHandler.h"
+
+#if defined(__linux__)
+#include <csignal>
+#include <cstdio>
+#include <cxxabi.h> // for __cxa_demangle
+#include <dlfcn.h> // for dladdr
+#include <execinfo.h>
+#include <unistd.h>
+
+extern "C" void DeinitOTR(void);
+
+
+static void PrintRegisters(ucontext_t* ctx) {
+ char regbuffer[1024];
+ SPDLOG_CRITICAL("Registers:");
+#if defined(__x86_64__)
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RAX]);
+ SPDLOG_CRITICAL("RAX: {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RDI]);
+ SPDLOG_CRITICAL("RDI: {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RSI]);
+ SPDLOG_CRITICAL("RSI: {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RDX]);
+ SPDLOG_CRITICAL("RDX: {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RCX]);
+ SPDLOG_CRITICAL("RCX: {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R8]);
+ SPDLOG_CRITICAL("R8 : {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R9]);
+ SPDLOG_CRITICAL("R9 : {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R10]);
+ SPDLOG_CRITICAL("R10: {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R11]);
+ SPDLOG_CRITICAL("R11: {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RSP]);
+ SPDLOG_CRITICAL("RSP: {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RBX]);
+ SPDLOG_CRITICAL("RBX: {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RBP]);
+ SPDLOG_CRITICAL("RBP: {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R12]);
+ SPDLOG_CRITICAL("R12: {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R13]);
+ SPDLOG_CRITICAL("R13: {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R14]);
+ SPDLOG_CRITICAL("R14: {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R15]);
+ SPDLOG_CRITICAL("R15: {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RIP]);
+ SPDLOG_CRITICAL("RIP: {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_EFL]);
+ SPDLOG_CRITICAL("EFLAGS: {} ", regbuffer);
+#else
+ snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EDI]);
+ SPDLOG_CRITICAL("EDI : {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_ESI]);
+ SPDLOG_CRITICAL("ESI : {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EBP]);
+ SPDLOG_CRITICAL("EBP : {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_ESP]);
+ SPDLOG_CRITICAL("ESP : {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EBX]);
+ SPDLOG_CRITICAL("EBX : {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EDX]);
+ SPDLOG_CRITICAL("EDX : {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_ECX]);
+ SPDLOG_CRITICAL("ECX : {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EAX]);
+ SPDLOG_CRITICAL("EAX : {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EIP]);
+ SPDLOG_CRITICAL("EIP : {} ", regbuffer);
+ snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EFL]);
+ SPDLOG_CRITICAL("EFL : {} ", regbuffer);
+#endif
+}
+
+static void ErrorHandler(int sig, siginfo_t* sigInfo, void* data)
+{
+ std::array<void*, 4096> arr;
+ ucontext_t* ctx = static_cast<ucontext_t*>(data);
+ constexpr size_t nMaxFrames = arr.size();
+ size_t size = backtrace(arr.data(), nMaxFrames);
+ char** symbols = backtrace_symbols(arr.data(), nMaxFrames);
+
+ SPDLOG_CRITICAL("(Signal: {})\n", sig);
+
+ switch (sig) {
+ case SIGILL:
+ SPDLOG_CRITICAL("ILLEGAL INSTRUCTION");
+ break;
+ case SIGABRT:
+ SPDLOG_CRITICAL("ABORT");
+ break;
+ case SIGFPE:
+ SPDLOG_CRITICAL("ERRONEUS ARITHEMETIC OPERATION");
+ break;
+ case SIGSEGV:
+ SPDLOG_CRITICAL("INVALID ACCESS TO STORAGE");
+ break;
+ }
+
+ PrintRegisters(ctx);
+
+ SPDLOG_CRITICAL("Traceback:\n");
+ for (size_t i = 1; i < size; i++)
+ {
+ Dl_info info;
+ int gotAddress = dladdr(arr[i], &info);
+ std::string functionName(symbols[i]);
+
+ if (gotAddress != 0 && info.dli_sname != nullptr)
+ {
+ FILE* pipe;
+ int32_t status;
+ char* demangled = abi::__cxa_demangle(info.dli_sname, nullptr, nullptr, &status);
+ const char* nameFound = info.dli_sname;
+
+ if (status == 0)
+ {
+ nameFound = demangled;
+ }
+ #if 0
+ char command[256];
+ char addrLine[128];
+ snprintf(command, sizeof(command), "addr2line -e soh.elf %s + 0x%lX", nameFound, (uintptr_t)arr[i] - (uintptr_t)info.dli_saddr);
+ pipe = popen(command, "r");
+ fgets(addrLine, 128, pipe);
+ #endif
+
+ functionName = StringHelper::Sprintf("%s (+0x%X)", nameFound,
+ (char*)arr[i] - (char*)info.dli_saddr);
+ free(demangled);
+ }
+
+ SPDLOG_CRITICAL("{} {}", i, functionName.c_str());
+ }
+
+ free(symbols);
+ DeinitOTR();
+ exit(1);
+}
+
+static void ShutdownHandler(int sig, siginfo_t* sigInfo, void* data) {
+ DeinitOTR();
+ exit(1);
+}
+
+extern "C" void SetupHandlerLinux() {
+ struct sigaction action;
+ struct sigaction shutdownAction;
+
+ action.sa_flags = SA_SIGINFO;
+ action.sa_sigaction = ErrorHandler;
+
+ sigaction(SIGILL, &action, nullptr);
+ sigaction(SIGABRT, &action, nullptr);
+ sigaction(SIGFPE, &action, nullptr);
+ sigaction(SIGSEGV, &action, nullptr);
+
+ shutdownAction.sa_flags = SA_SIGINFO;
+ shutdownAction.sa_sigaction = ShutdownHandler;
+ sigaction(SIGINT, &shutdownAction, nullptr);
+ sigaction(SIGTERM, &shutdownAction, nullptr);
+ sigaction(SIGQUIT, &shutdownAction, nullptr);
+ sigaction(SIGKILL, &shutdownAction, nullptr);
+
+
+}
+#endif
diff --git a/libultraship/libultraship/CrashHandler.h b/libultraship/libultraship/CrashHandler.h
new file mode 100644
index 000000000..e068a4e38
--- /dev/null
+++ b/libultraship/libultraship/CrashHandler.h
@@ -0,0 +1,18 @@
+#ifndef CRASH_HANDLER_H
+#define CRASH_HANDLER_H
+
+#ifdef __linux__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void SetupHandlerLinux(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __linux__
+
+#endif // CRASH_HANDLER_H \ No newline at end of file
diff --git a/soh/include/functions.h b/soh/include/functions.h
index a336cb1ef..6339cff64 100644
--- a/soh/include/functions.h
+++ b/soh/include/functions.h
@@ -1656,7 +1656,7 @@ void PadMgr_HandleRetraceMsg(PadMgr* padmgr);
void PadMgr_HandlePreNMI(PadMgr* padmgr);
// This function must remain commented out, because it is called incorrectly in
// fault.c (actual bug in game), and the compiler notices and won't compile it
-// void PadMgr_RequestPadData(PadMgr* padmgr, Input* inputs, s32 mode);
+void PadMgr_RequestPadData(PadMgr* padmgr, Input* inputs, s32 mode);
void PadMgr_Init(PadMgr* padmgr, OSMesgQueue* siIntMsgQ, IrqMgr* irqMgr, OSId id, OSPri priority, void* stack);
void Sched_SwapFrameBuffer(CfbInfo* cfbInfo);
void func_800C84E4(SchedContext* sc, CfbInfo* cfbInfo);
diff --git a/soh/include/segment_symbols.h b/soh/include/segment_symbols.h
index 81fe34801..3b50b4eaa 100644
--- a/soh/include/segment_symbols.h
+++ b/soh/include/segment_symbols.h
@@ -3,20 +3,20 @@
#include "z64.h"
-#define DECLARE_SEGMENT(name) \
- //extern u8 _##name##SegmentStart[]; \
+#define DECLARE_SEGMENT(name)
+ //extern u8 _##name##SegmentStart[];
//extern u8 _##name##SegmentEnd[];
-#define DECLARE_ROM_SEGMENT(name) \
- //extern u8 _##name##SegmentRomStart[]; \
+#define DECLARE_ROM_SEGMENT(name)
+ //extern u8 _##name##SegmentRomStart[];
//extern u8 _##name##SegmentRomEnd[];
#define DECLARE_BSS_SEGMENT(name) \
extern u8 _##name##SegmentBssStart[]; \
extern u8 _##name##SegmentBssEnd[];
-#define DECLARE_OVERLAY_SEGMENT(name) \
- //DECLARE_SEGMENT(ovl_##name) \
+#define DECLARE_OVERLAY_SEGMENT(name)
+ //DECLARE_SEGMENT(ovl_##name)
//DECLARE_ROM_SEGMENT(ovl_##name)
DECLARE_SEGMENT(boot)
diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h
index dc304358d..089394e33 100644
--- a/soh/soh/OTRGlobals.h
+++ b/soh/soh/OTRGlobals.h
@@ -32,6 +32,8 @@ private:
#endif
#ifndef __cplusplus
+void InitOTR(void);
+void DeinitOTR(void);
void VanillaItemTable_Init();
void OTRAudio_Init();
void InitAudio();
diff --git a/soh/src/code/fault.c b/soh/src/code/fault.c
index c55a63a00..f7414766a 100644
--- a/soh/src/code/fault.c
+++ b/soh/src/code/fault.c
@@ -293,7 +293,7 @@ void Fault_Sleep(u32 duration) {
void Fault_PadCallback(Input* input) {
//! @bug This function is not called correctly and thus will crash from reading a bad pointer at 0x800C7E4C
- PadMgr_RequestPadData(input, 0);
+ PadMgr_RequestPadData(&gPadMgr, input, 0);
}
void Fault_UpdatePadImpl()
diff --git a/soh/src/code/main.c b/soh/src/code/main.c
index ccfdc2019..8e9fe1776 100644
--- a/soh/src/code/main.c
+++ b/soh/src/code/main.c
@@ -3,6 +3,8 @@
#include <soh/Enhancements/bootcommands.h>
#include "soh/OTRGlobals.h"
+#include "../libultraship/CrashHandler.h"
+
s32 gScreenWidth = SCREEN_WIDTH;
s32 gScreenHeight = SCREEN_HEIGHT;
@@ -38,6 +40,10 @@ void Main_LogSystemHeap(void) {
int main(int argc, char** argv)
{
+#ifdef __linux__
+ SetupHandlerLinux();
+#endif
+
GameConsole_Init();
InitOTR();
BootCommands_Init();
@@ -64,14 +70,14 @@ void Main(void* arg) {
Fault_Init();
SysCfb_Init(0);
Heaps_Alloc();
- sysHeap = gSystemHeap;
+ sysHeap = (uintptr_t)gSystemHeap;
fb = SysCfb_GetFbPtr(0);
gSystemHeapSize = 1024 * 1024 * 4;
// "System heap initalization"
osSyncPrintf("システムヒープ初期化 %08x-%08x %08x\n", sysHeap, fb, gSystemHeapSize);
- SystemHeap_Init(sysHeap, gSystemHeapSize); // initializes the system heap
+ SystemHeap_Init((void*)sysHeap, gSystemHeapSize); // initializes the system heap
if (osMemSize >= 0x800000) {
- debugHeap = SysCfb_GetFbEnd();
+ debugHeap = (void*)SysCfb_GetFbEnd();
debugHeapSize = (0x80600000 - (uintptr_t)debugHeap);
} else {
debugHeapSize = 0x400;