mirror of https://github.com/openssl/openssl.git
				
				
				
			
		
			
				
	
	
		
			330 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			330 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
=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 engine modules
 | 
						|
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
 |