Commit | Line | Data |
---|---|---|
5e0cbfb0 PP |
1 | --- |
2 | id: probing-the-application-source-code | |
3 | --- | |
4 | ||
5 | Once tracepoints are properly defined within a tracepoint provider, | |
6 | they may be inserted into the user application to be instrumented | |
7 | using the `tracepoint()` macro. Its first argument is the tracepoint | |
8 | provider name and its second is the tracepoint name. The next, optional | |
9 | arguments are defined by the `TP_ARGS()` part of the definition of | |
10 | the tracepoint to use. | |
11 | ||
12 | As an example, let us again take the following tracepoint definition: | |
13 | ||
14 | ~~~ c | |
15 | TRACEPOINT_EVENT( | |
16 | /* tracepoint provider name */ | |
17 | my_provider, | |
18 | ||
19 | /* tracepoint/event name */ | |
20 | my_first_tracepoint, | |
21 | ||
22 | /* list of tracepoint arguments */ | |
23 | TP_ARGS( | |
24 | int, my_integer_arg, | |
25 | char*, my_string_arg | |
26 | ), | |
27 | ||
28 | /* list of fields of eventual event */ | |
29 | TP_FIELDS( | |
30 | ctf_string(my_string_field, my_string_arg) | |
31 | ctf_integer(int, my_integer_field, my_integer_arg) | |
32 | ) | |
33 | ) | |
34 | ~~~ | |
35 | ||
36 | Assuming this is part of a file named `tp.h` which defines the tracepoint | |
37 | provider and which is included by `tp.c`, here's a complete C application | |
38 | calling this tracepoint (multiple times): | |
39 | ||
40 | ~~~ c | |
41 | #define TRACEPOINT_DEFINE | |
42 | #include "tp.h" | |
43 | ||
44 | int main(int argc, char* argv[]) | |
45 | { | |
46 | int i; | |
47 | ||
48 | tracepoint(my_provider, my_first_tracepoint, 23, "Hello, World!"); | |
49 | ||
50 | for (i = 0; i < argc; ++i) { | |
51 | tracepoint(my_provider, my_first_tracepoint, i, argv[i]); | |
52 | } | |
53 | ||
54 | return 0; | |
55 | } | |
56 | ~~~ | |
57 | ||
cd41f97c PP |
58 | For each tracepoint provider, `TRACEPOINT_DEFINE` must be defined into |
59 | exactly one translation unit (C source file) of the user application, | |
60 | before including the tracepoint provider header file. In other words, | |
61 | for a given tracepoint provider, you cannot define `TRACEPOINT_DEFINE`, | |
62 | and then include its header file in two separate C source files of | |
63 | the same application. `TRACEPOINT_DEFINE` is discussed further in | |
5e0cbfb0 PP |
64 | [Building/linking tracepoint providers and the user application](#doc-building-tracepoint-providers-and-user-application). |
65 | ||
66 | As another example, remember this definition we wrote in a previous | |
67 | section (comments are stripped): | |
68 | ||
69 | ~~~ c | |
70 | /* for struct stat */ | |
71 | #include <sys/types.h> | |
72 | #include <sys/stat.h> | |
73 | #include <unistd.h> | |
74 | ||
75 | TRACEPOINT_EVENT( | |
76 | my_provider, | |
77 | my_tracepoint, | |
78 | TP_ARGS( | |
79 | int, my_int_arg, | |
80 | char*, my_str_arg, | |
81 | struct stat*, st | |
82 | ), | |
83 | TP_FIELDS( | |
84 | ctf_integer(int, my_constant_field, 23 + 17) | |
85 | ctf_integer(int, my_int_arg_field, my_int_arg) | |
86 | ctf_integer(int, my_int_arg_field2, my_int_arg * my_int_arg) | |
87 | ctf_integer(int, sum4_field, my_str_arg[0] + my_str_arg[1] + | |
88 | my_str_arg[2] + my_str_arg[3]) | |
89 | ctf_string(my_str_arg_field, my_str_arg) | |
90 | ctf_integer_hex(off_t, size_field, st->st_size) | |
91 | ctf_float(double, size_dbl_field, (double) st->st_size) | |
92 | ctf_sequence_text(char, half_my_str_arg_field, my_str_arg, | |
93 | size_t, strlen(my_str_arg) / 2) | |
94 | ) | |
95 | ) | |
96 | ~~~ | |
97 | ||
98 | Here's an example of calling it: | |
99 | ||
100 | ~~~ c | |
101 | #define TRACEPOINT_DEFINE | |
102 | #include "tp.h" | |
103 | ||
104 | int main(void) | |
105 | { | |
106 | struct stat s; | |
107 | ||
108 | stat("/etc/fstab", &s); | |
109 | ||
110 | tracepoint(my_provider, my_tracepoint, 23, "Hello, World!", &s); | |
111 | ||
112 | return 0; | |
113 | } | |
114 | ~~~ | |
115 | ||
116 | When viewing the trace, assuming the file size of `/etc/fstab` is | |
117 | 301 bytes, the event generated by the execution of this tracepoint | |
118 | should have the following fields, in this order: | |
119 | ||
120 | ~~~ text | |
121 | my_constant_field 40 | |
122 | my_int_arg_field 23 | |
123 | my_int_arg_field2 529 | |
124 | sum4_field 389 | |
125 | my_str_arg_field "Hello, World!" | |
126 | size_field 0x12d | |
127 | size_dbl_field 301.0 | |
128 | half_my_str_arg_field "Hello," | |
129 | ~~~ |