Bug#1000356: spring: FTBFS with glibc 2.34

Steve Langasek steve.langasek at canonical.com
Mon Nov 22 01:09:26 GMT 2021


Package: spring
Version: 105.0.1+dfsg-3
Severity: important
Tags: patch
User: ubuntu-devel at lists.ubuntu.com
Usertags: origin-ubuntu jammy ubuntu-patch

Hi Markus,

In Ubuntu, we have upgraded to glibc 2.34.  As a result, spring now fails to
build because MINSIGSTKSZ is no longer a constant but expands to a runtime
call to sysconf(), and the spring source assumes it's a constant.

I found an upstream patch for this in Catch, which is where the code in
spring was copied from, and have adapted it to apply to the spring source. 
The attached patch has been uploaded to Ubuntu and fixes the build failure
there.

This is obviously not critical yet for Debian, which still only has glibc
2.33 in experimental.

Cheers,
-- 
Steve Langasek                   Give me a lever long enough and a Free OS
Debian Developer                   to set it on, and I can move the world.
Ubuntu Developer                                   https://www.debian.org/
slangasek at ubuntu.com                                     vorlon at debian.org
-------------- next part --------------
diff -Nru spring-105.0.1+dfsg/debian/patches/glibc-2.34.patch spring-105.0.1+dfsg/debian/patches/glibc-2.34.patch
--- spring-105.0.1+dfsg/debian/patches/glibc-2.34.patch	1969-12-31 16:00:00.000000000 -0800
+++ spring-105.0.1+dfsg/debian/patches/glibc-2.34.patch	2021-11-20 18:22:38.000000000 -0800
@@ -0,0 +1,249 @@
+Description: compatibility with glibc 2.34
+ Taken from catch2 upstream, commit id
+ c0d0a50bdb2ae2f749443c0386c2b25379bdbf76 in
+ https://github.com/catchorg/Catch2.
+Author: Steve Langasek <steve.langasek at ubuntu.com>
+Last-Update: 2021-11-20
+
+Index: spring-105.0.1+dfsg/rts/lib/catch.hpp
+===================================================================
+--- spring-105.0.1+dfsg.orig/rts/lib/catch.hpp
++++ spring-105.0.1+dfsg/rts/lib/catch.hpp
+@@ -4876,56 +4876,61 @@
+ #endif // defined(CATCH_PLATFORM_WINDOWS)
+ 
+ // end catch_windows_h_proxy.h
+-#if defined( CATCH_CONFIG_WINDOWS_SEH )
+-
+-namespace Catch {
+-
+-    struct FatalConditionHandler {
+ 
+-        static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
+-        FatalConditionHandler();
+-        static void reset();
+-        ~FatalConditionHandler();
+-
+-    private:
+-        static bool isSet;
+-        static ULONG guaranteeSize;
+-        static PVOID exceptionHandlerHandle;
+-    };
+-
+-} // namespace Catch
+-
+-#elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
+-
+-#include <signal.h>
++#include <cassert>
+ 
+ namespace Catch {
+ 
+-    struct FatalConditionHandler {
+-
+-        static bool isSet;
+-        static struct sigaction oldSigActions[];
+-        static stack_t oldSigStack;
+-        static char altStackMem[];
+-
+-        static void handleSignal( int sig );
+-
++    /**
++     * Wrapper for platform-specific fatal error (signals/SEH) handlers
++     *
++     * Tries to be cooperative with other handlers, and not step over
++     * other handlers. This means that unknown structured exceptions
++     * are passed on, previous signal handlers are called, and so on.
++     *
++     * Can only be instantiated once, and assumes that once a signal
++     * is caught, the binary will end up terminating. Thus, there
++     */
++    class FatalConditionHandler {
++        bool m_started = false;
++
++        // Install/disengage implementation for specific platform.
++        // Should be if-defed to work on current platform, can assume
++        // engage-disengage 1:1 pairing.
++        void engage_platform();
++        void disengage_platform();
++    public:
++        // Should also have platform-specific implementations as needed
+         FatalConditionHandler();
+         ~FatalConditionHandler();
+-        static void reset();
+-    };
+ 
+-} // namespace Catch
++        void engage() {
++            assert(!m_started && "Handler cannot be installed twice.");
++            m_started = true;
++            engage_platform();
++        }
+ 
+-#else
++        void disengage() {
++            assert(m_started && "Handler cannot be uninstalled without being installed first");
++            m_started = false;
++            disengage_platform();
++        }
++    };
+ 
+-namespace Catch {
+-    struct FatalConditionHandler {
+-        void reset();
++    //! Simple RAII guard for (dis)engaging the FatalConditionHandler
++    class FatalConditionHandlerGuard {
++        FatalConditionHandler* m_handler;
++    public:
++        FatalConditionHandlerGuard(FatalConditionHandler* handler):
++            m_handler(handler) {
++            m_handler->engage();
++        }
++        ~FatalConditionHandlerGuard() {
++            m_handler->disengage();
++        }
+     };
+-}
+ 
+-#endif
++} // end namespace Catch
+ 
+ // end catch_fatal_condition.h
+ #include <string>
+@@ -7391,7 +7396,12 @@
+     void reportFatal( char const * const message ) {
+         Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
+     }
+-}
++
++    //! Minimal size Catch2 needs for its own fatal error handling.
++    //! Picked empirically, so it might not be sufficient on all
++    //! platforms, and for all configurations.
++    constexpr std::size_t minStackSizeForErrors = 32 * 1024;
++} // end unnamed namespace
+ 
+ #endif // signals/SEH handling
+ 
+@@ -7454,6 +7464,8 @@
+ 
+ #elif defined( CATCH_CONFIG_POSIX_SIGNALS )
+ 
++#include <signal.h>
++
+ namespace Catch {
+ 
+     struct SignalDefs {
+@@ -7461,10 +7473,6 @@
+         const char* name;
+     };
+ 
+-    // 32kb for the alternate stack seems to be sufficient. However, this value
+-    // is experimentally determined, so that's not guaranteed.
+-    constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
+-
+     static SignalDefs signalDefs[] = {
+         { SIGINT,  "SIGINT - Terminal interrupt signal" },
+         { SIGILL,  "SIGILL - Illegal instruction signal" },
+@@ -7474,7 +7482,24 @@
+         { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
+     };
+ 
+-    void FatalConditionHandler::handleSignal( int sig ) {
++    static char* altStackMem = nullptr;
++    static std::size_t altStackSize = 0;
++    static stack_t oldSigStack{};
++    static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{};
++
++    static void restorePreviousSignalHandlers() {
++        // We set signal handlers back to the previous ones. Hopefully
++        // nobody overwrote them in the meantime, and doesn't expect
++        // their signal handlers to live past ours given that they
++        // installed them after ours..
++        for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
++            sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
++        }
++        // Return the old stack
++        sigaltstack(&oldSigStack, nullptr);
++    }
++
++    static void handleSignal( int sig ) {
+         char const * name = "<unknown signal>";
+         for (auto const& def : signalDefs) {
+             if (sig == def.id) {
+@@ -7482,16 +7507,33 @@
+                 break;
+             }
+         }
+-        reset();
+-        reportFatal(name);
++        // We need to restore previous signal handlers and let them do
++        // their thing, so that the users can have the debugger break
++        // when a signal is raised, and so on.
++        restorePreviousSignalHandlers();
++        reportFatal( name );
+         raise( sig );
+     }
+ 
+     FatalConditionHandler::FatalConditionHandler() {
+-        isSet = true;
++        assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists");
++        if (altStackSize == 0) {
++            altStackSize = std::max(static_cast<size_t>(SIGSTKSZ), minStackSizeForErrors);
++        }
++        altStackMem = new char[altStackSize]();
++    }
++
++    FatalConditionHandler::~FatalConditionHandler() {
++        delete[] altStackMem;
++        // We signal that another instance can be constructed by zeroing
++        // out the pointer.
++        altStackMem = nullptr;
++    }
++
++    void FatalConditionHandler::engage_platform() {
+         stack_t sigStack;
+         sigStack.ss_sp = altStackMem;
+-        sigStack.ss_size = sigStackSize;
++        sigStack.ss_size = altStackSize;
+         sigStack.ss_flags = 0;
+         sigaltstack(&sigStack, &oldSigStack);
+         struct sigaction sa = { };
+@@ -7503,27 +7545,10 @@
+         }
+     }
+ 
+-    FatalConditionHandler::~FatalConditionHandler() {
+-        reset();
+-    }
+-
+-    void FatalConditionHandler::reset() {
+-        if( isSet ) {
+-            // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
+-            for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
+-                sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
+-            }
+-            // Return the old stack
+-            sigaltstack(&oldSigStack, nullptr);
+-            isSet = false;
+-        }
++    void FatalConditionHandler::disengage_platform() {
++        restorePreviousSignalHandlers();
+     }
+ 
+-    bool FatalConditionHandler::isSet = false;
+-    struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
+-    stack_t FatalConditionHandler::oldSigStack = {};
+-    char FatalConditionHandler::altStackMem[sigStackSize] = {};
+-
+ } // namespace Catch
+ 
+ #else
+@@ -9045,7 +9070,7 @@
+     void RunContext::invokeActiveTestCase() {
+         FatalConditionHandler fatalConditionHandler; // Handle signals
+         m_activeTestCase->invoke();
+-        fatalConditionHandler.reset();
++        fatalConditionHandler.disengage();
+     }
+ 
+     void RunContext::handleUnfinishedSections() {
diff -Nru spring-105.0.1+dfsg/debian/patches/series spring-105.0.1+dfsg/debian/patches/series
--- spring-105.0.1+dfsg/debian/patches/series	2021-10-15 13:07:22.000000000 -0700
+++ spring-105.0.1+dfsg/debian/patches/series	2021-11-20 18:21:13.000000000 -0800
@@ -5,3 +5,4 @@
 glShaderSource.patch
 jsoncpp.patch
 gcc11.patch
+glibc-2.34.patch


More information about the Pkg-games-devel mailing list