xref: /freebsd-src/crypto/openssl/doc/man3/OSSL_trace_enabled.pod (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1*b077aed3SPierre Pronchery=pod
2*b077aed3SPierre Pronchery
3*b077aed3SPierre Pronchery=head1 NAME
4*b077aed3SPierre Pronchery
5*b077aed3SPierre ProncheryOSSL_trace_enabled, OSSL_trace_begin, OSSL_trace_end,
6*b077aed3SPierre ProncheryOSSL_TRACE_BEGIN, OSSL_TRACE_END, OSSL_TRACE_CANCEL,
7*b077aed3SPierre ProncheryOSSL_TRACE, OSSL_TRACE1, OSSL_TRACE2, OSSL_TRACE3, OSSL_TRACE4,
8*b077aed3SPierre ProncheryOSSL_TRACE5, OSSL_TRACE6, OSSL_TRACE7, OSSL_TRACE8, OSSL_TRACE9,
9*b077aed3SPierre ProncheryOSSL_TRACEV,
10*b077aed3SPierre ProncheryOSSL_TRACE_ENABLED
11*b077aed3SPierre Pronchery- OpenSSL Tracing API
12*b077aed3SPierre Pronchery
13*b077aed3SPierre Pronchery=head1 SYNOPSIS
14*b077aed3SPierre Pronchery
15*b077aed3SPierre Pronchery=for openssl generic
16*b077aed3SPierre Pronchery
17*b077aed3SPierre Pronchery #include <openssl/trace.h>
18*b077aed3SPierre Pronchery
19*b077aed3SPierre Pronchery int OSSL_trace_enabled(int category);
20*b077aed3SPierre Pronchery
21*b077aed3SPierre Pronchery BIO *OSSL_trace_begin(int category);
22*b077aed3SPierre Pronchery void OSSL_trace_end(int category, BIO *channel);
23*b077aed3SPierre Pronchery
24*b077aed3SPierre Pronchery /* trace group macros */
25*b077aed3SPierre Pronchery OSSL_TRACE_BEGIN(category) {
26*b077aed3SPierre Pronchery     ...
27*b077aed3SPierre Pronchery     if (some_error) {
28*b077aed3SPierre Pronchery         /* Leave trace group prematurely in case of an error */
29*b077aed3SPierre Pronchery         OSSL_TRACE_CANCEL(category);
30*b077aed3SPierre Pronchery         goto err;
31*b077aed3SPierre Pronchery     }
32*b077aed3SPierre Pronchery     ...
33*b077aed3SPierre Pronchery } OSSL_TRACE_END(category);
34*b077aed3SPierre Pronchery
35*b077aed3SPierre Pronchery /* one-shot trace macros */
36*b077aed3SPierre Pronchery OSSL_TRACE1(category, format, arg1)
37*b077aed3SPierre Pronchery OSSL_TRACE2(category, format, arg1, arg2)
38*b077aed3SPierre Pronchery ...
39*b077aed3SPierre Pronchery OSSL_TRACE9(category, format, arg1, ..., arg9)
40*b077aed3SPierre Pronchery
41*b077aed3SPierre Pronchery /* check whether a trace category is enabled */
42*b077aed3SPierre Pronchery if (OSSL_TRACE_ENABLED(category)) {
43*b077aed3SPierre Pronchery     ...
44*b077aed3SPierre Pronchery }
45*b077aed3SPierre Pronchery
46*b077aed3SPierre Pronchery=head1 DESCRIPTION
47*b077aed3SPierre Pronchery
48*b077aed3SPierre ProncheryThe functions described here are mainly interesting for those who provide
49*b077aed3SPierre ProncheryOpenSSL functionality, either in OpenSSL itself or in engine modules
50*b077aed3SPierre Proncheryor similar.
51*b077aed3SPierre Pronchery
52*b077aed3SPierre ProncheryIf tracing is enabled (see L</NOTES> below), these functions are used to
53*b077aed3SPierre Proncherygenerate free text tracing output.
54*b077aed3SPierre Pronchery
55*b077aed3SPierre ProncheryThe tracing output is divided into types which are enabled
56*b077aed3SPierre Proncheryindividually by the application.
57*b077aed3SPierre ProncheryThe tracing types are described in detail in
58*b077aed3SPierre ProncheryL<OSSL_trace_set_callback(3)/Trace types>.
59*b077aed3SPierre ProncheryThe fallback type B<OSSL_TRACE_CATEGORY_ALL> should I<not> be used
60*b077aed3SPierre Proncherywith the functions described here.
61*b077aed3SPierre Pronchery
62*b077aed3SPierre ProncheryTracing for a specific category is enabled if a so called
63*b077aed3SPierre ProncheryI<trace channel> is attached to it. A trace channel is simply a
64*b077aed3SPierre ProncheryBIO object to which the application can write its trace output.
65*b077aed3SPierre Pronchery
66*b077aed3SPierre ProncheryThe application has two different ways of registering a trace channel,
67*b077aed3SPierre Proncheryeither by directly providing a BIO object using OSSL_trace_set_channel(),
68*b077aed3SPierre Proncheryor by providing a callback routine using OSSL_trace_set_callback().
69*b077aed3SPierre ProncheryThe latter is wrapped internally by a dedicated BIO object, so for the
70*b077aed3SPierre Proncherytracing code both channel types are effectively indistinguishable.
71*b077aed3SPierre ProncheryWe call them a I<simple trace channel> and a I<callback trace channel>,
72*b077aed3SPierre Proncheryrespectively.
73*b077aed3SPierre Pronchery
74*b077aed3SPierre ProncheryTo produce trace output, it is necessary to obtain a pointer to the
75*b077aed3SPierre Proncherytrace channel (i.e., the BIO object) using OSSL_trace_begin(), write
76*b077aed3SPierre Proncheryto it using arbitrary BIO output routines, and finally releases the
77*b077aed3SPierre Proncherychannel using OSSL_trace_end(). The OSSL_trace_begin()/OSSL_trace_end()
78*b077aed3SPierre Proncherycalls surrounding the trace output create a group, which acts as a
79*b077aed3SPierre Proncherycritical section (guarded by a mutex) to ensure that the trace output
80*b077aed3SPierre Proncheryof different threads does not get mixed up.
81*b077aed3SPierre Pronchery
82*b077aed3SPierre ProncheryThe tracing code normally does not call OSSL_trace_{begin,end}() directly,
83*b077aed3SPierre Proncherybut rather uses a set of convenience macros, see the L</Macros> section below.
84*b077aed3SPierre Pronchery
85*b077aed3SPierre Pronchery
86*b077aed3SPierre Pronchery=head2 Functions
87*b077aed3SPierre Pronchery
88*b077aed3SPierre ProncheryOSSL_trace_enabled() can be used to check if tracing for the given
89*b077aed3SPierre ProncheryI<category> is enabled.
90*b077aed3SPierre Pronchery
91*b077aed3SPierre ProncheryOSSL_trace_begin() is used to starts a tracing section, and get the
92*b077aed3SPierre Proncherychannel for the given I<category> in form of a BIO.
93*b077aed3SPierre ProncheryThis BIO can only be used for output.
94*b077aed3SPierre Pronchery
95*b077aed3SPierre ProncheryOSSL_trace_end() is used to end a tracing section.
96*b077aed3SPierre Pronchery
97*b077aed3SPierre ProncheryUsing OSSL_trace_begin() and OSSL_trace_end() to wrap tracing sections
98*b077aed3SPierre Proncheryis I<mandatory>.
99*b077aed3SPierre ProncheryThe result of trying to produce tracing output outside of such
100*b077aed3SPierre Proncherysections is undefined.
101*b077aed3SPierre Pronchery
102*b077aed3SPierre Pronchery=head2 Macros
103*b077aed3SPierre Pronchery
104*b077aed3SPierre ProncheryThere are a number of convenience macros defined, to make tracing
105*b077aed3SPierre Proncheryeasy and consistent.
106*b077aed3SPierre Pronchery
107*b077aed3SPierre ProncheryOSSL_TRACE_BEGIN() and OSSL_TRACE_END() reserve the B<BIO> C<trc_out> and are
108*b077aed3SPierre Proncheryused as follows to wrap a trace section:
109*b077aed3SPierre Pronchery
110*b077aed3SPierre Pronchery OSSL_TRACE_BEGIN(TLS) {
111*b077aed3SPierre Pronchery
112*b077aed3SPierre Pronchery     BIO_fprintf(trc_out, ... );
113*b077aed3SPierre Pronchery
114*b077aed3SPierre Pronchery } OSSL_TRACE_END(TLS);
115*b077aed3SPierre Pronchery
116*b077aed3SPierre ProncheryThis will normally expand to:
117*b077aed3SPierre Pronchery
118*b077aed3SPierre Pronchery do {
119*b077aed3SPierre Pronchery     BIO *trc_out = OSSL_trace_begin(OSSL_TRACE_CATEGORY_TLS);
120*b077aed3SPierre Pronchery     if (trc_out != NULL) {
121*b077aed3SPierre Pronchery         ...
122*b077aed3SPierre Pronchery         BIO_fprintf(trc_out, ...);
123*b077aed3SPierre Pronchery     }
124*b077aed3SPierre Pronchery     OSSL_trace_end(OSSL_TRACE_CATEGORY_TLS, trc_out);
125*b077aed3SPierre Pronchery } while (0);
126*b077aed3SPierre Pronchery
127*b077aed3SPierre ProncheryOSSL_TRACE_CANCEL() must be used before returning from or jumping out of a
128*b077aed3SPierre Proncherytrace section:
129*b077aed3SPierre Pronchery
130*b077aed3SPierre Pronchery OSSL_TRACE_BEGIN(TLS) {
131*b077aed3SPierre Pronchery
132*b077aed3SPierre Pronchery     if (some_error) {
133*b077aed3SPierre Pronchery         OSSL_TRACE_CANCEL(TLS);
134*b077aed3SPierre Pronchery         goto err;
135*b077aed3SPierre Pronchery     }
136*b077aed3SPierre Pronchery     BIO_fprintf(trc_out, ... );
137*b077aed3SPierre Pronchery
138*b077aed3SPierre Pronchery } OSSL_TRACE_END(TLS);
139*b077aed3SPierre Pronchery
140*b077aed3SPierre ProncheryThis will normally expand to:
141*b077aed3SPierre Pronchery
142*b077aed3SPierre Pronchery do {
143*b077aed3SPierre Pronchery     BIO *trc_out = OSSL_trace_begin(OSSL_TRACE_CATEGORY_TLS);
144*b077aed3SPierre Pronchery     if (trc_out != NULL) {
145*b077aed3SPierre Pronchery         if (some_error) {
146*b077aed3SPierre Pronchery             OSSL_trace_end(OSSL_TRACE_CATEGORY_TLS, trc_out);
147*b077aed3SPierre Pronchery             goto err;
148*b077aed3SPierre Pronchery         }
149*b077aed3SPierre Pronchery         BIO_fprintf(trc_out, ... );
150*b077aed3SPierre Pronchery     }
151*b077aed3SPierre Pronchery     OSSL_trace_end(OSSL_TRACE_CATEGORY_TLS, trc_out);
152*b077aed3SPierre Pronchery } while (0);
153*b077aed3SPierre Pronchery
154*b077aed3SPierre Pronchery
155*b077aed3SPierre ProncheryOSSL_TRACE() and OSSL_TRACE1(), OSSL_TRACE2(), ... OSSL_TRACE9() are
156*b077aed3SPierre Proncheryso-called one-shot macros:
157*b077aed3SPierre Pronchery
158*b077aed3SPierre ProncheryThe macro call C<OSSL_TRACE(category, text)>, produces literal text trace output.
159*b077aed3SPierre Pronchery
160*b077aed3SPierre ProncheryThe macro call C<OSSL_TRACEn(category, format, arg1, ..., argn)> produces
161*b077aed3SPierre Proncheryprintf-style trace output with n format field arguments (n=1,...,9).
162*b077aed3SPierre ProncheryIt expands to:
163*b077aed3SPierre Pronchery
164*b077aed3SPierre Pronchery OSSL_TRACE_BEGIN(category) {
165*b077aed3SPierre Pronchery     BIO_printf(trc_out, format, arg1, ..., argN)
166*b077aed3SPierre Pronchery } OSSL_TRACE_END(category)
167*b077aed3SPierre Pronchery
168*b077aed3SPierre ProncheryInternally, all one-shot macros are implemented using a generic OSSL_TRACEV()
169*b077aed3SPierre Proncherymacro, since C90 does not support variadic macros. This helper macro has a rather
170*b077aed3SPierre Proncheryweird synopsis and should not be used directly.
171*b077aed3SPierre Pronchery
172*b077aed3SPierre ProncheryThe OSSL_TRACE_ENABLED() macro can be used to conditionally execute some code
173*b077aed3SPierre Proncheryonly if a specific trace category is enabled.
174*b077aed3SPierre ProncheryIn some situations this is simpler than entering a trace section using
175*b077aed3SPierre ProncheryOSSL_TRACE_BEGIN() and OSSL_TRACE_END().
176*b077aed3SPierre ProncheryFor example, the code
177*b077aed3SPierre Pronchery
178*b077aed3SPierre Pronchery if (OSSL_TRACE_ENABLED(TLS)) {
179*b077aed3SPierre Pronchery     ...
180*b077aed3SPierre Pronchery }
181*b077aed3SPierre Pronchery
182*b077aed3SPierre Proncheryexpands to
183*b077aed3SPierre Pronchery
184*b077aed3SPierre Pronchery if (OSSL_trace_enabled(OSSL_TRACE_CATEGORY_TLS) {
185*b077aed3SPierre Pronchery     ...
186*b077aed3SPierre Pronchery }
187*b077aed3SPierre Pronchery
188*b077aed3SPierre Pronchery=head1 NOTES
189*b077aed3SPierre Pronchery
190*b077aed3SPierre ProncheryIf producing the trace output requires carrying out auxiliary calculations,
191*b077aed3SPierre Proncherythis auxiliary code should be placed inside a conditional block which is
192*b077aed3SPierre Proncheryexecuted only if the trace category is enabled.
193*b077aed3SPierre Pronchery
194*b077aed3SPierre ProncheryThe most natural way to do this is to place the code inside the trace section
195*b077aed3SPierre Proncheryitself because it already introduces such a conditional block.
196*b077aed3SPierre Pronchery
197*b077aed3SPierre Pronchery OSSL_TRACE_BEGIN(TLS) {
198*b077aed3SPierre Pronchery     int var = do_some_auxiliary_calculation();
199*b077aed3SPierre Pronchery
200*b077aed3SPierre Pronchery     BIO_printf(trc_out, "var = %d\n", var);
201*b077aed3SPierre Pronchery
202*b077aed3SPierre Pronchery } OSSL_TRACE_END(TLS);
203*b077aed3SPierre Pronchery
204*b077aed3SPierre ProncheryIn some cases it is more advantageous to use a simple conditional group instead
205*b077aed3SPierre Proncheryof a trace section. This is the case if calculations and tracing happen in
206*b077aed3SPierre Proncherydifferent locations of the code, or if the calculations are so time consuming
207*b077aed3SPierre Proncherythat placing them inside a (critical) trace section would create too much
208*b077aed3SPierre Proncherycontention.
209*b077aed3SPierre Pronchery
210*b077aed3SPierre Pronchery if (OSSL_TRACE_ENABLED(TLS)) {
211*b077aed3SPierre Pronchery     int var = do_some_auxiliary_calculation();
212*b077aed3SPierre Pronchery
213*b077aed3SPierre Pronchery     OSSL_TRACE1("var = %d\n", var);
214*b077aed3SPierre Pronchery }
215*b077aed3SPierre Pronchery
216*b077aed3SPierre ProncheryNote however that premature optimization of tracing code is in general futile
217*b077aed3SPierre Proncheryand it's better to keep the tracing code as simple as possible.
218*b077aed3SPierre ProncheryBecause most often the limiting factor for the application's speed is the time
219*b077aed3SPierre Proncheryit takes to print the trace output, not to calculate it.
220*b077aed3SPierre Pronchery
221*b077aed3SPierre Pronchery=head2 Configure Tracing
222*b077aed3SPierre Pronchery
223*b077aed3SPierre ProncheryBy default, the OpenSSL library is built with tracing disabled. To
224*b077aed3SPierre Proncheryuse the tracing functionality documented here, it is therefore
225*b077aed3SPierre Proncherynecessary to configure and build OpenSSL with the 'enable-trace' option.
226*b077aed3SPierre Pronchery
227*b077aed3SPierre ProncheryWhen the library is built with tracing disabled:
228*b077aed3SPierre Pronchery
229*b077aed3SPierre Pronchery=over 4
230*b077aed3SPierre Pronchery
231*b077aed3SPierre Pronchery=item *
232*b077aed3SPierre Pronchery
233*b077aed3SPierre ProncheryThe macro B<OPENSSL_NO_TRACE> is defined in F<< <openssl/opensslconf.h> >>.
234*b077aed3SPierre Pronchery
235*b077aed3SPierre Pronchery=item *
236*b077aed3SPierre Pronchery
237*b077aed3SPierre Proncheryall functions are still present, but OSSL_trace_enabled() will always
238*b077aed3SPierre Proncheryreport the categories as disabled, and all other functions will do
239*b077aed3SPierre Proncherynothing.
240*b077aed3SPierre Pronchery
241*b077aed3SPierre Pronchery=item *
242*b077aed3SPierre Pronchery
243*b077aed3SPierre Proncherythe convenience macros are defined to produce dead code.
244*b077aed3SPierre ProncheryFor example, take this example from L</Macros> section above:
245*b077aed3SPierre Pronchery
246*b077aed3SPierre Pronchery OSSL_TRACE_BEGIN(TLS) {
247*b077aed3SPierre Pronchery
248*b077aed3SPierre Pronchery     if (condition) {
249*b077aed3SPierre Pronchery         OSSL_TRACE_CANCEL(TLS);
250*b077aed3SPierre Pronchery         goto err;
251*b077aed3SPierre Pronchery     }
252*b077aed3SPierre Pronchery     BIO_fprintf(trc_out, ... );
253*b077aed3SPierre Pronchery
254*b077aed3SPierre Pronchery } OSSL_TRACE_END(TLS);
255*b077aed3SPierre Pronchery
256*b077aed3SPierre ProncheryWhen the tracing API isn't operational, that will expand to:
257*b077aed3SPierre Pronchery
258*b077aed3SPierre Pronchery do {
259*b077aed3SPierre Pronchery     BIO *trc_out = NULL;
260*b077aed3SPierre Pronchery     if (0) {
261*b077aed3SPierre Pronchery         if (condition) {
262*b077aed3SPierre Pronchery             ((void)0);
263*b077aed3SPierre Pronchery             goto err;
264*b077aed3SPierre Pronchery         }
265*b077aed3SPierre Pronchery         BIO_fprintf(trc_out, ... );
266*b077aed3SPierre Pronchery     }
267*b077aed3SPierre Pronchery } while (0);
268*b077aed3SPierre Pronchery
269*b077aed3SPierre Pronchery=back
270*b077aed3SPierre Pronchery
271*b077aed3SPierre Pronchery=head1 RETURN VALUES
272*b077aed3SPierre Pronchery
273*b077aed3SPierre ProncheryOSSL_trace_enabled() returns 1 if tracing for the given I<type> is
274*b077aed3SPierre Proncheryoperational and enabled, otherwise 0.
275*b077aed3SPierre Pronchery
276*b077aed3SPierre ProncheryOSSL_trace_begin() returns a B<BIO> pointer if the given I<type> is enabled,
277*b077aed3SPierre Proncheryotherwise NULL.
278*b077aed3SPierre Pronchery
279*b077aed3SPierre Pronchery=head1 HISTORY
280*b077aed3SPierre Pronchery
281*b077aed3SPierre ProncheryThe OpenSSL Tracing API was added in OpenSSL 3.0.
282*b077aed3SPierre Pronchery
283*b077aed3SPierre Pronchery=head1 COPYRIGHT
284*b077aed3SPierre Pronchery
285*b077aed3SPierre ProncheryCopyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
286*b077aed3SPierre Pronchery
287*b077aed3SPierre ProncheryLicensed under the Apache License 2.0 (the "License").  You may not use
288*b077aed3SPierre Proncherythis file except in compliance with the License.  You can obtain a copy
289*b077aed3SPierre Proncheryin the file LICENSE in the source distribution or at
290*b077aed3SPierre ProncheryL<https://www.openssl.org/source/license.html>.
291*b077aed3SPierre Pronchery
292*b077aed3SPierre Pronchery=cut
293