From 95815353cc0cd4e96cf3a295c951bee37253b874 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 8 Jun 2023 15:16:35 -0700 Subject: [PATCH] implemented stack traces on windows --- .efrocachemap | 56 +++---- CHANGELOG.md | 5 +- src/assets/ba_data/python/baenv.py | 2 +- src/ballistica/core/core.cc | 8 +- src/ballistica/core/platform/core_platform.cc | 2 +- src/ballistica/core/platform/core_platform.h | 2 +- .../platform/windows/core_platform_windows.cc | 153 ++++++++++++++++++ .../platform/windows/core_platform_windows.h | 11 ++ src/ballistica/shared/ballistica.cc | 2 +- src/ballistica/shared/foundation/exception.cc | 2 +- src/ballistica/ui_v1/ui_v1.h | 2 +- tools/batools/project/_checks.py | 6 +- 12 files changed, 211 insertions(+), 40 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 783083ad..54f52996 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -4072,26 +4072,26 @@ "build/assets/workspace/ninjafightplug.py": "https://files.ballistica.net/cache/ba1/c5/09/4f10b8a21ba87aa5509cff7a164b", "build/assets/workspace/onslaughtplug.py": "https://files.ballistica.net/cache/ba1/ff/0a/a354984f9c074dab0676ac7e4877", "build/assets/workspace/runaroundplug.py": "https://files.ballistica.net/cache/ba1/2a/1c/9ee5db6d1bceca7fa6638fb8abde", - "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/76/e2/95ac7cceb6e94fd34acc7c350263", - "build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/54/b3/9c381ed5dda3c399c7b955fa8d50", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/a6/77/a0efaffa066d6b00bc996b56636b", - "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/ee/51/d753711059b5438da91fe1ac03db", - "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/07/5a/2cc7650c428543f5a33013bfceeb", - "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/1c/38/2665b9bd9bac14ad73ef4986acd7", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/fc/18/11baef9fa7f78211da59e1396fc9", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/5a/fc/fcf4c33bde143d92cfafbdf16ee3", - "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/83/02/b567d1fd06d21863ba125fd1ae22", - "build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/fc/64/129a84c24ee5074d3b1a7c0d3440", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/ad/d2/87c0898b21b23d8d54a16e44a2fd", - "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/89/8f/27cd935153e755742f79753ce9a0", - "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/cb/46/21e3e231e46b9a694747bb060333", - "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/db/e8/73eb4dc951795c665c946c943ebb", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/e1/b6/941774ba089254534ac54612a842", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/d0/86/9cb45fca207b9b43db1beee48514", - "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/21/a0/13b7bb057fc1d351427127f5b001", - "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/8d/63/657b92f76a646cb7cace9c467c26", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/9c/e0/ef535d0fc11b943eced693b1465d", - "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/86/f0/6a02c50487ba42a86f4bd173e54c", + "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/fa/78/a214be11993d36a52192d87ec637", + "build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/37/b3/419b2996dcf20e83d2550512ede5", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/fc/32/72b0b40b06ecca15e7da66180553", + "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/8c/8e/692af6872e7a247793d88d9ebf99", + "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/1c/c6/59084601f9a9ab70c673a8782c5a", + "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/f4/44/aee3980f4d679d89145abcdc4146", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/99/6e/bb06e27cf507f1ac597cd88ddf99", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/e1/7b/811ab8937a398e7d40c85a22cc0e", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/1b/73/543b3d40a8ab5ec65f549d575736", + "build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/f0/e1/b305a86d0ee307b497b19eb7ae18", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/14/5e/6e8bfa5870766ab3cb0bc1363fc1", + "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/5a/24/8779125082977f75de7aeac097ca", + "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/c5/ab/969f814415316f5a32b21b5ec95e", + "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/63/7a/fb8c34f54070613f56c5ecdb5d0a", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/df/a6/4406c159af542d841a9a598a50d2", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/17/0b/052ded44e214490afb11370e548c", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/49/1f/f9bf566efdd357185713ee2db3f7", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/a5/6f/3f16a4bc453b29f2934269afe369", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/b6/93/f1daebdde56b97167ac43c6e983c", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/51/7c/833fcba248f23598eb606ec1e366", "build/prefab/lib/linux_arm64_gui/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/58/55/b6ae6dd4f3615fa87bb170a43233", "build/prefab/lib/linux_arm64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/b9/f8/37285d0ced7794a82534d13c33ac", "build/prefab/lib/linux_arm64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/c7/cc/0c5f0afbfa0ddabaea8d5838562a", @@ -4108,14 +4108,14 @@ "build/prefab/lib/mac_x86_64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/96/2e/1b0ba43fe24fe9cc223a434db647", "build/prefab/lib/mac_x86_64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/f3/83/581b7df96f6516032a0747b83e15", "build/prefab/lib/mac_x86_64_server/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/6a/6d/7aaf7617929eeff41bc5a574e6c8", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/20/f0/4e9e3644c559e00816a8621a8987", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/7c/39/5390a4370b1c3a931a84abf6f477", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/f8/ec/e98d729c3d66249a1e11aa26af2d", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/62/9c/2c38890b97307365059b162abe51", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/90/81/4d46be8eb3992b016a7c82f5766a", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/18/09/af24159486d0253f900e262d9fd9", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/a8/f5/68bb806fdee3a4694352d1e03a60", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/ee/96/8259473f7ed61dfdb8dd8af6f845", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/bf/67/b2e47d165f67487a411c10ec6761", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/68/3f/b02ee9d51503a71abe3fc9a160a8", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/87/9b/63f4ed1cef6e7214b69c06962d2c", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/ee/64/6a17dc184bac9e42613a2228e210", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/a3/7c/607018f0aa7f918a978d8d9719e2", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/14/49/7af3c9043dadbb78e5d4467e471b", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/15/a5/28c86995a7171bd8b5d0291da22f", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/93/f5/0ad008b1910c9a630e47d4077d83", "src/assets/ba_data/python/babase/_mgen/__init__.py": "https://files.ballistica.net/cache/ba1/52/c6/c11130af7b10d6c0321add5518fa", "src/assets/ba_data/python/babase/_mgen/enums.py": "https://files.ballistica.net/cache/ba1/38/c3/1dedd5e74f2508efc5974c8815a1", "src/ballistica/base/mgen/pyembed/binding_base.inc": "https://files.ballistica.net/cache/ba1/75/9f/bcf597b362c9f2480cb348188bdd", diff --git a/CHANGELOG.md b/CHANGELOG.md index 608ae192..41ccdb03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.20 (build 21073, api 8, 2023-06-08) +### 1.7.20 (build 21074, api 8, 2023-06-08) - This seems like a good time for a `refactoring` release in anticipation of changes coming in 1.8. Basically this means that a lot of things will be @@ -300,6 +300,9 @@ - (build 21070) Fixed an issue where teams series would incorrectly end after 1 round (thanks for the heads up SEBASTIAN2059) - (build 21072) Fixed a crash drawing a terrain node with no texture set. +- (build 21073) Stack traces are now implemented under windows so should show up + for fatal errors and whatnot. Also fatal error logging now mentions when stack + traces are not available. ### 1.7.19 (build 20997, api 7, 2023-01-19) diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py index f4b21301..380acbf4 100644 --- a/src/assets/ba_data/python/baenv.py +++ b/src/assets/ba_data/python/baenv.py @@ -28,7 +28,7 @@ if TYPE_CHECKING: # Build number and version of the ballistica binary we expect to be # using. -TARGET_BALLISTICA_BUILD = 21073 +TARGET_BALLISTICA_BUILD = 21074 TARGET_BALLISTICA_VERSION = '1.7.20' _g_env_config: EnvConfig | None = None diff --git a/src/ballistica/core/core.cc b/src/ballistica/core/core.cc index c5db9aa0..1ae694ab 100644 --- a/src/ballistica/core/core.cc +++ b/src/ballistica/core/core.cc @@ -123,10 +123,10 @@ void CoreFeatureSet::PostInit() { // We can use it to make error messages/etc. more pretty by stripping out // all but sub-project paths. const char* f = __FILE__; - auto* f_end = strstr( - f, "src" BA_DIRSLASH "ballistica" BA_DIRSLASH "app" BA_DIRSLASH "app.cc"); - if (!f) { - Log(LogLevel::kWarning, "Unable to calc project dir from __FILE__."); + auto* f_end = strstr(f, "src" BA_DIRSLASH "ballistica" BA_DIRSLASH + "core" BA_DIRSLASH "core.cc"); + if (!f_end) { + Log(LogLevel::kWarning, "Unable to calc build source dir from __FILE__."); } else { build_src_dir_ = std::string(f).substr(0, f_end - f); } diff --git a/src/ballistica/core/platform/core_platform.cc b/src/ballistica/core/platform/core_platform.cc index f13e1916..c8b7911b 100644 --- a/src/ballistica/core/platform/core_platform.cc +++ b/src/ballistica/core/platform/core_platform.cc @@ -1078,7 +1078,7 @@ class PlatformStackTraceExecInfo : public PlatformStackTrace { } } - auto copy() const noexcept -> PlatformStackTrace* override { + auto Copy() const noexcept -> PlatformStackTrace* override { try { auto s = new PlatformStackTraceExecInfo(*this); diff --git a/src/ballistica/core/platform/core_platform.h b/src/ballistica/core/platform/core_platform.h index e5f3cc95..06c459e2 100644 --- a/src/ballistica/core/platform/core_platform.h +++ b/src/ballistica/core/platform/core_platform.h @@ -30,7 +30,7 @@ class PlatformStackTrace { // Should return a copy of itself allocated via new() (or nullptr if not // possible). - virtual auto copy() const noexcept -> PlatformStackTrace* = 0; + virtual auto Copy() const noexcept -> PlatformStackTrace* = 0; }; /// This class attempts to abstract away most platform-specific diff --git a/src/ballistica/core/platform/windows/core_platform_windows.cc b/src/ballistica/core/platform/windows/core_platform_windows.cc index 1fca333f..d3d4d4ff 100644 --- a/src/ballistica/core/platform/windows/core_platform_windows.cc +++ b/src/ballistica/core/platform/windows/core_platform_windows.cc @@ -12,6 +12,11 @@ #include #include +/* clang-format off */ +// Builds fail if this is further up. +#include +/* clang-format on */ + #pragma comment(lib, "Rpcrt4.lib") #pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "iphlpapi.lib") @@ -20,7 +25,9 @@ #else #pragma comment(lib, "python311.lib") #endif +#pragma comment(lib, "DbgHelp.lib") +// GUI Only Stuff. #if !BA_HEADLESS_BUILD #pragma comment(lib, "libogg.lib") #pragma comment(lib, "libvorbis.lib") @@ -39,6 +46,108 @@ namespace ballistica::core { +static const int kTraceMaxStackFrames{256}; +static const int kTraceMaxFunctionNameLength{1024}; + +class WinStackTrace : public PlatformStackTrace { + public: + explicit WinStackTrace(CorePlatformWindows* platform) : platform_{platform} { + number_of_frames_ = + CaptureStackBackTrace(0, kTraceMaxStackFrames, stack_, NULL); + } + + // Return a human readable version of the trace (with symbolification if + // available). + auto GetDescription() noexcept -> std::string { + return platform_->GetWinStackTraceDescription(this); + } + + // Should return a copy of itself allocated via new() (or nullptr if not + // possible). + auto Copy() const noexcept -> PlatformStackTrace* override { + try { + auto s = new WinStackTrace(*this); + + // Vanilla copy constructor should do the right thing here. + assert(s->number_of_frames_ == number_of_frames_ + && memcmp(s->stack_, stack_, sizeof(stack_)) == 0); + return s; + } catch (const std::exception&) { + // If this is failing we're in big trouble anyway. + return nullptr; + } + } + + auto number_of_frames() const { return number_of_frames_; } + auto* stack() const { return stack_; } + + private: + CorePlatformWindows* platform_; + WORD number_of_frames_{}; + void* stack_[kTraceMaxStackFrames]; +}; + +auto CorePlatformWindows::GetWinStackTraceDescription( + WinStackTrace* stack_trace) -> std::string { + try { + std::string out; + + // Win docs say this is not thread safe so limit to one at a time. + std::scoped_lock lock(win_stack_mutex_); + + // Docs say to do this only once. + if (!win_sym_inited_) { + win_sym_process_ = GetCurrentProcess(); + SymInitialize(win_sym_process_, NULL, TRUE); + win_sym_inited_ = true; + } + + char buf[sizeof(SYMBOL_INFO) + + (kTraceMaxFunctionNameLength - 1) * sizeof(TCHAR)]; + SYMBOL_INFO* symbol = reinterpret_cast(buf); + symbol->MaxNameLen = kTraceMaxFunctionNameLength; + symbol->SizeOfStruct = sizeof(SYMBOL_INFO); + DWORD displacement; + IMAGEHLP_LINE64 line; + line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + + std::string build_src_dir = g_core ? g_core->build_src_dir() : ""; + + char linebuf[kTraceMaxFunctionNameLength + 128]; + for (int i = 0; i < stack_trace->number_of_frames(); i++) { + DWORD64 address = (DWORD64)(stack_trace->stack()[i]); + SymFromAddr(win_sym_process_, address, NULL, symbol); + if (SymGetLineFromAddr64(win_sym_process_, address, &displacement, + &line)) { + const char* filename = line.FileName; + if (!build_src_dir.empty() + && !strncmp(filename, build_src_dir.c_str(), + build_src_dir.size())) { + filename += build_src_dir.size(); + } + snprintf(linebuf, sizeof(linebuf), + "%-3d %s in %s: line: %lu: address: 0x%p\n", i, symbol->Name, + filename, line.LineNumber, + reinterpret_cast(symbol->Address)); + } else { + snprintf(linebuf, sizeof(linebuf), + "SymGetLineFromAddr64 returned error code %lu.\n", + GetLastError()); + snprintf(linebuf, sizeof(linebuf), "%-3d %s, address 0x%p.\n", i, + symbol->Name, reinterpret_cast(symbol->Address)); + } + out += linebuf; + } + return out; + } catch (const std::exception&) { + return "stack-trace construction failed."; + } +} + +auto CorePlatformWindows::GetStackTrace() -> PlatformStackTrace* { + return new WinStackTrace(this); +} + // Convert a wide Unicode string to an UTF8 string. auto CorePlatformWindows::UTF8Encode(const std::wstring& wstr) -> std::string { if (wstr.empty()) return std::string(); @@ -61,10 +170,54 @@ auto CorePlatformWindows::UTF8Decode(const std::string& str) -> std::wstring { return wstr; } +#define TRACE_MAX_STACK_FRAMES 256 +#define TRACE_MAX_FUNCTION_NAME_LENGTH 1024 + +// int printStackTrace() { +// void* stack[TRACE_MAX_STACK_FRAMES]; +// if (!win_sym_inited_) { +// win_sym_process_ = GetCurrentProcess(); +// SymInitialize(win_sym_process_, NULL, TRUE); +// win_sym_inited_ = true; +// } +// WORD numberOfFrames = +// CaptureStackBackTrace(0, TRACE_MAX_STACK_FRAMES, stack, NULL); + +// char buf[sizeof(SYMBOL_INFO) +// + (TRACE_MAX_FUNCTION_NAME_LENGTH - 1) * sizeof(TCHAR)]; +// SYMBOL_INFO* symbol = (SYMBOL_INFO*)buf; +// symbol->MaxNameLen = TRACE_MAX_FUNCTION_NAME_LENGTH; +// symbol->SizeOfStruct = sizeof(SYMBOL_INFO); +// DWORD displacement; +// IMAGEHLP_LINE64 line; +// line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); +// for (int i = 0; i < numberOfFrames; i++) { +// DWORD64 address = (DWORD64)(stack[i]); +// SymFromAddr(win_sym_process_, address, NULL, symbol); +// if (SymGetLineFromAddr64(win_sym_process_, address, &displacement, +// &line)) { +// printf("\tat %s in %s: line: %lu: address: 0x%0X\n", symbol->Name, +// line.FileName, line.LineNumber, symbol->Address); +// } else { +// printf("\tSymGetLineFromAddr64 returned error code %lu.\n", +// GetLastError()); +// printf("\tat %s, address 0x%0X.\n", symbol->Name, symbol->Address); +// } +// } +// return 0; +// } + CorePlatformWindows::CorePlatformWindows() { // We should be built in unicode mode. assert(sizeof(TCHAR) == 2); + // printStackTrace(); + + // auto* testtrace = new WinStackTrace(this); + // printf("WINTRACE:\n%s", testtrace->GetDescription().c_str()); + // printf("WOOHOO!\n"); + // fflush(stdout); + // Need to init winsock immediately since we use it for // threading/logging/etc. { diff --git a/src/ballistica/core/platform/windows/core_platform_windows.h b/src/ballistica/core/platform/windows/core_platform_windows.h index ac14b3ff..15a045ee 100644 --- a/src/ballistica/core/platform/windows/core_platform_windows.h +++ b/src/ballistica/core/platform/windows/core_platform_windows.h @@ -4,6 +4,7 @@ #define BALLISTICA_CORE_PLATFORM_WINDOWS_CORE_PLATFORM_WINDOWS_H_ #if BA_OSTYPE_WINDOWS +#include #include #include @@ -11,6 +12,8 @@ namespace ballistica::core { +class WinStackTrace; + class CorePlatformWindows : public CorePlatform { public: CorePlatformWindows(); @@ -18,6 +21,7 @@ class CorePlatformWindows : public CorePlatform { static auto UTF8Encode(const std::wstring& wstr) -> std::string; static auto UTF8Decode(const std::string& str) -> std::wstring; + auto GetStackTrace() -> PlatformStackTrace* override; auto GetDeviceV1AccountUUIDPrefix() -> std::string override { return "w"; } auto GetDeviceUUIDInputs() -> std::list override; auto GenerateUUID() -> std::string override; @@ -53,6 +57,13 @@ class CorePlatformWindows : public CorePlatform { auto GetPlatformName() -> std::string override; auto GetSubplatformName() -> std::string override; bool have_stdin_stdout_ = false; + + auto GetWinStackTraceDescription(WinStackTrace* stack_trace) -> std::string; + + private: + std::mutex win_stack_mutex_; + bool win_sym_inited_{}; + void* win_sym_process_{}; }; } // namespace ballistica::core diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc index 5812a726..db815e43 100644 --- a/src/ballistica/shared/ballistica.cc +++ b/src/ballistica/shared/ballistica.cc @@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int { namespace ballistica { // These are set automatically via script; don't modify them here. -const int kEngineBuildNumber = 21073; +const int kEngineBuildNumber = 21074; const char* kEngineVersion = "1.7.20"; auto MonolithicMain(const core::CoreConfig& core_config) -> int { diff --git a/src/ballistica/shared/foundation/exception.cc b/src/ballistica/shared/foundation/exception.cc index 23a2277b..3b5abc9e 100644 --- a/src/ballistica/shared/foundation/exception.cc +++ b/src/ballistica/shared/foundation/exception.cc @@ -43,7 +43,7 @@ Exception::Exception(const Exception& other) noexcept { full_description_ = other.full_description_; python_type_ = other.python_type_; if (other.stack_trace_) { - stack_trace_ = other.stack_trace_->copy(); + stack_trace_ = other.stack_trace_->Copy(); } } catch (const std::exception&) { // Hmmm not sure what we should do if this happens; diff --git a/src/ballistica/ui_v1/ui_v1.h b/src/ballistica/ui_v1/ui_v1.h index 67503861..2227c200 100644 --- a/src/ballistica/ui_v1/ui_v1.h +++ b/src/ballistica/ui_v1/ui_v1.h @@ -18,7 +18,7 @@ class CoreFeatureSet; } namespace ballistica::base { class BaseFeatureSet; -class WidgetMessage; +struct WidgetMessage; } // namespace ballistica::base namespace ballistica::ui_v1 { diff --git a/tools/batools/project/_checks.py b/tools/batools/project/_checks.py index 337c0aa6..df396736 100755 --- a/tools/batools/project/_checks.py +++ b/tools/batools/project/_checks.py @@ -132,7 +132,11 @@ def _get_namespace_info(lines: list[str], index: int) -> tuple[str, bool]: if lines[index].startswith('}'): return name, True if not ( - lines[index].startswith('class ') and lines[index].endswith(';') + ( + lines[index].startswith('class ') + or lines[index].startswith('struct ') + ) + and lines[index].endswith(';') ): # Found a non-predeclare statement return name, False