From ab8d3bc1245f0e454cd3865009f6332a8c0090a0 Mon Sep 17 00:00:00 2001 From: Jason Madden Date: Fri, 20 Sep 2024 10:19:59 -0500 Subject: [PATCH] Disable thread-local cleanup on 32-bit MacOS PPC with GCC. This will result in some test failures on that platform, but hopefully solves a crash we were never able to debug when using multiple threads. This is only tested on pre-release versions of an OS that was never released using a compiler available from MacPorts. --- CHANGES.rst | 8 ++++++++ src/greenlet/TThreadStateDestroy.cpp | 4 ++++ src/greenlet/greenlet_compiler_compat.hpp | 11 +++++++++++ src/greenlet/slp_platformselect.h | 2 +- 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 8c24a4e..b8625d3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -11,6 +11,14 @@ `_. - Remove unnecessary logging sometimes during interpreter shutdown. See `issue 426 `_. +- Fix some crashes on 32-bit PPC MacOS. This is a very old platform, + and is only known to be tested on beta versions of an operating + system that was never released, using the GCC 14 only provided by + MacPorts; it may or may not work on the final MacOS X release that + supported 32-bit PowerPC. It has the known issue of leaking memory + when greenlets are used in multiple threads. Help debugging this + would be appreciated. See `PR 419 + `_. 3.1.0 (2024-09-10) ================== diff --git a/src/greenlet/TThreadStateDestroy.cpp b/src/greenlet/TThreadStateDestroy.cpp index 9c4f2e0..37fcc8c 100644 --- a/src/greenlet/TThreadStateDestroy.cpp +++ b/src/greenlet/TThreadStateDestroy.cpp @@ -16,6 +16,7 @@ #include "greenlet_thread_support.hpp" #include "greenlet_cpython_add_pending.hpp" +#include "greenlet_compiler_compat.hpp" #include "TGreenletGlobals.cpp" #include "TThreadState.hpp" #include "TThreadStateCreator.hpp" @@ -32,6 +33,9 @@ struct ThreadState_DestroyNoGIL static void MarkGreenletDeadAndQueueCleanup(ThreadState* const state) { +#if GREENLET_BROKEN_THREAD_LOCAL_CLEANUP_JUST_LEAK + return; +#endif // We are *NOT* holding the GIL. Our thread is in the middle // of its death throes and the Python thread state is already // gone so we can't use most Python APIs. One that is safe is diff --git a/src/greenlet/greenlet_compiler_compat.hpp b/src/greenlet/greenlet_compiler_compat.hpp index 6fe892f..af24bd8 100644 --- a/src/greenlet/greenlet_compiler_compat.hpp +++ b/src/greenlet/greenlet_compiler_compat.hpp @@ -83,5 +83,16 @@ # define G_NOEXCEPT_WIN32 #endif +#if defined(__GNUC__) && defined(__POWERPC__) && defined(__APPLE__) +// 32-bit PPC/MacOSX. Only known to be tested on unreleased versions +// of macOS 10.6 using a macports build gcc 14. It appears that +// running C++ destructors of thread-local variables is broken. + +// See https://github.com/python-greenlet/greenlet/pull/419 +# define GREENLET_BROKEN_THREAD_LOCAL_CLEANUP_JUST_LEAK 1 +#else +# define GREENLET_BROKEN_THREAD_LOCAL_CLEANUP_JUST_LEAK 0 +#endif + #endif diff --git a/src/greenlet/slp_platformselect.h b/src/greenlet/slp_platformselect.h index 87898a4..4945648 100644 --- a/src/greenlet/slp_platformselect.h +++ b/src/greenlet/slp_platformselect.h @@ -22,7 +22,7 @@ extern "C" { #elif defined(__GNUC__) && defined(__PPC__) && (defined(__linux__) || defined(__FreeBSD__)) # include "platform/switch_ppc_linux.h" /* gcc on PowerPC */ #elif defined(__GNUC__) && defined(__POWERPC__) && defined(__APPLE__) -# include "platform/switch_ppc_macosx.h" /* Apple MacOS X on PowerPC */ +# include "platform/switch_ppc_macosx.h" /* Apple MacOS X on 32-bit PowerPC */ #elif defined(__GNUC__) && defined(__powerpc64__) && defined(_AIX) # include "platform/switch_ppc64_aix.h" /* gcc on AIX/PowerPC 64-bit */ #elif defined(__GNUC__) && defined(_ARCH_PPC) && defined(_AIX)