]>
Commit | Line | Data |
---|---|---|
0b836c21 RL |
1 | =pod |
2 | ||
3 | =head1 NAME | |
4 | ||
c37e6350 | 5 | OSSL_trace_enabled, OSSL_trace_begin, OSSL_trace_end, |
6f92692b DMSP |
6 | OSSL_TRACE_BEGIN, OSSL_TRACE_END, OSSL_TRACE_CANCEL, |
7 | OSSL_TRACE, OSSL_TRACE1, OSSL_TRACE2, OSSL_TRACE3, OSSL_TRACE4, | |
8 | OSSL_TRACE5, OSSL_TRACE6, OSSL_TRACE7, OSSL_TRACE8, OSSL_TRACE9, | |
9 | OSSL_TRACEV, | |
10 | OSSL_TRACE_ENABLED | |
0b836c21 RL |
11 | - OpenSSL Tracing API |
12 | ||
13 | =head1 SYNOPSIS | |
14 | ||
6f92692b DMSP |
15 | =for comment generic |
16 | ||
0b836c21 RL |
17 | #include <openssl/trace.h> |
18 | ||
19 | int OSSL_trace_enabled(int category); | |
20 | ||
21 | BIO *OSSL_trace_begin(int category); | |
22 | void OSSL_trace_end(int category, BIO *channel); | |
23 | ||
c37e6350 DMSP |
24 | /* trace group macros */ |
25 | OSSL_TRACE_BEGIN(category) { | |
6f92692b DMSP |
26 | ... |
27 | if (some_error) { | |
28 | /* Leave trace group prematurely in case of an error */ | |
29 | OSSL_TRACE_CANCEL(category); | |
30 | goto err; | |
31 | } | |
32 | ... | |
c37e6350 DMSP |
33 | } OSSL_TRACE_END(category); |
34 | ||
35 | /* one-shot trace macros */ | |
36 | OSSL_TRACE1(category, format, arg1) | |
37 | OSSL_TRACE2(category, format, arg1, arg2) | |
38 | ... | |
39 | OSSL_TRACE9(category, format, arg1, ..., arg9) | |
40 | ||
6f92692b DMSP |
41 | /* check whether a trace category is enabled */ |
42 | if (OSSL_TRACE_ENABLED(category)) { | |
43 | ... | |
44 | } | |
c37e6350 | 45 | |
0b836c21 RL |
46 | =head1 DESCRIPTION |
47 | ||
48 | The functions described here are mainly interesting for those who provide | |
49 | OpenSSL functionality, either in OpenSSL itself or in engine modules | |
50 | or similar. | |
51 | ||
6bc62a62 | 52 | If tracing is enabled (see L</NOTES> below), these functions are used to |
0b836c21 RL |
53 | generate free text tracing output. |
54 | ||
55 | The tracing output is divided into types which are enabled | |
56 | individually by the application. | |
57 | The tracing types are described in detail in | |
58 | L<OSSL_trace_set_callback(3)/Trace types>. | |
3a8269b3 | 59 | The fallback type C<OSSL_TRACE_CATEGORY_ALL> should I<not> be used |
0b836c21 RL |
60 | with the functions described here. |
61 | ||
c37e6350 DMSP |
62 | Tracing for a specific category is enabled if a so called |
63 | I<trace channel> is attached to it. A trace channel is simply a | |
64 | BIO object to which the application can write its trace output. | |
65 | ||
66 | The application has two different ways of registering a trace channel, | |
67 | either by directly providing a BIO object using OSSL_trace_set_channel(), | |
68 | or by providing a callback routine using OSSL_trace_set_callback(). | |
69 | The latter is wrapped internally by a dedicated BIO object, so for the | |
70 | tracing code both channel types are effectively indistinguishable. | |
71 | We call them a I<simple trace channel> and a I<callback trace channel>, | |
72 | respectively. | |
73 | ||
74 | To produce trace output, it is necessary to obtain a pointer to the | |
75 | trace channel (i.e., the BIO object) using OSSL_trace_begin(), write | |
76 | to it using arbitrary BIO output routines, and finally releases the | |
77 | channel using OSSL_trace_end(). The OSSL_trace_begin()/OSSL_trace_end() | |
78 | calls surrounding the trace output create a group, which acts as a | |
79 | critical section (guarded by a mutex) to ensure that the trace output | |
80 | of different threads does not get mixed up. | |
81 | ||
82 | The tracing code normally does not call OSSL_trace_{begin,end}() directly, | |
83 | but rather uses a set of convenience macros, see the L</Macros> section below. | |
84 | ||
85 | ||
0b836c21 RL |
86 | =head2 Functions |
87 | ||
88 | OSSL_trace_enabled() can be used to check if tracing for the given | |
89 | C<category> is enabled. | |
90 | ||
91 | OSSL_trace_begin() is used to starts a tracing section, and get the | |
92 | channel for the given C<category> in form of a BIO. | |
93 | This BIO can only be used for output. | |
94 | ||
95 | OSSL_trace_end() is used to end a tracing section. | |
96 | ||
97 | Using OSSL_trace_begin() and OSSL_trace_end() to wrap tracing sections | |
98 | is I<mandatory>. | |
99 | The result of trying to produce tracing output outside of such | |
100 | sections is undefined. | |
101 | ||
c37e6350 | 102 | =head2 Macros |
0b836c21 RL |
103 | |
104 | There are a number of convenience macros defined, to make tracing | |
105 | easy and consistent. | |
106 | ||
107 | C<OSSL_TRACE_BEGIN(category)> and C<OSSL_TRACE_END(category)> reserve | |
108 | the B<BIO> C<trc_out> and are used as follows to wrap a trace section: | |
109 | ||
110 | OSSL_TRACE_BEGIN(TLS) { | |
111 | ||
112 | BIO_fprintf(trc_out, ... ); | |
113 | ||
114 | } OSSL_TRACE_END(TLS); | |
115 | ||
c37e6350 | 116 | This will normally expand to: |
0b836c21 RL |
117 | |
118 | do { | |
119 | BIO *trc_out = OSSL_trace_begin(OSSL_TRACE_CATEGORY_TLS); | |
120 | if (trc_out != NULL) { | |
121 | ... | |
122 | BIO_fprintf(trc_out, ...); | |
123 | } | |
124 | OSSL_trace_end(OSSL_TRACE_CATEGORY_TLS, trc_out); | |
125 | } while (0); | |
126 | ||
127 | C<OSSL_TRACE_CANCEL(category)> must be used before returning from or | |
128 | jumping out of a trace section: | |
129 | ||
130 | OSSL_TRACE_BEGIN(TLS) { | |
131 | ||
6f92692b | 132 | if (some_error) { |
0b836c21 RL |
133 | OSSL_TRACE_CANCEL(TLS); |
134 | goto err; | |
135 | } | |
136 | BIO_fprintf(trc_out, ... ); | |
137 | ||
138 | } OSSL_TRACE_END(TLS); | |
139 | ||
140 | This will normally expand to: | |
141 | ||
142 | do { | |
143 | BIO *trc_out = OSSL_trace_begin(OSSL_TRACE_CATEGORY_TLS); | |
144 | if (trc_out != NULL) { | |
6f92692b | 145 | if (some_error) { |
0b836c21 RL |
146 | OSSL_trace_end(OSSL_TRACE_CATEGORY_TLS, trc_out); |
147 | goto err; | |
148 | } | |
149 | BIO_fprintf(trc_out, ... ); | |
150 | } | |
151 | OSSL_trace_end(OSSL_TRACE_CATEGORY_TLS, trc_out); | |
152 | } while (0); | |
153 | ||
c37e6350 | 154 | |
6f92692b DMSP |
155 | C<OSSL_TRACE()> and C<OSSL_TRACE1()>, C<OSSL_TRACE2()>, ... C<OSSL_TRACE9()> are |
156 | so-called one-shot macros: | |
157 | ||
158 | The macro call C<OSSL_TRACE(category, text)>, produces literal text trace output. | |
159 | ||
160 | The macro call C<OSSL_TRACEn(category, format, arg1, ..., argn)> produces | |
161 | printf-style trace output with n format field arguments (n=1,...,9). | |
162 | It expands to: | |
163 | ||
164 | OSSL_TRACE_BEGIN(category) { | |
165 | BIO_printf(trc_out, format, arg1, ..., argN) | |
166 | } OSSL_TRACE_END(category) | |
167 | ||
168 | Internally, all one-shot macros are implemented using a generic C<OSSL_TRACEV()> | |
169 | macro, since C90 does not support variadic macros. This helper macro has a rather | |
170 | weird synopsis and should not be used directly. | |
171 | ||
172 | The C<OSSL_TRACE_ENABLED(category)> macro can be used to conditionally execute | |
173 | some code only if a specific trace category is enabled. | |
174 | In some situations this is simpler than entering a trace section using | |
175 | C<OSSL_TRACE_BEGIN(category)> and C<OSSL_TRACE_END(category)>. | |
176 | For example, the code | |
177 | ||
178 | if (OSSL_TRACE_ENABLED(TLS)) { | |
179 | ... | |
180 | } | |
c37e6350 | 181 | |
6f92692b | 182 | expands to |
c37e6350 | 183 | |
6f92692b DMSP |
184 | if (OSSL_trace_enabled(OSSL_TRACE_CATEGORY_TLS) { |
185 | ... | |
186 | } | |
c37e6350 | 187 | |
0b836c21 RL |
188 | =head1 NOTES |
189 | ||
6f92692b DMSP |
190 | If producing the trace output requires carrying out auxiliary calculations, |
191 | this auxiliary code should be placed inside a conditional block which is | |
192 | executed only if the trace category is enabled. | |
193 | ||
194 | The most natural way to do this is to place the code inside the trace section | |
195 | itself because it already introduces such a conditional block. | |
196 | ||
197 | OSSL_TRACE_BEGIN(TLS) { | |
198 | int var = do_some_auxiliary_calculation(); | |
199 | ||
200 | BIO_printf(trc_out, "var = %d\n", var); | |
201 | ||
202 | } OSSL_TRACE_END(TLS); | |
203 | ||
204 | In some cases it is more advantageous to use a simple conditional group instead | |
205 | of a trace section. This is the case if calculations and tracing happen in | |
206 | different locations of the code, or if the calculations are so time consuming | |
207 | that placing them inside a (critical) trace section would create too much | |
208 | contention. | |
209 | ||
210 | if (OSSL_TRACE_ENABLED(TLS)) { | |
211 | int var = do_some_auxiliary_calculation(); | |
212 | ||
213 | OSSL_TRACE1("var = %d\n", var); | |
214 | } | |
0b836c21 | 215 | |
6f92692b DMSP |
216 | Note however that premature optimization of tracing code is in general futile |
217 | and it's better to keep the tracing code as simple as possible. | |
218 | Because most often the limiting factor for the application's speed is the time | |
219 | it takes to print the trace output, not to calculate it. | |
0b836c21 | 220 | |
6bc62a62 | 221 | =head2 Configure Tracing |
0b836c21 | 222 | |
6bc62a62 DMSP |
223 | By default, the OpenSSL library is built with tracing disabled. To |
224 | use the tracing functionality documented here, it is therefore | |
225 | necessary to configure and build OpenSSL with the 'enable-trace' option. | |
0b836c21 RL |
226 | |
227 | When the library is built with tracing disabled: | |
228 | ||
229 | =over 4 | |
230 | ||
231 | =item * | |
232 | ||
233 | The macro C<OPENSSL_NO_TRACE> is defined in C<openssl/opensslconf.h>. | |
234 | ||
235 | =item * | |
236 | ||
237 | all functions are still present, bu OSSL_trace_enabled() will always | |
238 | report the categories as disabled, and all other functions will do | |
239 | nothing. | |
240 | ||
241 | =item * | |
242 | ||
243 | the convenience macros are defined to produce dead code. | |
c37e6350 | 244 | For example, take this example from L</Macros> section above: |
0b836c21 RL |
245 | |
246 | OSSL_TRACE_BEGIN(TLS) { | |
247 | ||
248 | if (condition) { | |
249 | OSSL_TRACE_CANCEL(TLS); | |
250 | goto err; | |
251 | } | |
252 | BIO_fprintf(trc_out, ... ); | |
253 | ||
254 | } OSSL_TRACE_END(TLS); | |
255 | ||
256 | When the tracing API isn't operational, that will expand to: | |
257 | ||
258 | do { | |
259 | BIO *trc_out = NULL; | |
260 | if (0) { | |
261 | if (condition) { | |
262 | ((void)0); | |
263 | goto err; | |
264 | } | |
265 | BIO_fprintf(trc_out, ... ); | |
266 | } | |
267 | } while (0); | |
268 | ||
269 | =back | |
270 | ||
271 | =head1 RETURN VALUES | |
272 | ||
273 | OSSL_trace_enabled() returns 1 if tracing for the given B<type> is | |
274 | operational and enabled, otherwise 0. | |
275 | ||
276 | OSSL_trace_begin() returns a C<BIO *> if the given B<type> is enabled, | |
277 | otherwise C<NULL>. | |
278 | ||
279 | =head1 HISTORY | |
280 | ||
4674aaf4 | 281 | The OpenSSL Tracing API was added ino OpenSSL 3.0. |
0b836c21 RL |
282 | |
283 | =head1 COPYRIGHT | |
284 | ||
285 | Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. | |
286 | ||
287 | Licensed under the Apache License 2.0 (the "License"). You may not use | |
288 | this file except in compliance with the License. You can obtain a copy | |
289 | in the file LICENSE in the source distribution or at | |
290 | L<https://www.openssl.org/source/license.html>. | |
291 | ||
292 | =cut |