diff -pruN 21.0.0~dfsg1-2/debian/changelog 21.0.0~dfsg1-2ubuntu3/debian/changelog
--- 21.0.0~dfsg1-2/debian/changelog	2021-10-26 21:59:16.000000000 +0000
+++ 21.0.0~dfsg1-2ubuntu3/debian/changelog	2022-07-09 06:18:55.000000000 +0000
@@ -1,3 +1,21 @@
+monado (21.0.0~dfsg1-2ubuntu3) kinetic; urgency=medium
+
+  * No-change rebuild against libopencv-core406
+
+ -- Steve Langasek <steve.langasek@ubuntu.com>  Sat, 09 Jul 2022 06:18:55 +0000
+
+monado (21.0.0~dfsg1-2ubuntu2) jammy; urgency=medium
+
+  * No-change rebuild against libopencv-core4.5d
+
+ -- Steve Langasek <steve.langasek@ubuntu.com>  Wed, 08 Dec 2021 03:09:03 +0000
+
+monado (21.0.0~dfsg1-2ubuntu1) jammy; urgency=medium
+
+  * debian/patches/glibc-2.34.patch: compatibility with glibc 2.34.
+
+ -- Steve Langasek <steve.langasek@ubuntu.com>  Tue, 07 Dec 2021 07:38:35 +0000
+
 monado (21.0.0~dfsg1-2) unstable; urgency=medium
 
   * d/control
diff -pruN 21.0.0~dfsg1-2/debian/control 21.0.0~dfsg1-2ubuntu3/debian/control
--- 21.0.0~dfsg1-2/debian/control	2021-10-26 21:59:16.000000000 +0000
+++ 21.0.0~dfsg1-2ubuntu3/debian/control	2021-12-07 07:38:35.000000000 +0000
@@ -1,5 +1,6 @@
 Source: monado
-Maintainer: Ryan Pavlik <ryan@ryanpavlik.com>
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
+XSBC-Original-Maintainer: Ryan Pavlik <ryan@ryanpavlik.com>
 Uploaders: Andrew Lee (李健秋) <ajqlee@debian.org>
 Section: libs
 Priority: optional
diff -pruN 21.0.0~dfsg1-2/debian/.gitattributes 21.0.0~dfsg1-2ubuntu3/debian/.gitattributes
--- 21.0.0~dfsg1-2/debian/.gitattributes	2021-10-26 21:59:16.000000000 +0000
+++ 21.0.0~dfsg1-2ubuntu3/debian/.gitattributes	1970-01-01 00:00:00.000000000 +0000
@@ -1 +0,0 @@
-changelog merge=dpkg-mergechangelogs
diff -pruN 21.0.0~dfsg1-2/debian/.gitignore 21.0.0~dfsg1-2ubuntu3/debian/.gitignore
--- 21.0.0~dfsg1-2/debian/.gitignore	2021-10-26 21:59:16.000000000 +0000
+++ 21.0.0~dfsg1-2ubuntu3/debian/.gitignore	1970-01-01 00:00:00.000000000 +0000
@@ -1,12 +0,0 @@
-tmp/
-libopenxr1-monado/
-monado-cli/
-monado-gui/
-monado-service/
-.debhelper/
-debhelper-build-stamp
-files
-*.debhelper.log
-*.substvars
-*.debhelper
-!patches/
diff -pruN 21.0.0~dfsg1-2/debian/patches/glibc-2.34.patch 21.0.0~dfsg1-2ubuntu3/debian/patches/glibc-2.34.patch
--- 21.0.0~dfsg1-2/debian/patches/glibc-2.34.patch	1970-01-01 00:00:00.000000000 +0000
+++ 21.0.0~dfsg1-2ubuntu3/debian/patches/glibc-2.34.patch	2021-12-07 07:38:35.000000000 +0000
@@ -0,0 +1,297 @@
+Description: compatibility with glibc 2.34
+ Taken from catch2 upstream, commit id
+ c0d0a50bdb2ae2f749443c0386c2b25379bdbf76 in
+ https://github.com/catchorg/Catch2.
+Author: Steve Langasek <steve.langasek@ubuntu.com>
+Last-Update: 2021-12-06
+
+Index: monado-21.0.0~dfsg1/src/external/Catch2/catch/catch.hpp
+===================================================================
+--- monado-21.0.0~dfsg1.orig/src/external/Catch2/catch/catch.hpp
++++ monado-21.0.0~dfsg1/src/external/Catch2/catch/catch.hpp
+@@ -7986,56 +7986,60 @@
+ #endif // defined(CATCH_PLATFORM_WINDOWS)
+ 
+ // end catch_windows_h_proxy.h
+-#if defined( CATCH_CONFIG_WINDOWS_SEH )
++#include <cassert>
+ 
+ namespace Catch {
+ 
+-    struct FatalConditionHandler {
+-
+-        static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
++    /**
++     * 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();
+-        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>
+-
+-namespace Catch {
+-
+-    struct FatalConditionHandler {
+-
+-        static bool isSet;
+-        static struct sigaction oldSigActions[];
+-        static stack_t oldSigStack;
+-        static char altStackMem[];
+-
+-        static void handleSignal( int sig );
++        void engage() {
++            assert(!m_started && "Handler cannot be installed twice.");
++            m_started = true;
++            engage_platform();
++        }
+ 
+-        FatalConditionHandler();
+-        ~FatalConditionHandler();
+-        static void reset();
++        void disengage() {
++            assert(m_started && "Handler cannot be uninstalled without being installed first");
++            m_started = false;
++            disengage_platform();
++        }
+     };
+ 
+-} // namespace Catch
+-
+-#else
+-
+-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>
+@@ -8160,6 +8164,7 @@
+         AssertionInfo m_lastAssertionInfo;
+         std::vector<SectionEndInfo> m_unfinishedSections;
+         std::vector<ITracker*> m_activeSections;
++        FatalConditionHandler m_fatalConditionhandler;
+         TrackerContext m_trackerContext;
+         bool m_lastAssertionPassed = false;
+         bool m_shouldReportUnexpected = true;
+@@ -10707,19 +10712,19 @@
+ // end catch_exception_translator_registry.cpp
+ // start catch_fatal_condition.cpp
+ 
+-#if defined(__GNUC__)
+-#    pragma GCC diagnostic push
+-#    pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+-#endif
+-
+ #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
+ 
+ namespace {
+-    // Report the error condition
++    //! Signals fatal error message to the run context
+     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
+ 
+@@ -10770,10 +10775,6 @@
+         }
+     }
+ 
+-    FatalConditionHandler::~FatalConditionHandler() {
+-        reset();
+-    }
+-
+ bool FatalConditionHandler::isSet = false;
+ ULONG FatalConditionHandler::guaranteeSize = 0;
+ PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
+@@ -10782,6 +10783,8 @@
+ 
+ #elif defined( CATCH_CONFIG_POSIX_SIGNALS )
+ 
++#include <signal.h>
++
+ namespace Catch {
+ 
+     struct SignalDefs {
+@@ -10789,10 +10792,6 @@
+         const char* name;
+     };
+ 
+-    // 32kb for the alternate stack seems to be sufficient. However, this value
+-    // is experimentally determined, so that's not guaranteed.
+-    static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
+-
+     static SignalDefs signalDefs[] = {
+         { SIGINT,  "SIGINT - Terminal interrupt signal" },
+         { SIGILL,  "SIGILL - Illegal instruction signal" },
+@@ -10802,7 +10801,32 @@
+         { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
+     };
+ 
+-    void FatalConditionHandler::handleSignal( int sig ) {
++// Older GCCs trigger -Wmissing-field-initializers for T foo = {}
++// which is zero initialization, but not explicit. We want to avoid
++// that.
++#if defined(__GNUC__)
++#    pragma GCC diagnostic push
++#    pragma GCC diagnostic ignored "-Wmissing-field-initializers"
++#endif
++
++    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) {
+@@ -10810,16 +10834,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 = { };
+@@ -10831,29 +10872,16 @@
+         }
+     }
+ 
+-    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;
+-        }
+-    }
++#if defined(__GNUC__)
++#    pragma GCC diagnostic pop
++#endif
+ 
+-    bool FatalConditionHandler::isSet = false;
+-    struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
+-    stack_t FatalConditionHandler::oldSigStack = {};
+-    char FatalConditionHandler::altStackMem[sigStackSize] = {};
+ 
+-} // namespace Catch
++    void FatalConditionHandler::disengage_platform() {
++        restorePreviousSignalHandlers();
++    }
+ 
++} // end namespace Catch
+ #else
+ 
+ namespace Catch {
+@@ -12846,9 +12874,8 @@
+     }
+ 
+     void RunContext::invokeActiveTestCase() {
+-        FatalConditionHandler fatalConditionHandler; // Handle signals
++        FatalConditionHandlerGuard _(&m_fatalConditionhandler);
+         m_activeTestCase->invoke();
+-        fatalConditionHandler.reset();
+     }
+ 
+     void RunContext::handleUnfinishedSections() {
diff -pruN 21.0.0~dfsg1-2/debian/patches/series 21.0.0~dfsg1-2ubuntu3/debian/patches/series
--- 21.0.0~dfsg1-2/debian/patches/series	2021-10-26 21:59:16.000000000 +0000
+++ 21.0.0~dfsg1-2ubuntu3/debian/patches/series	2021-12-07 07:38:29.000000000 +0000
@@ -1,2 +1,3 @@
 0001-Allow-overriding-package-version.patch
 0002-comp-Fix-warning-after-Vulkan-1.2.174-VK_NULL_HANDLE.patch
+glibc-2.34.patch
