| =pod |
| |
| =head1 NAME |
| |
| OSSL_trace_enabled, OSSL_trace_begin, OSSL_trace_end, |
| OSSL_TRACE_BEGIN, OSSL_TRACE_END, OSSL_TRACE_CANCEL, |
| OSSL_TRACE, OSSL_TRACE1, OSSL_TRACE2, OSSL_TRACE3, OSSL_TRACE4, |
| OSSL_TRACE5, OSSL_TRACE6, OSSL_TRACE7, OSSL_TRACE8, OSSL_TRACE9, |
| OSSL_TRACEV, |
| OSSL_TRACE_STRING, OSSL_TRACE_STRING_MAX, OSSL_trace_string, |
| OSSL_TRACE_ENABLED |
| - OpenSSL Tracing API |
| |
| =head1 SYNOPSIS |
| |
| =for openssl generic |
| |
| #include <openssl/trace.h> |
| |
| int OSSL_trace_enabled(int category); |
| |
| BIO *OSSL_trace_begin(int category); |
| void OSSL_trace_end(int category, BIO *channel); |
| |
| /* trace group macros */ |
| OSSL_TRACE_BEGIN(category) { |
| ... |
| if (some_error) { |
| /* Leave trace group prematurely in case of an error */ |
| OSSL_TRACE_CANCEL(category); |
| goto err; |
| } |
| ... |
| } OSSL_TRACE_END(category); |
| |
| /* one-shot trace macros */ |
| OSSL_TRACE(category, text) |
| OSSL_TRACE1(category, format, arg1) |
| OSSL_TRACE2(category, format, arg1, arg2) |
| ... |
| OSSL_TRACE9(category, format, arg1, ..., arg9) |
| OSSL_TRACE_STRING(category, text, full, data, len) |
| |
| #define OSSL_TRACE_STRING_MAX 80 |
| int OSSL_trace_string(BIO *out, int text, int full, |
| const unsigned char *data, size_t size); |
| |
| /* check whether a trace category is enabled */ |
| if (OSSL_TRACE_ENABLED(category)) { |
| ... |
| } |
| |
| =head1 DESCRIPTION |
| |
| The functions described here are mainly interesting for those who provide |
| OpenSSL functionality, either in OpenSSL itself or in a provider or similar. |
| |
| If the tracing facility is enabled (see L</Configure Tracing> below), |
| these functions are used to generate free text tracing output. |
| |
| The tracing output is divided into types which are enabled |
| individually by the application. |
| The tracing types are described in detail in |
| L<OSSL_trace_set_callback(3)/Trace types>. |
| The fallback type B<OSSL_TRACE_CATEGORY_ALL> should I<not> be used |
| with the functions described here. |
| |
| Tracing for a specific category is enabled at run-time if a so-called |
| I<trace channel> is attached to it. A trace channel is simply a |
| BIO object to which the application can write its trace output. |
| |
| The application has two different ways of registering a trace channel, |
| either by directly providing a BIO object using L<OSSL_trace_set_channel(3)>, |
| or by providing a callback routine using L<OSSL_trace_set_callback(3)>. |
| The latter is wrapped internally by a dedicated BIO object, so for the |
| tracing code both channel types are effectively indistinguishable. |
| We call them a I<simple trace channel> and a I<callback trace channel>, |
| respectively. |
| |
| To produce trace output, it is necessary to obtain a pointer to the |
| trace channel (i.e., the BIO object) using OSSL_trace_begin(), write |
| to it using arbitrary BIO output routines, and finally releases the |
| channel using OSSL_trace_end(). The OSSL_trace_begin()/OSSL_trace_end() |
| calls surrounding the trace output create a group, which acts as a |
| critical section (guarded by a mutex) to ensure that the trace output |
| of different threads does not get mixed up. |
| |
| The tracing code normally does not call OSSL_trace_{begin,end}() directly, |
| but rather uses a set of convenience macros, see the L</Macros> section below. |
| |
| |
| =head2 Functions |
| |
| OSSL_trace_enabled() can be used to check if tracing for the given |
| I<category> is enabled, i.e., if the tracing facility has been statically |
| enabled (see L</Configure Tracing> below) and a trace channel has been |
| registered using L<OSSL_trace_set_channel(3)> or L<OSSL_trace_set_callback(3)>. |
| |
| OSSL_trace_begin() is used to start a tracing section, |
| and get the channel for the given I<category> in form of a BIO. |
| This BIO can only be used for output. |
| The pointer returned is NULL if the category is invalid or not enabled. |
| |
| OSSL_trace_end() is used to end a tracing section. |
| |
| Using OSSL_trace_begin() and OSSL_trace_end() to wrap tracing sections |
| is I<mandatory>. |
| The result of trying to produce tracing output outside of such |
| sections is undefined. |
| |
| OSSL_trace_string() outputs I<data> of length I<size> as a string on BIO I<out>. |
| If I<text> is 0, the function masks any included control characters apart from |
| newlines and makes sure for nonempty input that the output ends with a newline. |
| Unless I<full> is nonzero, the length is limited (with a suitable warning) |
| to B<OSSL_TRACE_STRING_MAX> characters, which currently is 80. |
| |
| =head2 Macros |
| |
| There are a number of convenience macros defined, to make tracing |
| easy and consistent. |
| |
| OSSL_TRACE_BEGIN() and OSSL_TRACE_END() reserve the B<BIO> C<trc_out> and are |
| used as follows to wrap a trace section: |
| |
| OSSL_TRACE_BEGIN(TLS) { |
| |
| BIO_printf(trc_out, ... ); |
| |
| } OSSL_TRACE_END(TLS); |
| |
| This will normally expand to: |
| |
| do { |
| BIO *trc_out = OSSL_trace_begin(OSSL_TRACE_CATEGORY_TLS); |
| if (trc_out != NULL) { |
| ... |
| BIO_printf(trc_out, ...); |
| } |
| OSSL_trace_end(OSSL_TRACE_CATEGORY_TLS, trc_out); |
| } while (0); |
| |
| OSSL_TRACE_CANCEL() must be used before returning from or jumping out of a |
| trace section: |
| |
| OSSL_TRACE_BEGIN(TLS) { |
| |
| if (some_error) { |
| OSSL_TRACE_CANCEL(TLS); |
| goto err; |
| } |
| BIO_printf(trc_out, ... ); |
| |
| } OSSL_TRACE_END(TLS); |
| |
| This will normally expand to: |
| |
| do { |
| BIO *trc_out = OSSL_trace_begin(OSSL_TRACE_CATEGORY_TLS); |
| if (trc_out != NULL) { |
| if (some_error) { |
| OSSL_trace_end(OSSL_TRACE_CATEGORY_TLS, trc_out); |
| goto err; |
| } |
| BIO_printf(trc_out, ... ); |
| } |
| OSSL_trace_end(OSSL_TRACE_CATEGORY_TLS, trc_out); |
| } while (0); |
| |
| |
| OSSL_TRACE() and OSSL_TRACE1(), OSSL_TRACE2(), ... OSSL_TRACE9() are |
| so-called one-shot macros: |
| |
| The macro call C<OSSL_TRACE(category, text)>, produces literal text trace output. |
| |
| The macro call C<OSSL_TRACEn(category, format, arg1, ..., argn)> produces |
| printf-style trace output with n format field arguments (n=1,...,9). |
| It expands to: |
| |
| OSSL_TRACE_BEGIN(category) { |
| BIO_printf(trc_out, format, arg1, ..., argN); |
| } OSSL_TRACE_END(category) |
| |
| Internally, all one-shot macros are implemented using a generic OSSL_TRACEV() |
| macro, since C90 does not support variadic macros. This helper macro has a rather |
| weird synopsis and should not be used directly. |
| |
| The macro call C<OSSL_TRACE_STRING(category, text, full, data, len)> |
| outputs I<data> of length I<size> as a string |
| if tracing for the given I<category> is enabled. |
| It expands to: |
| |
| OSSL_TRACE_BEGIN(category) { |
| OSSL_trace_string(trc_out, text, full, data, len); |
| } OSSL_TRACE_END(category) |
| |
| The OSSL_TRACE_ENABLED() macro can be used to conditionally execute some code |
| only if a specific trace category is enabled. |
| In some situations this is simpler than entering a trace section using |
| OSSL_TRACE_BEGIN() and OSSL_TRACE_END(). |
| For example, the code |
| |
| if (OSSL_TRACE_ENABLED(TLS)) { |
| ... |
| } |
| |
| expands to |
| |
| if (OSSL_trace_enabled(OSSL_TRACE_CATEGORY_TLS) { |
| ... |
| } |
| |
| =head1 NOTES |
| |
| It is not needed to guard trace output function calls like |
| I<OSSL_TRACE(category, ...)> by I<OSSL_TRACE_ENABLED(category)>. |
| |
| If producing the trace output requires carrying out auxiliary calculations, |
| this auxiliary code should be placed inside a conditional block which is |
| executed only if the trace category is enabled. |
| |
| The most natural way to do this is to place the code inside the trace section |
| itself because it already introduces such a conditional block. |
| |
| OSSL_TRACE_BEGIN(TLS) { |
| int var = do_some_auxiliary_calculation(); |
| |
| BIO_printf(trc_out, "var = %d\n", var); |
| |
| } OSSL_TRACE_END(TLS); |
| |
| In some cases it is more advantageous to use a simple conditional group instead |
| of a trace section. This is the case if calculations and tracing happen in |
| different locations of the code, or if the calculations are so time consuming |
| that placing them inside a (critical) trace section would create too much |
| contention. |
| |
| if (OSSL_TRACE_ENABLED(TLS)) { |
| int var = do_some_auxiliary_calculation(); |
| |
| OSSL_TRACE1("var = %d\n", var); |
| } |
| |
| Note however that premature optimization of tracing code is in general futile |
| and it's better to keep the tracing code as simple as possible. |
| Because most often the limiting factor for the application's speed is the time |
| it takes to print the trace output, not to calculate it. |
| |
| =head2 Configure Tracing |
| |
| By default, the OpenSSL library is built with tracing disabled. To |
| use the tracing functionality documented here, it is therefore |
| necessary to configure and build OpenSSL with the 'enable-trace' option. |
| |
| When the library is built with tracing disabled: |
| |
| =over 4 |
| |
| =item * |
| |
| The macro B<OPENSSL_NO_TRACE> is defined in F<< <openssl/opensslconf.h> >>. |
| |
| =item * |
| |
| all functions are still present, but OSSL_trace_enabled() will always |
| report the categories as disabled, and all other functions will do |
| nothing. |
| |
| =item * |
| |
| the convenience macros are defined to produce dead code. |
| For example, take this example from L</Macros> section above: |
| |
| OSSL_TRACE_BEGIN(TLS) { |
| |
| if (condition) { |
| OSSL_TRACE_CANCEL(TLS); |
| goto err; |
| } |
| BIO_printf(trc_out, ... ); |
| |
| } OSSL_TRACE_END(TLS); |
| |
| When the tracing API isn't operational, that will expand to: |
| |
| do { |
| BIO *trc_out = NULL; |
| if (0) { |
| if (condition) { |
| ((void)0); |
| goto err; |
| } |
| BIO_printf(trc_out, ... ); |
| } |
| } while (0); |
| |
| =back |
| |
| =head1 RETURN VALUES |
| |
| OSSL_trace_enabled() returns 1 if tracing for the given I<type> is |
| operational and enabled, otherwise 0. |
| |
| OSSL_trace_begin() returns a B<BIO> pointer if the given I<type> is enabled, |
| otherwise NULL. |
| |
| OSSL_trace_string() returns the number of characters emitted, or -1 on error. |
| |
| =head1 SEE ALSO |
| |
| L<OSSL_trace_set_channel(3)>, L<OSSL_trace_set_callback(3)> |
| |
| =head1 HISTORY |
| |
| The OpenSSL Tracing functions were added in OpenSSL 3.0. |
| |
| OSSL_TRACE_STRING(), OSSL_TRACE_STRING_MAX, and OSSL_trace_string |
| were added in OpenSSL 3.2. |
| |
| =head1 COPYRIGHT |
| |
| Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. |
| |
| Licensed under the Apache License 2.0 (the "License"). You may not use |
| this file except in compliance with the License. You can obtain a copy |
| in the file LICENSE in the source distribution or at |
| L<https://www.openssl.org/source/license.html>. |
| |
| =cut |