Commit | Line | Data |
---|---|---|
6a5671e4 DG |
1 | RFC - Testpoint mechanism\r |
2 | \r | |
3 | Author: Christian Babeux <christian.babeux@efficios.com>\r | |
4 | \r | |
5 | Contributors:\r | |
6 | * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>\r | |
7 | \r | |
8 | Version:\r | |
9 | - v0.1: 11/09/2012\r | |
10 | * Initial proposal\r | |
11 | \r | |
12 | Motivation\r | |
13 | ----------\r | |
14 | \r | |
15 | The main goal behind the testpoint mechanism is to be able to test and\r | |
16 | validate failure cases in different portion of the LTTng codebase. It\r | |
17 | could also be used by developers as a debugging aid.\r | |
18 | \r | |
19 | By injecting code at runtime in the lttng daemons/processes/executables,\r | |
20 | we can painlessly trigger faulty behavior, test errors paths or even\r | |
21 | reproduce race conditions by introducing or exacerbating delays between\r | |
22 | threads.\r | |
23 | \r | |
24 | Requirements\r | |
25 | ------------\r | |
26 | \r | |
27 | The testpoint mechanism should be able to be triggered via scripts to\r | |
28 | automate testing efforts.\r | |
29 | \r | |
30 | Ideally, the testpoint mechanism should *NOT* incur a significant\r | |
31 | performance hit if we want to leave it always on, in a similar fashion\r | |
32 | to the assert() macros.\r | |
33 | \r | |
34 | By leaving it always on, any user is able to use our tests and validate\r | |
35 | the behavior of his installation via a simple 'make check' execution.\r | |
36 | \r | |
37 | Proposed solution\r | |
38 | -----------------\r | |
39 | \r | |
40 | This patch introduce two new macros: TESTPOINT_DECL(name)\r | |
41 | and testpoint(name).\r | |
42 | \r | |
43 | Here a quick example that shows how to use the testpoint mechanism:\r | |
44 | \r | |
45 | file: main.c\r | |
46 | #include <stdio.h>\r | |
47 | #include <common/testpoint/testpoint/testpoint.h>\r | |
48 | \r | |
49 | /* Testpoint declaration */\r | |
50 | TESTPOINT_DECL(interesting_function)\r | |
51 | \r | |
52 | void interesting_function(void)\r | |
53 | {\r | |
54 | testpoint(interesting_function);\r | |
55 | /* Some processing that can fail */\r | |
56 | ...\r | |
57 | }\r | |
58 | \r | |
59 | int main(int argc, char *argv[])\r | |
60 | {\r | |
61 | interesting_function();\r | |
62 | ...\r | |
63 | printf("End");\r | |
64 | }\r | |
65 | \r | |
66 | file: testpoint.c\r | |
67 | #include <stdio.h>\r | |
68 | void __testpoint_interesting_function(void)\r | |
69 | {\r | |
70 | printf("In testpoint of interesting function!");\r | |
71 | }\r | |
72 | \r | |
73 | Compile:\r | |
74 | gcc -o test main.c\r | |
75 | gcc -fPIC -shared -o testpoint.so testpoint.c\r | |
76 | \r | |
77 | Run:\r | |
78 | > ./test\r | |
79 | End\r | |
80 | > export LTTNG_TESTPOINT_ENABLE=1\r | |
81 | > LD_PRELOAD=testpoint.so ./test\r | |
82 | In testpoint of interesting function!\r | |
83 | End\r | |
84 | > export LTTNG_TESTPOINT_ENABLE=0\r | |
85 | > LD_PRELOAD=testpoint.so ./test\r | |
86 | End\r | |
87 | \r | |
88 | The testpoint mechanism is triggered via the preloading of a shared\r | |
89 | object containing the appropriate testpoint symbols and by setting the\r | |
90 | LTTNG_TESTPOINT_ENABLE environment variable.\r | |
91 | \r | |
92 | The check on this environment variable is done on the application\r | |
93 | startup with the help of a constructor (lttng_testpoint_check) which\r | |
94 | toggle a global state variable indicating whether or not the testpoints\r | |
95 | should be activated.\r | |
96 | \r | |
97 | When enabled, the testpoint() macro calls an underlying wrapper specific\r | |
98 | to the testpoint and simply try to lookup the testpoint symbol via a\r | |
99 | dlsym() call.\r | |
100 | \r | |
101 | When disabled, the testpoint() call will only incur an additionnal test\r | |
102 | per testpoint on a global variable. This performance 'hit' should be\r | |
103 | acceptable for production use.\r | |
104 | \r | |
105 | As stated previously, the testpoint mechanism should be *always on*. It\r | |
106 | can be explicitly disabled via CFLAGS="-DNTESTPOINT" in a way similar to\r | |
107 | NDEBUG and assert().\r |