Skip to content
This repository was archived by the owner on May 24, 2026. It is now read-only.

Commit 81532cb

Browse files
caesayclaude
andcommitted
Skip g_object_unref during process detach to prevent shutdown crash
.NET finalizers call MsiCloseHandle during process shutdown, after GLib's type system may already be partially torn down. This causes AccessViolationException when g_object_unref tries to access the GObject vtable. Add DllMain that sets a flag on DLL_PROCESS_DETACH. When set, handle_table_close skips the g_object_unref - the OS will reclaim all memory anyway. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d156d3a commit 81532cb

1 file changed

Lines changed: 21 additions & 10 deletions

File tree

msi-interop/handle_table.c

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@
44
#include <stdlib.h>
55
#include "libmsi.h"
66

7+
#ifdef _WIN32
8+
#include <windows.h>
9+
static volatile LONG g_process_detaching = 0;
10+
11+
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
12+
{
13+
(void)hinstDLL;
14+
(void)lpvReserved;
15+
if (fdwReason == DLL_PROCESS_DETACH) {
16+
InterlockedExchange(&g_process_detaching, 1);
17+
}
18+
return TRUE;
19+
}
20+
#endif
21+
722
typedef struct {
823
GObject *obj;
924
HandleType type;
@@ -227,8 +242,12 @@ handle_table_close(MSIHANDLE handle)
227242

228243
g_mutex_unlock(&table_mutex);
229244

230-
// Unref outside the lock to avoid potential deadlocks from destroy callbacks
231-
g_object_unref(obj);
245+
#ifdef _WIN32
246+
if (!InterlockedCompareExchange(&g_process_detaching, 0, 0))
247+
#endif
248+
{
249+
g_object_unref(obj);
250+
}
232251

233252
return 0;
234253
}
@@ -274,13 +293,6 @@ handle_table_close_all(void)
274293
return count;
275294
}
276295

277-
static void
278-
handle_table_atexit_cleanup(void)
279-
{
280-
handle_table_close_all();
281-
gsf_shutdown();
282-
}
283-
284296
__attribute__((constructor))
285297
static void
286298
handle_table_auto_init(void)
@@ -291,5 +303,4 @@ handle_table_auto_init(void)
291303
g_type_ensure(libmsi_record_get_type());
292304
g_type_ensure(libmsi_summary_info_get_type());
293305
handle_table_init();
294-
atexit(handle_table_atexit_cleanup);
295306
}

0 commit comments

Comments
 (0)