[lttng-dev] [RFC PATCH lttng-ust] Add tracepoint_disable_destructors()

Mathieu Desnoyers mathieu.desnoyers at efficios.com
Thu Mar 10 22:58:35 UTC 2016


----- On Mar 10, 2016, at 9:44 AM, Mathieu Desnoyers mathieu.desnoyers at efficios.com wrote:

> Calling this function from an instrumented program allows disabling
> tracepoint destructors. This allows threads to continue calling
> tracepoint code even after the tracepoint destructors have run. This is
> needed for applications that exit without joining all their threads.
> 
> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
> CC: Jeffrey Chen <cpthk at live.com>
> ---
> include/lttng/tracepoint.h | 19 +++++++++++++++++--
> 1 file changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/include/lttng/tracepoint.h b/include/lttng/tracepoint.h
> index 16348b8..bcd8d67 100644
> --- a/include/lttng/tracepoint.h
> +++ b/include/lttng/tracepoint.h
> @@ -227,6 +227,21 @@ struct lttng_ust_tracepoint_dlopen {
> 
> extern struct lttng_ust_tracepoint_dlopen tracepoint_dlopen;
> 
> +/* Disable tracepoint destructors. */
> +int __tracepoints__disable_destructors __attribute__((weak));
> +
> +/*
> + * Programs that have threads that survive after they exit, and
> + * therefore call library destructors, should disable the tracepoint
> + * destructors by calling tracepoint_disable_destructors(). This will
> + * leak the tracepoint instrumentation library shared object, leaving
> + * its teardown to the operating system process teardown.
> + */
> +static inline void tracepoint_disable_destructors(void)
> +{
> +	__tracepoints__disable_destructors = 1;
> +}
> +
> #if defined(TRACEPOINT_DEFINE) || defined(TRACEPOINT_CREATE_PROBES)
> 
> /*
> @@ -299,7 +314,7 @@ __tracepoints__destroy(void)
> {
> 	int ret;
> 
> -	if (--__tracepoint_registered)
> +	if (--__tracepoint_registered || __tracepoints__disable_destructors)
> 		return;
> 	if (tracepoint_dlopen.liblttngust_handle && !__tracepoint_ptrs_registered) {
> 		ret = dlclose(tracepoint_dlopen.liblttngust_handle);
> @@ -402,7 +417,7 @@ __tracepoints__ptrs_destroy(void)
> {
> 	int ret;
> 
> -	if (--__tracepoint_ptrs_registered)
> +	if (--__tracepoint_ptrs_registered || __tracepoints__disable_destructors)
> 		return;
> 	if (tracepoint_dlopen.tracepoint_unregister_lib)
> 		tracepoint_dlopen.tracepoint_unregister_lib(__start___tracepoints_ptrs);

We could probably let the library unregister itself even if the
destructors are disabled: it will unregister all tracepoint callsites
associated with that library, which appears to be a cleaner teardown.
It would only leave the tracepoint_dlopen structure content in place,
and leak the lttng-ust-tracepoint shared object.

I'm also wondering if leaking this shared object should become the
default behavior, since it appears that it makes lttng-ust more
robust against application that leave their threads running after
the destructors.

Thoughts ?

Thanks,

Mathieu

> --
> 2.1.4

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


More information about the lttng-dev mailing list