When unloading a module, lt_dlclose() may remove the module from memory. If a module unloads itself, it's not safe to call lt_dlclose() synchronously from pa_module_unload(), because the execution may return to the module code that was removed from memory. To avoid this situation, let's postpone lt_dlclose() until it's safe to call it. BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=96831 --- src/pulsecore/module.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/module.c b/src/pulsecore/module.c index 7cba3a7..ac15815 100644 --- a/src/pulsecore/module.c +++ b/src/pulsecore/module.c @@ -228,6 +228,12 @@ fail: return NULL; } +static void postponed_dlclose(pa_mainloop_api *api, void *userdata) { + lt_dlhandle dl = userdata; + + lt_dlclose(dl); +} + static void pa_module_free(pa_module *m) { pa_assert(m); pa_assert(m->core); @@ -246,7 +252,15 @@ static void pa_module_free(pa_module *m) { if (m->proplist) pa_proplist_free(m->proplist); - lt_dlclose(m->dl); + /* If a module unloads itself with pa_module_unload(), we can't call + * lt_dlclose() here, because otherwise pa_module_unload() may return to a + * code location that has been removed from memory. Therefore, let's + * postpone the lt_dlclose() call a bit. + * + * Apparently lt_dlclose() doesn't always remove the module from memory, + * but it can happen, as can be seen here: + * https://bugs.freedesktop.org/show_bug.cgi?id=96831 */ + pa_mainloop_api_once(m->core->mainloop, postponed_dlclose, m->dl); pa_hashmap_remove(m->core->modules_pending_unload, m); -- 2.9.3