diff options
| author | Louis <35883445+louist103@users.noreply.github.com> | 2022-07-13 21:42:53 -0400 |
|---|---|---|
| committer | Nicholas Estelami <NEstelami@users.noreply.github.com> | 2022-07-30 22:18:11 -0400 |
| commit | 497bf79892c9ad6166f247be0f14ced632523b79 (patch) | |
| tree | 9805c1b9a1f394a6df6a1a02e020b9e2ab7adefe | |
| parent | f54f2fa96bfc476a15fcc3ebcd6124bc19164fcd (diff) | |
it works
| -rw-r--r-- | ExporterTest/ExporterTest.vcxproj | 4 | ||||
| -rw-r--r-- | ZAPD/CrashHandler.cpp | 146 | ||||
| -rw-r--r-- | ZAPD/CrashHandler.h | 21 | ||||
| -rw-r--r-- | ZAPD/Main.cpp | 91 | ||||
| -rw-r--r-- | ZAPD/ZAPD.vcxproj | 8 | ||||
| -rw-r--r-- | ZAPD/ZAPD.vcxproj.filters | 6 | ||||
| -rw-r--r-- | ZAPDUtils/ZAPDUtils.vcxproj | 4 |
7 files changed, 205 insertions, 75 deletions
diff --git a/ExporterTest/ExporterTest.vcxproj b/ExporterTest/ExporterTest.vcxproj index 5bdfc7a..341f72c 100644 --- a/ExporterTest/ExporterTest.vcxproj +++ b/ExporterTest/ExporterTest.vcxproj @@ -30,7 +30,7 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v143</PlatformToolset>
+ <PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -43,7 +43,7 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v143</PlatformToolset>
+ <PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
diff --git a/ZAPD/CrashHandler.cpp b/ZAPD/CrashHandler.cpp new file mode 100644 index 0000000..d73d0b9 --- /dev/null +++ b/ZAPD/CrashHandler.cpp @@ -0,0 +1,146 @@ +#include "CrashHandler.h" +#include "Utils/StringHelper.h" + +#if defined(__linux__) +void ErrorHandler(int sig) +{ + std::array<void*, 4096> arr; + constexpr size_t nMaxFrames = arr.size(); + size_t size = backtrace(arr.data(), nMaxFrames); + char** symbols = backtrace_symbols(arr.data(), nMaxFrames); + + fprintf(stderr, "\nZAPD crashed. (Signal: %i)\n", sig); + + // Feel free to add more crash messages. + std::array<const char*, 3> crashEasterEgg = { + "\tYou've met with a terrible fate, haven't you?", + "\tSEA BEARS FOAM. SLEEP BEARS DREAMS. \n\tBOTH END IN THE SAME WAY: CRASSSH!", + "\tZAPD has fallen and cannot get up.", + }; + + srand(time(nullptr)); + auto easterIndex = rand() % crashEasterEgg.size(); + + fprintf(stderr, "\n%s\n\n", crashEasterEgg[easterIndex]); + + fprintf(stderr, "Traceback:\n"); + for (size_t i = 1; i < size; i++) + { + Dl_info info; + uint32_t gotAddress = dladdr(arr[i], &info); + std::string functionName(symbols[i]); + + if (gotAddress != 0 && info.dli_sname != nullptr) + { + 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; + } + + functionName = StringHelper::Sprintf("%s (+0x%X)", nameFound, + (char*)arr[i] - (char*)info.dli_saddr); + free(demangled); + } + + fprintf(stderr, "%-3zd %s\n", i, functionName.c_str()); + } + + fprintf(stderr, "\n"); + + free(symbols); + exit(1); +} +#elif defined(_MSC_VER) + +void printStack(CONTEXT* ctx) +{ + BOOL result; + HANDLE process; + HANDLE thread; + HMODULE hModule; + ULONG frame; + DWORD64 displacement; + DWORD disp; + +#if defined(_M_AMD64) + STACKFRAME64 stack; + memset(&stack, 0, sizeof(STACKFRAME64)); +#else + STACKFRAME stack; + memset(&stack, 0, sizeof(STACKFRAME)); +#endif + + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME + sizeof(TCHAR)]; + char module[512]; + + PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; + + CONTEXT ctx2; + memcpy(&ctx2, ctx, sizeof(CONTEXT)); + + process = GetCurrentProcess(); + thread = GetCurrentThread(); + SymInitialize(process, nullptr, TRUE); + + constexpr DWORD machineType = +#if defined(_M_AMD64) + IMAGE_FILE_MACHINE_AMD64; +#else + IMAGE_FILE_MACHINE_I386; +#endif + + displacement = 0; + + for (frame = 0;; frame++) + { + result = StackWalk(machineType, process, thread, &stack, &ctx2, nullptr, + SymFunctionTableAccess, SymGetModuleBase, nullptr); + if (!result) + { + break; + } + symbol->SizeOfStruct = sizeof(SYMBOL_INFO); + symbol->MaxNameLen = MAX_SYM_NAME; + SymFromAddr(process, (ULONG64)stack.AddrPC.Offset, &displacement, symbol); +#if defined(_M_AMD64) + IMAGEHLP_LINE64 line; + line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); +#else + IMAGEHLP_LINE line; + line.SizeOfStruct = sizeof(IMAGEHLP_LINE); +#endif + if (SymGetLineFromAddr(process, stack.AddrPC.Offset, &disp, &line)) + { + fprintf(stderr, "%u\t %s in %s: line: %lu: \n", frame, symbol->Name, line.FileName, + line.LineNumber); + } + + else + { + fprintf(stderr, "%u\tat % s\n", frame, symbol->Name); + hModule = nullptr; + GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCTSTR)(stack.AddrPC.Offset), &hModule); + + if (hModule != nullptr) + { + GetModuleFileNameA(hModule, module, 512 - 1); + } + fprintf(stderr, "%u\tIn %s\n", frame, module); + } + } +} + +LONG seh_filter(_EXCEPTION_POINTERS* ex) +{ + fprintf(stderr, "EXCEPTION 0x%x occured\n", ex->ExceptionRecord->ExceptionCode); + printStack(ex->ContextRecord); + return EXCEPTION_EXECUTE_HANDLER; +} + +#endif diff --git a/ZAPD/CrashHandler.h b/ZAPD/CrashHandler.h new file mode 100644 index 0000000..9bb3f5b --- /dev/null +++ b/ZAPD/CrashHandler.h @@ -0,0 +1,21 @@ +#include <array> +#include <csignal> +#include <cstdio> +#include <cstdlib> +#include <ctime> + +#if defined(__linux__) +#include <cxxabi.h> // for __cxa_demangle +#include <dlfcn.h> // for dladdr +#include <execinfo.h> +#include <unistd.h> +void ErrorHandler(int sig); +#elif defined(_MSC_VER) +#include <Windows.h> +#include <DbgHelp.h> + +#include <inttypes.h> +LONG seh_filter(_EXCEPTION_POINTERS* ex); + +#pragma comment(lib, "Dbghelp.lib") +#endif diff --git a/ZAPD/Main.cpp b/ZAPD/Main.cpp index 531edc0..321ba01 100644 --- a/ZAPD/Main.cpp +++ b/ZAPD/Main.cpp @@ -10,22 +10,12 @@ #include "ZFile.h" #include "ZTexture.h" -#if !defined(_MSC_VER) && !defined(__CYGWIN__) -#include <csignal> -#include <cstdlib> -#include <ctime> -#include <cxxabi.h> // for __cxa_demangle -#include <dlfcn.h> // for dladdr -#include <execinfo.h> -#include <unistd.h> -#endif +#include "CrashHandler.h" #include <string> #include <string_view> #include "tinyxml2.h" -extern const char gBuildHash[]; - bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath, ZFileMode fileMode); @@ -33,63 +23,9 @@ void BuildAssetTexture(const fs::path& pngFilePath, TextureType texType, const f void BuildAssetBackground(const fs::path& imageFilePath, const fs::path& outPath); void BuildAssetBlob(const fs::path& blobFilePath, const fs::path& outPath); -#if !defined(_MSC_VER) && !defined(__CYGWIN__) -#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0])) -void ErrorHandler(int sig) -{ - void* array[4096]; - const size_t nMaxFrames = sizeof(array) / sizeof(array[0]); - size_t size = backtrace(array, nMaxFrames); - char** symbols = backtrace_symbols(array, nMaxFrames); - - fprintf(stderr, "\nZAPD crashed. (Signal: %i)\n", sig); - - // Feel free to add more crash messages. - const char* crashEasterEgg[] = { - "\tYou've met with a terrible fate, haven't you?", - "\tSEA BEARS FOAM. SLEEP BEARS DREAMS. \n\tBOTH END IN THE SAME WAY: CRASSSH!", - "\tZAPD has fallen and cannot get up.", - }; - - srand(time(nullptr)); - auto easterIndex = rand() % ARRAY_COUNT(crashEasterEgg); - - fprintf(stderr, "\n%s\n\n", crashEasterEgg[easterIndex]); - - fprintf(stderr, "Traceback:\n"); - for (size_t i = 1; i < size; i++) - { - Dl_info info; - uint32_t gotAddress = dladdr(array[i], &info); - std::string functionName(symbols[i]); - - if (gotAddress != 0 && info.dli_sname != nullptr) - { - 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; - } - - functionName = StringHelper::Sprintf("%s (+0x%X)", nameFound, - (char*)array[i] - (char*)info.dli_saddr); - free(demangled); - } - - fprintf(stderr, "%-3zd %s\n", i, functionName.c_str()); - } - - fprintf(stderr, "\n"); - - free(symbols); - exit(1); -} -#endif +extern const char gBuildHash[]; -int main(int argc, char* argv[]) +int Main(int argc, char* argv[]) { // Syntax: ZAPD.out [mode (btex/bovl/e)] (Arbritrary Number of Arguments) @@ -187,10 +123,10 @@ int main(int argc, char* argv[]) } else if (arg == "-eh") // Enable Error Handler { -#if !defined(_MSC_VER) && !defined(__CYGWIN__) +#if defined(__linux__) signal(SIGSEGV, ErrorHandler); signal(SIGABRT, ErrorHandler); -#else +#elif !defined(_MSC_VER) HANDLE_WARNING(WarningType::Always, "tried to set error handler, but this ZAPD build lacks support for one", ""); @@ -329,6 +265,23 @@ int main(int argc, char* argv[]) return 0; } +// Windows doesn't make it easy to get a stack trace from just a signal. So we need to do this messy +// stuf for just windows. +int main(int argc, char* argv[]) +{ +#ifdef _MSC_VER + __try + { + return Main(argc, argv); + } + __except (seh_filter(GetExceptionInformation())) + { + } +#else + return Main(argc, argv); +#endif +} + bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath, ZFileMode fileMode) { diff --git a/ZAPD/ZAPD.vcxproj b/ZAPD/ZAPD.vcxproj index 26362c4..645cb51 100644 --- a/ZAPD/ZAPD.vcxproj +++ b/ZAPD/ZAPD.vcxproj @@ -30,7 +30,7 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v143</PlatformToolset>
+ <PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -43,7 +43,7 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v143</PlatformToolset>
+ <PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
@@ -95,6 +95,7 @@ </ClCompile>
<Link>
<Profile>true</Profile>
+ <SubSystem>Console</SubSystem>
</Link>
<PreBuildEvent>
<Command>cd .. @@ -119,6 +120,7 @@ mkdir build\ZAPD <Profile>true</Profile>
<AdditionalDependencies>ZAPDUtils.lib;/WHOLEARCHIVE:ExporterExample.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <SubSystem>Console</SubSystem>
</Link>
<PreBuildEvent>
<Command>cd .. @@ -177,6 +179,7 @@ mkdir build\ZAPD <ClCompile Include="..\lib\libgfxd\uc_f3dex.c" />
<ClCompile Include="..\lib\libgfxd\uc_f3dex2.c" />
<ClCompile Include="..\lib\libgfxd\uc_f3dexb.c" />
+ <ClCompile Include="CrashHandler.cpp" />
<ClCompile Include="Declaration.cpp" />
<ClCompile Include="GameConfig.cpp" />
<ClCompile Include="Globals.cpp" />
@@ -265,6 +268,7 @@ mkdir build\ZAPD <ClInclude Include="..\lib\stb\stb_image.h" />
<ClInclude Include="..\lib\stb\stb_image_write.h" />
<ClInclude Include="..\lib\stb\tinyxml2.h" />
+ <ClInclude Include="CrashHandler.h" />
<ClInclude Include="CRC32.h" />
<ClInclude Include="Declaration.h" />
<ClInclude Include="GameConfig.h" />
diff --git a/ZAPD/ZAPD.vcxproj.filters b/ZAPD/ZAPD.vcxproj.filters index 4de236f..b5fefd6 100644 --- a/ZAPD/ZAPD.vcxproj.filters +++ b/ZAPD/ZAPD.vcxproj.filters @@ -288,6 +288,9 @@ <ClCompile Include="OtherStructs\CutsceneMM_Commands.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
+ <ClCompile Include="CrashHandler.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ZRoom\ZRoom.h">
@@ -548,6 +551,9 @@ <ClInclude Include="OtherStructs\CutsceneMM_Commands.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
+ <ClInclude Include="CrashHandler.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="..\SymbolMap_OoTMqDbg.txt">
diff --git a/ZAPDUtils/ZAPDUtils.vcxproj b/ZAPDUtils/ZAPDUtils.vcxproj index c0ef260..4b91c2a 100644 --- a/ZAPDUtils/ZAPDUtils.vcxproj +++ b/ZAPDUtils/ZAPDUtils.vcxproj @@ -29,7 +29,7 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v143</PlatformToolset>
+ <PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -42,7 +42,7 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v143</PlatformToolset>
+ <PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
