1 | =pod
|
---|
2 |
|
---|
3 | =head1 NAME
|
---|
4 |
|
---|
5 | OSSL_trace_enabled, OSSL_trace_begin, OSSL_trace_end,
|
---|
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
|
---|
11 | - OpenSSL Tracing API
|
---|
12 |
|
---|
13 | =head1 SYNOPSIS
|
---|
14 |
|
---|
15 | =for openssl generic
|
---|
16 |
|
---|
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 |
|
---|
24 | /* trace group macros */
|
---|
25 | OSSL_TRACE_BEGIN(category) {
|
---|
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 | ...
|
---|
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 |
|
---|
41 | /* check whether a trace category is enabled */
|
---|
42 | if (OSSL_TRACE_ENABLED(category)) {
|
---|
43 | ...
|
---|
44 | }
|
---|
45 |
|
---|
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 |
|
---|
52 | If tracing is enabled (see L</NOTES> below), these functions are used to
|
---|
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>.
|
---|
59 | The fallback type B<OSSL_TRACE_CATEGORY_ALL> should I<not> be used
|
---|
60 | with the functions described here.
|
---|
61 |
|
---|
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 |
|
---|
86 | =head2 Functions
|
---|
87 |
|
---|
88 | OSSL_trace_enabled() can be used to check if tracing for the given
|
---|
89 | I<category> is enabled.
|
---|
90 |
|
---|
91 | OSSL_trace_begin() is used to starts a tracing section, and get the
|
---|
92 | channel for the given I<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 |
|
---|
102 | =head2 Macros
|
---|
103 |
|
---|
104 | There are a number of convenience macros defined, to make tracing
|
---|
105 | easy and consistent.
|
---|
106 |
|
---|
107 | OSSL_TRACE_BEGIN() and OSSL_TRACE_END() reserve the B<BIO> C<trc_out> and are
|
---|
108 | 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 |
|
---|
116 | This will normally expand to:
|
---|
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 | OSSL_TRACE_CANCEL() must be used before returning from or jumping out of a
|
---|
128 | trace section:
|
---|
129 |
|
---|
130 | OSSL_TRACE_BEGIN(TLS) {
|
---|
131 |
|
---|
132 | if (some_error) {
|
---|
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) {
|
---|
145 | if (some_error) {
|
---|
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 |
|
---|
154 |
|
---|
155 | OSSL_TRACE() and OSSL_TRACE1(), OSSL_TRACE2(), ... 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 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 OSSL_TRACE_ENABLED() macro can be used to conditionally execute some code
|
---|
173 | only if a specific trace category is enabled.
|
---|
174 | In some situations this is simpler than entering a trace section using
|
---|
175 | OSSL_TRACE_BEGIN() and OSSL_TRACE_END().
|
---|
176 | For example, the code
|
---|
177 |
|
---|
178 | if (OSSL_TRACE_ENABLED(TLS)) {
|
---|
179 | ...
|
---|
180 | }
|
---|
181 |
|
---|
182 | expands to
|
---|
183 |
|
---|
184 | if (OSSL_trace_enabled(OSSL_TRACE_CATEGORY_TLS) {
|
---|
185 | ...
|
---|
186 | }
|
---|
187 |
|
---|
188 | =head1 NOTES
|
---|
189 |
|
---|
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 | }
|
---|
215 |
|
---|
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.
|
---|
220 |
|
---|
221 | =head2 Configure Tracing
|
---|
222 |
|
---|
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.
|
---|
226 |
|
---|
227 | When the library is built with tracing disabled:
|
---|
228 |
|
---|
229 | =over 4
|
---|
230 |
|
---|
231 | =item *
|
---|
232 |
|
---|
233 | The macro B<OPENSSL_NO_TRACE> is defined in F<< <openssl/opensslconf.h> >>.
|
---|
234 |
|
---|
235 | =item *
|
---|
236 |
|
---|
237 | all functions are still present, but 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.
|
---|
244 | For example, take this example from L</Macros> section above:
|
---|
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 I<type> is
|
---|
274 | operational and enabled, otherwise 0.
|
---|
275 |
|
---|
276 | OSSL_trace_begin() returns a B<BIO> pointer if the given I<type> is enabled,
|
---|
277 | otherwise NULL.
|
---|
278 |
|
---|
279 | =head1 HISTORY
|
---|
280 |
|
---|
281 | The OpenSSL Tracing API was added in OpenSSL 3.0.
|
---|
282 |
|
---|
283 | =head1 COPYRIGHT
|
---|
284 |
|
---|
285 | Copyright 2019-2021 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
|
---|