From f701d6c4975a526e41fd1f18082b5b3805310e7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1?= =?UTF-8?q?=D1=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= Date: Wed, 24 Mar 2021 16:36:42 +0000 Subject: [PATCH 1/2] GIO W32: Pin gio DLL On Windows gio runs a thread to update appinfo at startup. If someone unloads gio (this happens when a dynamic gio module gets unloaded by a program that doesn't use gio itself), there doesn't seem to be a way to detect that until gio is already gone, and as soon as gio is gone, the thread crashes, since it tries to execute instructions that are no longer there. Holding an extra reference to gio DLL fixes this, but it also prevents gio from being unloaded, and there's no "weak references" for DLLs. So we just pin gio and acknowledge that it will never be unloaded. Fixes #2300 Fixes #2359 --- gio/gwin32appinfo.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gio/gwin32appinfo.c b/gio/gwin32appinfo.c index b1709fbba..5403225e2 100644 --- a/gio/gwin32appinfo.c +++ b/gio/gwin32appinfo.c @@ -3964,6 +3964,8 @@ gio_win32_appinfo_init (gboolean do_wait) if (g_once_init_enter (&initialized)) { + HMODULE gio_dll_extra; + url_associations_key = g_win32_registry_key_new_w (L"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations", NULL); @@ -4006,6 +4008,11 @@ gio_win32_appinfo_init (gboolean do_wait) g_atomic_int_set (&gio_win32_appinfo_update_counter, 1); /* Trigger initial tree build. Fake data pointer. */ g_thread_pool_push (gio_win32_appinfo_threadpool, (gpointer) keys_updated, NULL); + /* Increment the DLL refcount */ + GetModuleHandleExA (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN, + (const char *) gio_win32_appinfo_init, + &gio_dll_extra); + /* gio DLL cannot be unloaded now */ g_once_init_leave (&initialized, TRUE); } From 03b574ae663153707a3e9c60ea75ce92a68446e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1?= =?UTF-8?q?=D1=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= Date: Thu, 25 Mar 2021 15:20:27 +0000 Subject: [PATCH 2/2] Don't leak a handle from _g_io_win32_get_module() This call increments the DLL refcount by default and needs a flag to avoid that. --- gio/giomodule.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gio/giomodule.c b/gio/giomodule.c index ca1daf2a8..a2909a8ef 100644 --- a/gio/giomodule.c +++ b/gio/giomodule.c @@ -1120,7 +1120,8 @@ void * _g_io_win32_get_module (void) { if (!gio_dll) - GetModuleHandleExA (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + GetModuleHandleExA (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (const char *) _g_io_win32_get_module, &gio_dll); return gio_dll;