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 tracing is enabled (see L</NOTES> below), these functions are used to 53generate 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 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 OSSL_trace_set_channel(), 68or by providing a callback routine using OSSL_trace_set_callback(). 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. 90 91OSSL_trace_begin() is used to starts a tracing section, and get the 92channel for the given I<category> in form of a BIO. 93This BIO can only be used for output. 94 95OSSL_trace_end() is used to end a tracing section. 96 97Using OSSL_trace_begin() and OSSL_trace_end() to wrap tracing sections 98is I<mandatory>. 99The result of trying to produce tracing output outside of such 100sections is undefined. 101 102=head2 Macros 103 104There are a number of convenience macros defined, to make tracing 105easy and consistent. 106 107OSSL_TRACE_BEGIN() and OSSL_TRACE_END() reserve the B<BIO> C<trc_out> and are 108used 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 116This 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 127OSSL_TRACE_CANCEL() must be used before returning from or jumping out of a 128trace 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 140This 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 155OSSL_TRACE() and OSSL_TRACE1(), OSSL_TRACE2(), ... OSSL_TRACE9() are 156so-called one-shot macros: 157 158The macro call C<OSSL_TRACE(category, text)>, produces literal text trace output. 159 160The macro call C<OSSL_TRACEn(category, format, arg1, ..., argn)> produces 161printf-style trace output with n format field arguments (n=1,...,9). 162It expands to: 163 164 OSSL_TRACE_BEGIN(category) { 165 BIO_printf(trc_out, format, arg1, ..., argN) 166 } OSSL_TRACE_END(category) 167 168Internally, all one-shot macros are implemented using a generic OSSL_TRACEV() 169macro, since C90 does not support variadic macros. This helper macro has a rather 170weird synopsis and should not be used directly. 171 172The OSSL_TRACE_ENABLED() macro can be used to conditionally execute some code 173only if a specific trace category is enabled. 174In some situations this is simpler than entering a trace section using 175OSSL_TRACE_BEGIN() and OSSL_TRACE_END(). 176For example, the code 177 178 if (OSSL_TRACE_ENABLED(TLS)) { 179 ... 180 } 181 182expands to 183 184 if (OSSL_trace_enabled(OSSL_TRACE_CATEGORY_TLS) { 185 ... 186 } 187 188=head1 NOTES 189 190If producing the trace output requires carrying out auxiliary calculations, 191this auxiliary code should be placed inside a conditional block which is 192executed only if the trace category is enabled. 193 194The most natural way to do this is to place the code inside the trace section 195itself 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 204In some cases it is more advantageous to use a simple conditional group instead 205of a trace section. This is the case if calculations and tracing happen in 206different locations of the code, or if the calculations are so time consuming 207that placing them inside a (critical) trace section would create too much 208contention. 209 210 if (OSSL_TRACE_ENABLED(TLS)) { 211 int var = do_some_auxiliary_calculation(); 212 213 OSSL_TRACE1("var = %d\n", var); 214 } 215 216Note however that premature optimization of tracing code is in general futile 217and it's better to keep the tracing code as simple as possible. 218Because most often the limiting factor for the application's speed is the time 219it takes to print the trace output, not to calculate it. 220 221=head2 Configure Tracing 222 223By default, the OpenSSL library is built with tracing disabled. To 224use the tracing functionality documented here, it is therefore 225necessary to configure and build OpenSSL with the 'enable-trace' option. 226 227When the library is built with tracing disabled: 228 229=over 4 230 231=item * 232 233The macro B<OPENSSL_NO_TRACE> is defined in F<< <openssl/opensslconf.h> >>. 234 235=item * 236 237all functions are still present, but OSSL_trace_enabled() will always 238report the categories as disabled, and all other functions will do 239nothing. 240 241=item * 242 243the convenience macros are defined to produce dead code. 244For 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 256When 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 273OSSL_trace_enabled() returns 1 if tracing for the given I<type> is 274operational and enabled, otherwise 0. 275 276OSSL_trace_begin() returns a B<BIO> pointer if the given I<type> is enabled, 277otherwise NULL. 278 279=head1 HISTORY 280 281The OpenSSL Tracing API was added in OpenSSL 3.0. 282 283=head1 COPYRIGHT 284 285Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. 286 287Licensed under the Apache License 2.0 (the "License"). You may not use 288this file except in compliance with the License. You can obtain a copy 289in the file LICENSE in the source distribution or at 290L<https://www.openssl.org/source/license.html>. 291 292=cut 293