mirror of https://github.com/openssl/openssl.git
				
				
				
			
		
			
				
	
	
		
			293 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			293 lines
		
	
	
		
			8.4 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_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_TRACE1(category, format, arg1)
 | |
|  OSSL_TRACE2(category, format, arg1, arg2)
 | |
|  ...
 | |
|  OSSL_TRACE9(category, format, arg1, ..., arg9)
 | |
| 
 | |
|  /* 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 tracing is enabled (see L</NOTES> 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 C<OSSL_TRACE_CATEGORY_ALL> should I<not> be used
 | |
| with the functions described here.
 | |
| 
 | |
| Tracing for a specific category is enabled 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 OSSL_trace_set_channel(),
 | |
| or by providing a callback routine using OSSL_trace_set_callback().
 | |
| 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
 | |
| C<category> is enabled.
 | |
| 
 | |
| OSSL_trace_begin() is used to starts a tracing section, and get the
 | |
| channel for the given C<category> in form of a BIO.
 | |
| This BIO can only be used for output.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| =head2 Macros
 | |
| 
 | |
| There are a number of convenience macros defined, to make tracing
 | |
| easy and consistent.
 | |
| 
 | |
| C<OSSL_TRACE_BEGIN(category)> and C<OSSL_TRACE_END(category)> reserve
 | |
| the B<BIO> C<trc_out> and are used as follows to wrap a trace section:
 | |
| 
 | |
|  OSSL_TRACE_BEGIN(TLS) {
 | |
| 
 | |
|      BIO_fprintf(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_fprintf(trc_out, ...);
 | |
|      }
 | |
|      OSSL_trace_end(OSSL_TRACE_CATEGORY_TLS, trc_out);
 | |
|  } while (0);
 | |
| 
 | |
| C<OSSL_TRACE_CANCEL(category)> 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_fprintf(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_fprintf(trc_out, ... );
 | |
|      }
 | |
|      OSSL_trace_end(OSSL_TRACE_CATEGORY_TLS, trc_out);
 | |
|  } while (0);
 | |
| 
 | |
| 
 | |
| C<OSSL_TRACE()> and C<OSSL_TRACE1()>, C<OSSL_TRACE2()>, ... C<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 C<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 C<OSSL_TRACE_ENABLED(category)> 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
 | |
| C<OSSL_TRACE_BEGIN(category)> and C<OSSL_TRACE_END(category)>.
 | |
| For example, the code
 | |
| 
 | |
|  if (OSSL_TRACE_ENABLED(TLS)) {
 | |
|      ...
 | |
|  }
 | |
| 
 | |
| expands to
 | |
| 
 | |
|  if (OSSL_trace_enabled(OSSL_TRACE_CATEGORY_TLS) {
 | |
|      ...
 | |
|  }
 | |
| 
 | |
| =head1 NOTES
 | |
| 
 | |
| 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 C<OPENSSL_NO_TRACE> is defined in C<openssl/opensslconf.h>.
 | |
| 
 | |
| =item *
 | |
| 
 | |
| all functions are still present, bu 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_fprintf(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_fprintf(trc_out, ... );
 | |
|      }
 | |
|  } while (0);
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head1 RETURN VALUES
 | |
| 
 | |
| OSSL_trace_enabled() returns 1 if tracing for the given B<type> is
 | |
| operational and enabled, otherwise 0.
 | |
| 
 | |
| OSSL_trace_begin() returns a C<BIO *> if the given B<type> is enabled,
 | |
| otherwise C<NULL>.
 | |
| 
 | |
| =head1 HISTORY
 | |
| 
 | |
| The OpenSSL Tracing API was added ino OpenSSL 3.0.
 | |
| 
 | |
| =head1 COPYRIGHT
 | |
| 
 | |
| Copyright 2019 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
 |