[Patches] avoid atexit() in talloc.c (bug #7587)

Stefan Metzmacher metze at samba.org
Wed Mar 21 07:33:28 UTC 2018


Hi,

while trying to fix the picky developer build on FreeBSD 11,
I came across https://bugzilla.samba.org/show_bug.cgi?id=7587

As we already make use of a library constructor if supported,
we should also use a destructor instead of atexit() to cleanup
the autofree memory or print a talloc report.

Please review and push:-)

Thanks!
metze
-------------- next part --------------
From fe5097eb17fc60b0b181d674b43591c3f03aaefb Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 20 Mar 2018 16:48:33 +0100
Subject: [PATCH 1/2] talloc: use a library destructor instead of atexit() if
 available

BUG: https://bugzilla.samba.org/show_bug.cgi?id=7587

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 lib/talloc/talloc.c | 72 ++++++++++++++++++++++++++++++++---------------------
 1 file changed, 44 insertions(+), 28 deletions(-)

diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c
index cd159ef..46da1ba 100644
--- a/lib/talloc/talloc.c
+++ b/lib/talloc/talloc.c
@@ -121,8 +121,12 @@ static unsigned int talloc_magic = TALLOC_MAGIC_NON_RANDOM;
    NULL
 */
 static void *null_context;
+static bool talloc_report_null;
+static bool talloc_report_null_full;
 static void *autofree_context;
 
+static void talloc_setup_atexit(void);
+
 /* used to enable fill of memory on free, which can be useful for
  * catching use after free errors when valgrind is too slow
  */
@@ -426,6 +430,41 @@ void talloc_lib_init(void)
 #warning "No __attribute__((constructor)) support found on this platform, additional talloc security measures not available"
 #endif
 
+#ifdef HAVE_DESTRUCTOR_ATTRIBUTE
+void talloc_lib_fini(void) __attribute__((destructor));
+void talloc_lib_fini(void)
+#else /* ! HAVE_DESTRUCTOR_ATTRIBUTE */
+static void talloc_lib_fini(void)
+#endif /* ! HAVE_DESTRUCTOR_ATTRIBUTE */
+{
+	TALLOC_FREE(autofree_context);
+
+	if (talloc_total_size(null_context) == 0) {
+		return;
+	}
+
+	if (talloc_report_null_full) {
+		talloc_report_full(null_context, stderr);
+	} else if (talloc_report_null) {
+		talloc_report(null_context, stderr);
+	}
+}
+
+static void talloc_setup_atexit(void)
+{
+#ifndef HAVE_DESTRUCTOR_ATTRIBUTE
+	static bool done;
+
+	if (done) {
+		return;
+	}
+
+#warning "No __attribute__((destructor)) support found on this platform, using atexit"
+	atexit(talloc_lib_fini);
+	done = true;
+#endif /* ! HAVE_DESTRUCTOR_ATTRIBUTE */
+}
+
 static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
 static void talloc_log(const char *fmt, ...)
 {
@@ -2295,26 +2334,6 @@ _PUBLIC_ void talloc_report(const void *ptr, FILE *f)
 }
 
 /*
-  report on any memory hanging off the null context
-*/
-static void talloc_report_null(void)
-{
-	if (talloc_total_size(null_context) != 0) {
-		talloc_report(null_context, stderr);
-	}
-}
-
-/*
-  report on any memory hanging off the null context
-*/
-static void talloc_report_null_full(void)
-{
-	if (talloc_total_size(null_context) != 0) {
-		talloc_report_full(null_context, stderr);
-	}
-}
-
-/*
   enable tracking of the NULL context
 */
 _PUBLIC_ void talloc_enable_null_tracking(void)
@@ -2369,7 +2388,8 @@ _PUBLIC_ void talloc_disable_null_tracking(void)
 _PUBLIC_ void talloc_enable_leak_report(void)
 {
 	talloc_enable_null_tracking();
-	atexit(talloc_report_null);
+	talloc_report_null = true;
+	talloc_setup_atexit();
 }
 
 /*
@@ -2378,7 +2398,8 @@ _PUBLIC_ void talloc_enable_leak_report(void)
 _PUBLIC_ void talloc_enable_leak_report_full(void)
 {
 	talloc_enable_null_tracking();
-	atexit(talloc_report_null_full);
+	talloc_report_null_full = true;
+	talloc_setup_atexit();
 }
 
 /*
@@ -2760,11 +2781,6 @@ static int talloc_autofree_destructor(void *ptr)
 	return 0;
 }
 
-static void talloc_autofree(void)
-{
-	talloc_free(autofree_context);
-}
-
 /*
   return a context which will be auto-freed on exit
   this is useful for reducing the noise in leak reports
@@ -2774,7 +2790,7 @@ _PUBLIC_ void *talloc_autofree_context(void)
 	if (autofree_context == NULL) {
 		autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
 		talloc_set_destructor(autofree_context, talloc_autofree_destructor);
-		atexit(talloc_autofree);
+		talloc_setup_atexit();
 	}
 	return autofree_context;
 }
-- 
1.9.1


From 75a4692618ef7092e203ce0d1ef7268f47a028c2 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 21 Mar 2018 08:24:06 +0100
Subject: [PATCH 2/2] talloc: version 2.1.12

* Fix documentation typo
* Use a library destructor instead of atexit() if available
  (bug #7587)

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 lib/talloc/ABI/pytalloc-util-2.1.12.sigs     | 16 +++++++
 lib/talloc/ABI/pytalloc-util.py3-2.1.12.sigs | 15 +++++++
 lib/talloc/ABI/talloc-2.1.12.sigs            | 65 ++++++++++++++++++++++++++++
 lib/talloc/wscript                           |  2 +-
 4 files changed, 97 insertions(+), 1 deletion(-)
 create mode 100644 lib/talloc/ABI/pytalloc-util-2.1.12.sigs
 create mode 100644 lib/talloc/ABI/pytalloc-util.py3-2.1.12.sigs
 create mode 100644 lib/talloc/ABI/talloc-2.1.12.sigs

diff --git a/lib/talloc/ABI/pytalloc-util-2.1.12.sigs b/lib/talloc/ABI/pytalloc-util-2.1.12.sigs
new file mode 100644
index 0000000..9d4d4d1
--- /dev/null
+++ b/lib/talloc/ABI/pytalloc-util-2.1.12.sigs
@@ -0,0 +1,16 @@
+_pytalloc_check_type: int (PyObject *, const char *)
+_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *)
+_pytalloc_get_ptr: void *(PyObject *)
+_pytalloc_get_type: void *(PyObject *, const char *)
+pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *)
+pytalloc_BaseObject_check: int (PyObject *)
+pytalloc_BaseObject_size: size_t (void)
+pytalloc_CObject_FromTallocPtr: PyObject *(void *)
+pytalloc_Check: int (PyObject *)
+pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *)
+pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *)
+pytalloc_GetBaseObjectType: PyTypeObject *(void)
+pytalloc_GetObjectType: PyTypeObject *(void)
+pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
+pytalloc_steal: PyObject *(PyTypeObject *, void *)
+pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
diff --git a/lib/talloc/ABI/pytalloc-util.py3-2.1.12.sigs b/lib/talloc/ABI/pytalloc-util.py3-2.1.12.sigs
new file mode 100644
index 0000000..62f066f
--- /dev/null
+++ b/lib/talloc/ABI/pytalloc-util.py3-2.1.12.sigs
@@ -0,0 +1,15 @@
+_pytalloc_check_type: int (PyObject *, const char *)
+_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *)
+_pytalloc_get_ptr: void *(PyObject *)
+_pytalloc_get_type: void *(PyObject *, const char *)
+pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *)
+pytalloc_BaseObject_check: int (PyObject *)
+pytalloc_BaseObject_size: size_t (void)
+pytalloc_Check: int (PyObject *)
+pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *)
+pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *)
+pytalloc_GetBaseObjectType: PyTypeObject *(void)
+pytalloc_GetObjectType: PyTypeObject *(void)
+pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
+pytalloc_steal: PyObject *(PyTypeObject *, void *)
+pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
diff --git a/lib/talloc/ABI/talloc-2.1.12.sigs b/lib/talloc/ABI/talloc-2.1.12.sigs
new file mode 100644
index 0000000..9969ce3
--- /dev/null
+++ b/lib/talloc/ABI/talloc-2.1.12.sigs
@@ -0,0 +1,65 @@
+_talloc: void *(const void *, size_t)
+_talloc_array: void *(const void *, size_t, unsigned int, const char *)
+_talloc_free: int (void *, const char *)
+_talloc_get_type_abort: void *(const void *, const char *, const char *)
+_talloc_memdup: void *(const void *, const void *, size_t, const char *)
+_talloc_move: void *(const void *, const void *)
+_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t)
+_talloc_realloc: void *(const void *, void *, size_t, const char *)
+_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *)
+_talloc_reference_loc: void *(const void *, const void *, const char *)
+_talloc_set_destructor: void (const void *, int (*)(void *))
+_talloc_steal_loc: void *(const void *, const void *, const char *)
+_talloc_zero: void *(const void *, size_t, const char *)
+_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *)
+talloc_asprintf: char *(const void *, const char *, ...)
+talloc_asprintf_append: char *(char *, const char *, ...)
+talloc_asprintf_append_buffer: char *(char *, const char *, ...)
+talloc_autofree_context: void *(void)
+talloc_check_name: void *(const void *, const char *)
+talloc_disable_null_tracking: void (void)
+talloc_enable_leak_report: void (void)
+talloc_enable_leak_report_full: void (void)
+talloc_enable_null_tracking: void (void)
+talloc_enable_null_tracking_no_autofree: void (void)
+talloc_find_parent_byname: void *(const void *, const char *)
+talloc_free_children: void (void *)
+talloc_get_name: const char *(const void *)
+talloc_get_size: size_t (const void *)
+talloc_increase_ref_count: int (const void *)
+talloc_init: void *(const char *, ...)
+talloc_is_parent: int (const void *, const void *)
+talloc_named: void *(const void *, size_t, const char *, ...)
+talloc_named_const: void *(const void *, size_t, const char *)
+talloc_parent: void *(const void *)
+talloc_parent_name: const char *(const void *)
+talloc_pool: void *(const void *, size_t)
+talloc_realloc_fn: void *(const void *, void *, size_t)
+talloc_reference_count: size_t (const void *)
+talloc_reparent: void *(const void *, const void *, const void *)
+talloc_report: void (const void *, FILE *)
+talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *)
+talloc_report_depth_file: void (const void *, int, int, FILE *)
+talloc_report_full: void (const void *, FILE *)
+talloc_set_abort_fn: void (void (*)(const char *))
+talloc_set_log_fn: void (void (*)(const char *))
+talloc_set_log_stderr: void (void)
+talloc_set_memlimit: int (const void *, size_t)
+talloc_set_name: const char *(const void *, const char *, ...)
+talloc_set_name_const: void (const void *, const char *)
+talloc_show_parents: void (const void *, FILE *)
+talloc_strdup: char *(const void *, const char *)
+talloc_strdup_append: char *(char *, const char *)
+talloc_strdup_append_buffer: char *(char *, const char *)
+talloc_strndup: char *(const void *, const char *, size_t)
+talloc_strndup_append: char *(char *, const char *, size_t)
+talloc_strndup_append_buffer: char *(char *, const char *, size_t)
+talloc_test_get_magic: int (void)
+talloc_total_blocks: size_t (const void *)
+talloc_total_size: size_t (const void *)
+talloc_unlink: int (const void *, void *)
+talloc_vasprintf: char *(const void *, const char *, va_list)
+talloc_vasprintf_append: char *(char *, const char *, va_list)
+talloc_vasprintf_append_buffer: char *(char *, const char *, va_list)
+talloc_version_major: int (void)
+talloc_version_minor: int (void)
diff --git a/lib/talloc/wscript b/lib/talloc/wscript
index 0afa162..6320021 100644
--- a/lib/talloc/wscript
+++ b/lib/talloc/wscript
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 APPNAME = 'talloc'
-VERSION = '2.1.11'
+VERSION = '2.1.12'
 
 
 blddir = 'bin'
-- 
1.9.1

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20180321/339d9b91/signature.sig>


More information about the samba-technical mailing list