]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Move xmlInitThreads()/xmlCleanupThreads() calls
authorMichał Kępień <michal@isc.org>
Mon, 2 Dec 2019 15:03:23 +0000 (16:03 +0100)
committerMichał Kępień <michal@isc.org>
Mon, 2 Dec 2019 16:10:03 +0000 (17:10 +0100)
xmlInitThreads() and xmlCleanupThreads() are called from within
ns_statschannels_configure() and ns_statschannels_shutdown(),
respectively.  Both of these functions are executed by worker threads,
not the main named thread.  This causes ASAN to report memory leaks like
the following one upon shutdown (as long as named is asked to produce
any XML output over its configured statistics channels during its
lifetime):

    Direct leak of 968 byte(s) in 1 object(s) allocated from:
        #0 0x7f677c249cd8 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:153
        #1 0x7f677bc1838f in xmlGetGlobalState (/usr/lib/libxml2.so.2+0xa838f)

The data mentioned in the above report is a libxml2 state structure
stored as thread-specific data.  Such chunks of memory are automatically
released (by a destructor passed to pthread_key_create() by libxml2)
whenever a thread that allocated a given chunk exits.  However, if
xmlCleanupThreads() is called by a given thread before it exits, the
destructor will not be invoked (due to xmlCleanupThreads() calling
pthread_key_delete()) and ASAN will report a memory leak.  Thus,
xmlInitThreads() and xmlCleanupThreads() must not be called from worker
threads.  Since xmlInitThreads() must be called on Windows in order for
libxml2 to work at all, move xmlInitThreads() and xmlCleanupThreads()
calls to the main named thread (which does not produce any XML output
itself) in order to prevent the memory leak from being reported by ASAN.

(cherry picked from commit b425b5d56e7dab15484c04153fe12f740c79a3ab)

bin/named/main.c
bin/named/statschannel.c

index 8143ecf22eabeb69b448f25e0ea17c5e3d053799..1827ac4b328f54bdec00d4561648cb75c1a2c945 100644 (file)
@@ -1473,6 +1473,10 @@ main(int argc, char *argv[]) {
        setvbuf(stderr, NULL, _IOFBF, BUFSIZ);
 #endif
 
+#ifdef HAVE_LIBXML2
+       xmlInitThreads();
+#endif /* HAVE_LIBXML2 */
+
        /*
         * Record version in core image.
         * strings named.core | grep "named version:"
@@ -1600,6 +1604,10 @@ main(int argc, char *argv[]) {
 
        ns_os_shutdown();
 
+#ifdef HAVE_LIBXML2
+       xmlCleanupThreads();
+#endif /* HAVE_LIBXML2 */
+
 #ifdef HAVE_GPERFTOOLS_PROFILER
        ProfilerStop();
 #endif
index a243599ab17016b7fdeaa89e5f09174f650e58eb..6292bcb84d9daf139939a37add86d6d16d8bb6e6 100644 (file)
@@ -3282,10 +3282,6 @@ ns_statschannels_configure(ns_server_t *server, const cfg_obj_t *config,
 
        ISC_LIST_INIT(new_listeners);
 
-#ifdef HAVE_LIBXML2
-       xmlInitThreads();
-#endif /* HAVE_LIBXML2 */
-
        /*
         * Get the list of named.conf 'statistics-channels' statements.
         */
@@ -3418,10 +3414,6 @@ ns_statschannels_shutdown(ns_server_t *server) {
                ISC_LIST_UNLINK(server->statschannels, listener, link);
                shutdown_listener(listener);
        }
-
-#ifdef HAVE_LIBXML2
-       xmlCleanupThreads();
-#endif /* HAVE_LIBXML2 */
 }
 
 isc_result_t