----- On Mar 10, 2016, at 9:44 AM, Mathieu Desnoyers mathieu.desnoy...@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.desnoy...@efficios.com> > CC: Jeffrey Chen <cp...@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 _______________________________________________ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev