Skip to content

Commit d156d3a

Browse files
caesayclaude
andcommitted
Use atexit instead of DLL destructor for cleanup
DLL destructors (__attribute__((destructor))) run during DLL_PROCESS_DETACH when other DLLs may already be unloaded. Calling g_object_unref at that point crashes because GLib's vtable is gone. Switch to atexit() which runs before DLL unloading. Since we register after gsf_init() (which registers GLib's own atexit handlers), LIFO ordering ensures our cleanup runs first. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 6a3b102 commit d156d3a

1 file changed

Lines changed: 9 additions & 8 deletions

File tree

msi-interop/handle_table.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "handle_table.h"
22
#include <glib.h>
33
#include <gsf/gsf-utils.h>
4+
#include <stdlib.h>
45
#include "libmsi.h"
56

67
typedef struct {
@@ -273,6 +274,13 @@ handle_table_close_all(void)
273274
return count;
274275
}
275276

277+
static void
278+
handle_table_atexit_cleanup(void)
279+
{
280+
handle_table_close_all();
281+
gsf_shutdown();
282+
}
283+
276284
__attribute__((constructor))
277285
static void
278286
handle_table_auto_init(void)
@@ -283,12 +291,5 @@ handle_table_auto_init(void)
283291
g_type_ensure(libmsi_record_get_type());
284292
g_type_ensure(libmsi_summary_info_get_type());
285293
handle_table_init();
286-
}
287-
288-
__attribute__((destructor))
289-
static void
290-
handle_table_auto_cleanup(void)
291-
{
292-
handle_table_close_all();
293-
gsf_shutdown();
294+
atexit(handle_table_atexit_cleanup);
294295
}

0 commit comments

Comments
 (0)