From 3f8d53c7f00eb6082853cb2f7a208e5dd6f89d36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?= Date: Wed, 2 Sep 2015 15:21:41 +0200 Subject: [PATCH] ralloc: Use __attribute__((destructor)) instead of atexit(3) ... to free the ralloc context at program exit. On Linux, atexit(3) handlers are called when the program exits but also when a library is unloaded. The latter behavior is a Glibc extension. On systems where this extension is not supported, this causes an application to crash when, for instance, a library using ralloc is dlclosed: at program exit, the registered function is no longer in memory. For example, this happens with OpenCL applications using an ICD loader on FreeBSD. __attribute__((destructor)) fixes the problem because such handlers are called when a library is unloaded and when the program exits. --- src/util/ralloc.c | 3 ++- src/util/ralloc.h | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/util/ralloc.c b/src/util/ralloc.c index 01719c8..93933fc 100644 --- a/src/util/ralloc.c +++ b/src/util/ralloc.c @@ -311,6 +311,7 @@ ralloc_parent(const void *ptr) static void *autofree_context = NULL; +__attribute__((destructor)) static void autofree(void) { @@ -322,7 +323,7 @@ ralloc_autofree_context(void) { if (unlikely(autofree_context == NULL)) { autofree_context = ralloc_context(NULL); - atexit(autofree); + /* autofree_context is freed at program exit in autofree() above. */ } return autofree_context; } diff --git a/src/util/ralloc.h b/src/util/ralloc.h index 7587e11..d8c6cc0 100644 --- a/src/util/ralloc.h +++ b/src/util/ralloc.h @@ -249,9 +249,12 @@ void *ralloc_parent(const void *ptr); /** * Return a context whose memory will be automatically freed at program exit. * - * The first call to this function creates a context and registers a handler - * to free it using \c atexit. This may cause trouble if used in a library - * loaded with \c dlopen. + * The first call to this function creates a context. + * + * The context is freed in a function registered with + * \c __attribute__((destructor)). \c atexit is not used for this + * purpose as it would crash when used in a library loaded with + * \c dlopen. */ void *ralloc_autofree_context(void); -- 2.4.6