From 37e3e29c8c8ecb80ba868d0cfbd0a02b50cf1a55 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 17 Mar 2021 14:04:27 +0530 Subject: [PATCH] Fix a crash on systems using musl as libc Fixes #3395 --- docs/changelog.rst | 2 ++ glfw/glfw.py | 11 +++++------ kitty/desktop.c | 9 ++++++--- kitty/glfw-wrapper.c | 19 +++++++++++++++++++ 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index a25b5024f..1e5d5c1d1 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -97,6 +97,8 @@ To update |kitty|, :doc:`follow the instructions `. - Fix inactive tab closing causing active tab to change (:iss:`3398`) +- Fix a crash on systems using musl as libc (:iss:`3395`) + 0.19.3 [2020-12-19] ------------------- diff --git a/glfw/glfw.py b/glfw/glfw.py index f9d181319..837a58eda 100755 --- a/glfw/glfw.py +++ b/glfw/glfw.py @@ -179,13 +179,12 @@ class Function: ) def load(self) -> str: - ans = '*(void **) (&{name}_impl) = dlsym(handle, "{name}");'.format( - name=self.name - ) + ans = f'*(void **) (&{self.name}_impl) = dlsym(handle, "{self.name}");' + ans += f'\n if ({self.name}_impl == NULL) ' if self.check_fail: - ans += '\n if ({name}_impl == NULL) fail("Failed to load glfw function {name} with error: %s", dlerror());'.format( - name=self.name - ) + ans += f'fail("Failed to load glfw function {self.name} with error: %s", dlerror());' + else: + ans += 'dlerror(); // clear error indicator' return ans diff --git a/kitty/desktop.c b/kitty/desktop.c index 1417e0815..b3d5625a2 100644 --- a/kitty/desktop.c +++ b/kitty/desktop.c @@ -11,9 +11,11 @@ #define FUNC(name, restype, ...) typedef restype (*name##_func)(__VA_ARGS__); static name##_func name = NULL #define LOAD_FUNC(handle, name) {\ *(void **) (&name) = dlsym(handle, #name); \ - const char* error = dlerror(); \ - if (error != NULL) { \ - PyErr_Format(PyExc_OSError, "Failed to load the function %s with error: %s", #name, error); dlclose(handle); handle = NULL; return NULL; \ + if (!name) { \ + const char* error = dlerror(); \ + if (error != NULL) { \ + PyErr_Format(PyExc_OSError, "Failed to load the function %s with error: %s", #name, error); dlclose(handle); handle = NULL; return NULL; \ + } \ } \ } @@ -139,6 +141,7 @@ load_libcanberra(void) { if (PyErr_Occurred()) { PyErr_Print(); dlclose(libcanberra_handle); libcanberra_handle = NULL; + return; } if (ca_context_create(&canberra_ctx) != 0) { fprintf(stderr, "Failed to create libcanberra context, cannot play beep sound\n"); diff --git a/kitty/glfw-wrapper.c b/kitty/glfw-wrapper.c index f1e2fdab9..e3251bfb8 100644 --- a/kitty/glfw-wrapper.c +++ b/kitty/glfw-wrapper.c @@ -379,42 +379,61 @@ load_glfw(const char* path) { if (glfwGetRequiredInstanceExtensions_impl == NULL) fail("Failed to load glfw function glfwGetRequiredInstanceExtensions with error: %s", dlerror()); *(void **) (&glfwGetCocoaWindow_impl) = dlsym(handle, "glfwGetCocoaWindow"); + if (glfwGetCocoaWindow_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwHideCocoaTitlebar_impl) = dlsym(handle, "glfwHideCocoaTitlebar"); + if (glfwHideCocoaTitlebar_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwGetNSGLContext_impl) = dlsym(handle, "glfwGetNSGLContext"); + if (glfwGetNSGLContext_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwGetCocoaMonitor_impl) = dlsym(handle, "glfwGetCocoaMonitor"); + if (glfwGetCocoaMonitor_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwSetCocoaTextInputFilter_impl) = dlsym(handle, "glfwSetCocoaTextInputFilter"); + if (glfwSetCocoaTextInputFilter_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwSetCocoaFileOpenCallback_impl) = dlsym(handle, "glfwSetCocoaFileOpenCallback"); + if (glfwSetCocoaFileOpenCallback_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwSetCocoaToggleFullscreenIntercept_impl) = dlsym(handle, "glfwSetCocoaToggleFullscreenIntercept"); + if (glfwSetCocoaToggleFullscreenIntercept_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwSetApplicationShouldHandleReopen_impl) = dlsym(handle, "glfwSetApplicationShouldHandleReopen"); + if (glfwSetApplicationShouldHandleReopen_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwSetApplicationWillFinishLaunching_impl) = dlsym(handle, "glfwSetApplicationWillFinishLaunching"); + if (glfwSetApplicationWillFinishLaunching_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwGetCocoaKeyEquivalent_impl) = dlsym(handle, "glfwGetCocoaKeyEquivalent"); + if (glfwGetCocoaKeyEquivalent_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwCocoaRequestRenderFrame_impl) = dlsym(handle, "glfwCocoaRequestRenderFrame"); + if (glfwCocoaRequestRenderFrame_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwGetX11Display_impl) = dlsym(handle, "glfwGetX11Display"); + if (glfwGetX11Display_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwGetX11Window_impl) = dlsym(handle, "glfwGetX11Window"); + if (glfwGetX11Window_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwSetPrimarySelectionString_impl) = dlsym(handle, "glfwSetPrimarySelectionString"); + if (glfwSetPrimarySelectionString_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwGetPrimarySelectionString_impl) = dlsym(handle, "glfwGetPrimarySelectionString"); + if (glfwGetPrimarySelectionString_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwGetNativeKeyForName_impl) = dlsym(handle, "glfwGetNativeKeyForName"); + if (glfwGetNativeKeyForName_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwRequestWaylandFrameEvent_impl) = dlsym(handle, "glfwRequestWaylandFrameEvent"); + if (glfwRequestWaylandFrameEvent_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwDBusUserNotify_impl) = dlsym(handle, "glfwDBusUserNotify"); + if (glfwDBusUserNotify_impl == NULL) dlerror(); // clear error indicator *(void **) (&glfwDBusSetUserNotificationHandler_impl) = dlsym(handle, "glfwDBusSetUserNotificationHandler"); + if (glfwDBusSetUserNotificationHandler_impl == NULL) dlerror(); // clear error indicator return NULL; }