[lttng-dev] [PATCH RFC v3 lttng-tools] New testpoint mechanism to instrument LTTng binaries for testing purpose
David Goulet
dgoulet at efficios.com
Mon Sep 17 10:51:49 EDT 2012
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
Hoy,
This looks good. However, I can _not_ merge it upstream for now. I
will at least need a testpoint library example in the git tree to test
it and make sure it does not break releases.
Cheers!
David
Christian Babeux:
> This commit introduce two new macros: TESTPOINT_DECL(name) and
> testpoint(name).
>
> Here a quick example that show how to use the testpoint mechanism:
>
> file: main.c
>
> /* Testpoint declaration */ TESTPOINT_DECL(interesting_function)
>
> void interesting_function(void) { testpoint(interesting_function);
> /* Some processing that can fail */ ... }
>
> int main(int argc, char *argv[]) { interesting_function(); ...
> printf("End"); }
>
> file: testpoint.c void __testpoint_interesting_function(void) {
> printf("In testpoint of interesting function!"); }
>
> Compile: gcc -o test main.c gcc -fPIC -shared -o testpoint.so
> testpoint.c
>
> Run:
>> ./test
> End
>> export LTTNG_TESTPOINT_ENABLE=1 LD_PRELOAD=testpoint.so ./test
> In testpoint of interesting function! End
>> export LTTNG_TESTPOINT_ENABLE=0 LD_PRELOAD=testpoint.so ./test
> End
>
> The testpoint mechanism is triggered via the preloading of a
> shared object containing the appropriate testpoint symbols and by
> setting the LTTNG_TESTPOINT_ENABLE environment variable.
>
> The check on this environment variable is done on the application
> startup with the help of a constructor (lttng_testpoint_check)
> which toggle a global state variable indicating whether or not the
> testpoints should be activated.
>
> When enabled, the testpoint() macro calls an underlying wrapper
> specific to the testpoint and simply try to lookup the testpoint
> symbol via a dlsym() call.
>
> When disabled, the testpoint() call will only incur an additionnal
> test per testpoint on a global variable. This performance 'hit'
> should be acceptable for production use.
>
> The testpoint mechanism should be *always on*. It can be
> explicitly disabled via CFLAGS="-DNTESTPOINT" in a way similar to
> NDEBUG and assert().
>
> Signed-off-by: Christian Babeux <christian.babeux at efficios.com>
> --- configure.ac | 1 + src/common/Makefile.am
> | 2 +- src/common/testpoint/Makefile.am | 6 ++++
> src/common/testpoint/testpoint.c | 64
> ++++++++++++++++++++++++++++++++++ src/common/testpoint/testpoint.h
> | 74 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 146
> insertions(+), 1 deletion(-) create mode 100644
> src/common/testpoint/Makefile.am create mode 100644
> src/common/testpoint/testpoint.c create mode 100644
> src/common/testpoint/testpoint.h
>
> diff --git a/configure.ac b/configure.ac index 7687280..8e61115
> 100644 --- a/configure.ac +++ b/configure.ac @@ -275,6 +275,7 @@
> AC_CONFIG_FILES([ src/common/sessiond-comm/Makefile
> src/common/compat/Makefile src/common/relayd/Makefile +
> src/common/testpoint/Makefile src/lib/Makefile
> src/lib/lttng-ctl/Makefile src/lib/lttng-ctl/filter/Makefile diff
> --git a/src/common/Makefile.am b/src/common/Makefile.am index
> ca48153..889b04e 100644 --- a/src/common/Makefile.am +++
> b/src/common/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS =
>
> -SUBDIRS = compat hashtable kernel-ctl sessiond-comm relayd
> kernel-consumer ust-consumer +SUBDIRS = compat hashtable kernel-ctl
> sessiond-comm relayd kernel-consumer ust-consumer testpoint
>
> AM_CFLAGS = -fno-strict-aliasing
>
> diff --git a/src/common/testpoint/Makefile.am
> b/src/common/testpoint/Makefile.am new file mode 100644 index
> 0000000..7d3df16 --- /dev/null +++
> b/src/common/testpoint/Makefile.am @@ -0,0 +1,6 @@ +AM_CPPFLAGS =
> + +noinst_LTLIBRARIES = libtestpoint.la + +libtestpoint_la_SOURCES
> = testpoint.h testpoint.c +libtestpoint_la_LIBADD = -ldl diff --git
> a/src/common/testpoint/testpoint.c
> b/src/common/testpoint/testpoint.c new file mode 100644 index
> 0000000..3d01a03 --- /dev/null +++
> b/src/common/testpoint/testpoint.c @@ -0,0 +1,64 @@ +/* + *
> Copyright (C) 2012 - Christian Babeux
> <christian.babeux at efficios.com> + * + * This program is free
> software; you can redistribute it and/or modify + * it under the
> terms of the GNU General Public License, version 2 only, + * as
> published by the Free Software Foundation. + * + * This program is
> distributed in the hope that it will be useful, but WITHOUT + * ANY
> WARRANTY; without even the implied warranty of MERCHANTABILITY or +
> * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
> License for + * more details. + * + * You should have received a
> copy of the GNU General Public License along + * with this program;
> if not, write to the Free Software Foundation, Inc., + * 51
> Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +
> +#ifndef NTESTPOINT + +#define _GNU_SOURCE /* for RTLD_DEFAULT GNU
> extension */ + +#include <dlfcn.h> /* for dlsym */ +#include
> <stdlib.h> /* for getenv */ +#include <string.h> /* for strncmp
> */ + +#include "testpoint.h" + +/* Environment variable used to
> enable the testpoints facilities. */ +static const char
> *lttng_testpoint_env_var = "LTTNG_TESTPOINT_ENABLE"; + +/*
> Testpoint toggle flag */ +int lttng_testpoint_activated; + +/* + *
> Toggle the support for testpoints on the application startup. + */
> +static void __attribute__((constructor))
> lttng_testpoint_check(void) +{ + char *testpoint_env_val = NULL; +
> + testpoint_env_val = getenv(lttng_testpoint_env_var); + if
> (testpoint_env_val != NULL + && (strncmp(testpoint_env_val,
> "1", 1) == 0)) { + lttng_testpoint_activated = 1; + } +} + +/* + *
> Lookup a symbol by name. + * + * Return the address where the
> symbol is loaded + * or NULL if the symbol was not found. + */
> +void *lttng_testpoint_lookup(const char *name) +{ + if (!name) { +
> return NULL; + } + + return dlsym(RTLD_DEFAULT, name); +} + +#endif
> /* NTESTPOINT */ + diff --git a/src/common/testpoint/testpoint.h
> b/src/common/testpoint/testpoint.h new file mode 100644 index
> 0000000..2925b0a --- /dev/null +++
> b/src/common/testpoint/testpoint.h @@ -0,0 +1,74 @@ +/* + *
> Copyright (C) 2012 - Christian Babeux
> <christian.babeux at efficios.com> + * + * This program is free
> software; you can redistribute it and/or modify + * it under the
> terms of the GNU General Public License, version 2 only, + * as
> published by the Free Software Foundation. + * + * This program is
> distributed in the hope that it will be useful, but WITHOUT + * ANY
> WARRANTY; without even the implied warranty of MERCHANTABILITY or +
> * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
> License for + * more details. + * + * You should have received a
> copy of the GNU General Public License along + * with this program;
> if not, write to the Free Software Foundation, Inc., + * 51
> Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +
> +#ifdef NTESTPOINT + +#define testpoint(name) +#define
> TESTPOINT_DECL(name) + +#else /* NTESTPOINT */ + +#include <urcu.h>
> /* for caa_likely/unlikely */ + +extern int
> lttng_testpoint_activated; + +void *lttng_testpoint_lookup(const
> char *name); + +/* + * Testpoint is only active if the global + *
> lttng_testpoint_activated flag is set. + */ +#define
> testpoint(name) \ + do { \ + if
> (caa_unlikely(lttng_testpoint_activated)) { \ +
> __testpoint_##name##_wrapper(); \ + } \ + } while (0) + +/*
> + * One wrapper per testpoint is generated. This is to keep track +
> * of the symbol lookup status and the corresponding function + *
> pointer, if any. + */ +#define _TESTPOINT_DECL(_name) \ +
> static inline void __testpoint_##_name##_wrapper(void) \ + {
> \ + static void (*tp)(void); \ + static int found; \ +
> const char *tp_name = "__testpoint_" #_name; \ + \ + if
> (tp) { \ + tp(); \ + } else { \ + if (!found) {
> \ + tp = lttng_testpoint_lookup(tp_name); \ + if (tp) { \
> + found = 1; \ + tp(); \ + } else { \ +
> found = -1; \ + } \ + } \ + } \ + } + +/*
> Testpoint declaration */ +#define TESTPOINT_DECL(name) \ +
> _TESTPOINT_DECL(name) + +#endif /* NTESTPOINT */ +
-----BEGIN PGP SIGNATURE-----
iQEcBAEBCgAGBQJQVzkBAAoJEELoaioR9I02oW8IAKePOQ5iMOVARGniB6xLtWeD
6yEc5dh+sh8kjR/Vl+of9Qi0GC/4nLzQeDes15UJgeMGK/aMl30PDtlUO0JHdYAO
HZoZpOi+TrX++4n0D7nU92XBAL6trDcMDzh+Dk+YMdVTgJiKcmZd0zXwD7wg8P5y
AaQ6ZhlKelNe/p5T2TZKTO4Vk5Pkz4tm2DiH62wkOUEhjk1OK5j2jYArKWHefoh1
lAyLHqYbq5jYH/i+c8XUsGBRlb7pvc+3fcFV26AFIxt1A9oZ33k1geHY9VDQ5vVc
fyovQjtR+OQmLFW4ifXsVb7RVSJCEosjlYnjK0LkyKEyb7DwjALwxArPNYy5i1E=
=42G8
-----END PGP SIGNATURE-----
More information about the lttng-dev
mailing list