From 01064e79609f339c8344538d789d6eb24fe3d705 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 8 Jun 2023 15:54:08 -0700 Subject: [PATCH] added babase.native_stack_trace() --- .efrocachemap | 56 +++++++++---------- CHANGELOG.md | 4 +- src/assets/ba_data/python/babase/__init__.py | 2 + src/assets/ba_data/python/baenv.py | 2 +- .../python/methods/python_methods_misc.cc | 32 +++++++++++ src/ballistica/core/platform/core_platform.cc | 4 +- src/ballistica/core/platform/core_platform.h | 10 ++-- .../platform/windows/core_platform_windows.cc | 8 +-- .../platform/windows/core_platform_windows.h | 2 +- src/ballistica/shared/ballistica.cc | 2 +- src/ballistica/shared/foundation/exception.cc | 2 +- .../shared/foundation/fatal_error.cc | 2 +- 12 files changed, 82 insertions(+), 44 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 54f52996..861a0a5e 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/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/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/6b/af/77143d27fc8d029928c5e1bb10c7", + "build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/85/76/121d40e717c2de145d6dca273642", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/1c/23/18d7ef96170aa3062abb354f2273", + "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/12/a9/99703794b4cc389f320721d94aae", + "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/80/32/2efd24f59072f1cb879b0f200655", + "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/21/46/cef78dedb759770ff165dae9c926", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/84/fc/0b6d71d75f4bd63f62fa7b980dbb", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/eb/81/93908c54010e63084ac763e65fed", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/f7/06/a66e097cd58666d098a38b700bdc", + "build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/e1/f9/8fcb8ff917dc0b2d2f06d8e43fd2", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/c4/8c/a7b9933f30c839ec5b9ad46e6584", + "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/d2/0f/7b312ae1f670cc9144208303e61c", + "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/c1/dd/c7e2c05c76b12bbe4b3ff6a2461a", + "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/74/6c/c2283283605425d3a3c8b60adbb8", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/e6/77/ecf7fc23cb0bed38be8f1779dd02", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/d7/21/776c71a0d8536ef13186c053cde4", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/ca/a0/40a94450ef233e76c6d0a34164b1", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/9b/0e/ac0aaf7253be3e379c8e32b0d29f", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/71/43/0f2794f1da00b2169b3e4652341e", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/b0/f5/8539056667c96d4bbe170073f74e", "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/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", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/55/c6/3e32ba9707e85f406ea329a00c21", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/4f/40/fc458ef6f3d7bcffb1f2998986d4", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/78/56/b042fdc52d047dce785cef6c1cb1", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/83/7a/33e42ec87ed9b0f3d42ae196efbf", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/91/24/0b00221d14389ae8ae7bd256f1e2", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/05/01/0c0f852d345d6b0cc64d254625bd", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/43/6b/d56519105aa22a01bc910f08c959", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/f7/fc/e25e5116bca1e0f647b725316fc0", "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 41ccdb03..d5c2bcf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.20 (build 21074, api 8, 2023-06-08) +### 1.7.20 (build 21075, 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 @@ -303,6 +303,8 @@ - (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. +- (build 21074) Added `babase.native_stack_trace()` to fetch native stack traces + as strings. ### 1.7.19 (build 20997, api 7, 2023-01-19) diff --git a/src/assets/ba_data/python/babase/__init__.py b/src/assets/ba_data/python/babase/__init__.py index 2fd7602b..2b6c4876 100644 --- a/src/assets/ba_data/python/babase/__init__.py +++ b/src/assets/ba_data/python/babase/__init__.py @@ -34,6 +34,7 @@ from _babase import ( clipboard_get_text, clipboard_set_text, in_logic_thread, + native_stack_trace, ) from babase._appintent import AppIntent, AppIntentDefault, AppIntentExec @@ -167,6 +168,7 @@ __all__ = [ 'AppMode', 'AppSubsystem', 'screenmessage', + 'native_stack_trace', ] # We want stuff to show up as babase.Foo instead of babase._sub.Foo. diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py index 380acbf4..bd103bf5 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 = 21074 +TARGET_BALLISTICA_BUILD = 21075 TARGET_BALLISTICA_VERSION = '1.7.20' _g_env_config: EnvConfig | None = None diff --git a/src/ballistica/base/python/methods/python_methods_misc.cc b/src/ballistica/base/python/methods/python_methods_misc.cc index 9fccda69..47e553fa 100644 --- a/src/ballistica/base/python/methods/python_methods_misc.cc +++ b/src/ballistica/base/python/methods/python_methods_misc.cc @@ -1383,6 +1383,37 @@ static PyMethodDef PyUnlockAllInputDef = { "Resumes normal keyboard, mouse, and gamepad event processing.", }; +// --------------------------- native_stack_trace ------------------------------ + +static auto PyNativeStackTrace(PyObject* self) -> PyObject* { + BA_PYTHON_TRY; + assert(g_core); + auto* trace = g_core->platform->GetStackTrace(); + if (!trace) { + Py_RETURN_NONE; + } + auto out = trace->FormatForDisplay(); + delete trace; + return PyUnicode_FromString(out.c_str()); + Py_RETURN_FALSE; + BA_PYTHON_CATCH; +} + +static PyMethodDef PyNativeStackTraceDef = { + "native_stack_trace", // name + (PyCFunction)PyNativeStackTrace, // method + METH_NOARGS, // flags + + "native_stack_trace() -> str | None\n" + "\n" + "Return a native stack trace as a string, or None if not available.\n" + "\n" + "Category: **General Utility Functions**\n" + "\n" + "Stack traces contain different data and formatting across platforms.\n" + "Only use them for debugging.", +}; + // ----------------------------------------------------------------------------- auto PythonMethodsMisc::GetMethods() -> std::vector { @@ -1436,6 +1467,7 @@ auto PythonMethodsMisc::GetMethods() -> std::vector { PySetUpSigIntDef, PyGetSimpleSoundDef, PyHasTouchScreenDef, + PyNativeStackTraceDef, }; } diff --git a/src/ballistica/core/platform/core_platform.cc b/src/ballistica/core/platform/core_platform.cc index c8b7911b..f1ff0f34 100644 --- a/src/ballistica/core/platform/core_platform.cc +++ b/src/ballistica/core/platform/core_platform.cc @@ -1058,10 +1058,10 @@ class PlatformStackTraceExecInfo : public PlatformStackTrace { // The stack trace should capture the stack state immediately upon // construction but should do the bare minimum amount of work to store it. Any // expensive operations such as symbolification should be deferred until - // GetDescription(). + // FormatForDisplay(). PlatformStackTraceExecInfo() { nsize_ = backtrace(array_, kMaxStackLevels); } - auto GetDescription() noexcept -> std::string override { + auto FormatForDisplay() noexcept -> std::string override { try { std::string s; char** symbols = backtrace_symbols(array_, nsize_); diff --git a/src/ballistica/core/platform/core_platform.h b/src/ballistica/core/platform/core_platform.h index 06c459e2..24d0fc4a 100644 --- a/src/ballistica/core/platform/core_platform.h +++ b/src/ballistica/core/platform/core_platform.h @@ -19,14 +19,14 @@ namespace ballistica::core { /// trace classes should capture the stack state immediately upon /// construction but should do the bare minimum amount of work to store it. /// Any expensive operations such as symbolification should be deferred -/// until GetDescription(). +/// until FormatForDisplay(). class PlatformStackTrace { public: virtual ~PlatformStackTrace() = default; // Return a human readable version of the trace (with symbolification if // available). - virtual auto GetDescription() noexcept -> std::string = 0; + virtual auto FormatForDisplay() noexcept -> std::string = 0; // Should return a copy of itself allocated via new() (or nullptr if not // possible). @@ -362,8 +362,10 @@ class CorePlatform { #pragma mark ERRORS & DEBUGGING ------------------------------------------------ - /// Should return a subclass of PlatformStackTrace allocated via new. - /// Platforms with no meaningful stack trace functionality can return nullptr. + /// Should return a subclass of PlatformStackTrace allocated via new. It + /// is up to the caller to call delete on the returned trace when done + /// with it. Platforms with no meaningful stack trace functionality can + /// return nullptr. virtual auto GetStackTrace() -> PlatformStackTrace*; // Called during stress testing. diff --git a/src/ballistica/core/platform/windows/core_platform_windows.cc b/src/ballistica/core/platform/windows/core_platform_windows.cc index d3d4d4ff..0587b49d 100644 --- a/src/ballistica/core/platform/windows/core_platform_windows.cc +++ b/src/ballistica/core/platform/windows/core_platform_windows.cc @@ -58,8 +58,8 @@ class WinStackTrace : public PlatformStackTrace { // Return a human readable version of the trace (with symbolification if // available). - auto GetDescription() noexcept -> std::string { - return platform_->GetWinStackTraceDescription(this); + auto FormatForDisplay() noexcept -> std::string { + return platform_->FormatWinStackTraceForDisplay(this); } // Should return a copy of itself allocated via new() (or nullptr if not @@ -87,7 +87,7 @@ class WinStackTrace : public PlatformStackTrace { void* stack_[kTraceMaxStackFrames]; }; -auto CorePlatformWindows::GetWinStackTraceDescription( +auto CorePlatformWindows::FormatWinStackTraceForDisplay( WinStackTrace* stack_trace) -> std::string { try { std::string out; @@ -214,7 +214,7 @@ CorePlatformWindows::CorePlatformWindows() { // printStackTrace(); // auto* testtrace = new WinStackTrace(this); - // printf("WINTRACE:\n%s", testtrace->GetDescription().c_str()); + // printf("WINTRACE:\n%s", testtrace->FormatForDisplay().c_str()); // printf("WOOHOO!\n"); // fflush(stdout); diff --git a/src/ballistica/core/platform/windows/core_platform_windows.h b/src/ballistica/core/platform/windows/core_platform_windows.h index 15a045ee..ddc1054a 100644 --- a/src/ballistica/core/platform/windows/core_platform_windows.h +++ b/src/ballistica/core/platform/windows/core_platform_windows.h @@ -58,7 +58,7 @@ class CorePlatformWindows : public CorePlatform { auto GetSubplatformName() -> std::string override; bool have_stdin_stdout_ = false; - auto GetWinStackTraceDescription(WinStackTrace* stack_trace) -> std::string; + auto FormatWinStackTraceForDisplay(WinStackTrace* stack_trace) -> std::string; private: std::mutex win_stack_mutex_; diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc index db815e43..e7877cc5 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 = 21074; +const int kEngineBuildNumber = 21075; 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 3b5abc9e..8e54fc6b 100644 --- a/src/ballistica/shared/foundation/exception.cc +++ b/src/ballistica/shared/foundation/exception.cc @@ -65,7 +65,7 @@ auto Exception::what() const noexcept -> const char* { if (stack_trace_ != nullptr) { const_cast(this)->full_description_ = message_ + "\nThrown from " + thread_name_ + " thread:\n" - + stack_trace_->GetDescription(); + + stack_trace_->FormatForDisplay(); } else { const_cast(this)->full_description_ = message_; } diff --git a/src/ballistica/shared/foundation/fatal_error.cc b/src/ballistica/shared/foundation/fatal_error.cc index 0c3373b7..2e8531e4 100644 --- a/src/ballistica/shared/foundation/fatal_error.cc +++ b/src/ballistica/shared/foundation/fatal_error.cc @@ -72,7 +72,7 @@ void FatalError::ReportFatalError(const std::string& message, if (g_core && g_core->platform) { core::PlatformStackTrace* trace{g_core->platform->GetStackTrace()}; if (trace) { - std::string tracestr = trace->GetDescription(); + std::string tracestr = trace->FormatForDisplay(); if (!tracestr.empty()) { logmsg += ("\nCPP-STACK-TRACE-BEGIN:\n" + tracestr + "\nCPP-STACK-TRACE-END");