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