d1836466 |
1 | .\" -*-nroff-*- |
fbf20b5b |
2 | .TH trace 3 "21 October 1999" "Straylight/Edgeware" "mLib utilities library" |
d1836466 |
3 | .SH "NAME" |
4 | trace \- configurable tracing output |
5 | .\" @trace |
6 | .\" @trace_block |
7 | .\" @trace_on |
0680be67 |
8 | .\" @trace_custom |
d1836466 |
9 | .\" @trace_level |
10 | .\" @tracing |
11 | .\" @traceopt |
12 | .\" @NTRACE |
13 | .\" @T |
14 | .\" IF_TRACING |
15 | .SH "SYNOPSIS" |
16 | .nf |
17 | .B "#include <mLib/trace.h>" |
18 | |
19 | .BI "void trace(unsigned " l ", const char *" f ", ...);" |
20 | .BI "void trace_block(unsigned " l ", const char *" s , |
21 | .BI " const void *" b ", size_t " sz ); |
22 | |
23 | .BI "void trace_on(FILE *" fp ", unsigned " l ); |
0680be67 |
24 | .BI "void trace_custom(void (*" func ")(const char *" buf , |
25 | .BI " size_t " sz ", void *" v ), |
26 | .BI " void *" v ); |
d1836466 |
27 | .BI "void trace_level(unsigned " l ); |
28 | .BI "unsigned tracing(void);" |
29 | |
0680be67 |
30 | .BI "unsigned traceopt(const trace_opt *" t ", const char *" p , |
d1836466 |
31 | .BI " unsigned " f ", unsigned " bad ); |
32 | |
33 | .BI T( statements\fR... ) |
34 | .BI "IF_TRACING(unsigned " l ", " statements\fR... ) |
35 | .fi |
36 | .SH "DESCRIPTION" |
37 | The |
38 | .B <mLib/trace.h> |
39 | header declares some functions and macros for handling trace output. |
40 | The emphasis for this system is primarily on user configurability of |
41 | what gets traced rather than where the output goes. That's a project |
42 | for later. |
43 | .SS "Trace levels" |
44 | Each trace message is assigned a |
45 | .I level |
46 | by the programmer. A tracing level is set during program |
47 | initialization, usually by the user. A trace message is output if there |
48 | is a trace destination set, and the result of a bitwise AND between the |
49 | message level and the overall tracing level is nonzero. The idea is |
50 | that the programmer assigns a different bit to each group of trace |
51 | messages, and allows a user to select which ones are wanted. |
52 | .SS "Producing trace output" |
53 | The basic function is |
54 | .BR trace . |
55 | It is passed an integer message level and a |
56 | .BR printf (3)-style |
57 | format string together with arguments for the placeholders and emits the |
58 | resulting message. |
59 | .PP |
60 | The function |
61 | .B trace_block |
62 | formats an arbitrary block of memory as a hex dump. The arguments are, |
63 | in order, the message level, a pointer to the header string for the hex |
64 | dump, the base address of the block to dump, and the size of the block |
65 | in bytes. |
66 | .SS "Configuring trace output" |
67 | The tracing destination is set with the function |
68 | .BR trace_on : |
69 | it is passed a |
70 | .B stdio |
71 | stream and a trace level to set. The stream may be null to disable |
72 | tracing completely (which is the default). The trace level may be set |
73 | on its own using |
74 | .BR trace_level , |
75 | which takes the new level as its single argument. The function |
76 | .B tracing |
77 | returns the current trace level, or zero if there is no trace |
78 | destination set. |
0680be67 |
79 | .PP |
80 | For more advanced programs, a custom output function may be provided by |
81 | .B trace_custom |
82 | and passing a function which will write a buffer of data somewhere |
83 | sensible. |
d1836466 |
84 | .SS "Parsing user trace options" |
85 | The function |
86 | .B traceopt |
87 | may be used to allow a user to set the trace level. It is passed a |
88 | table describing the available trace level bits, and some other |
89 | information, and returns a new trace level. The table consists of a |
90 | number of |
91 | .B trace_opt |
92 | structures, each of which describes a bit or selection of bits which may |
93 | be controlled. The structure contains the following members, in order: |
94 | .TP |
95 | .B "char ch;" |
96 | The character used to select this bit or collection of bits. |
97 | .TP |
98 | .B "unsigned f;" |
99 | The level bits for this option. |
100 | .TP |
101 | .B "const char *help;" |
102 | A help string describing this option. |
103 | .PP |
104 | The table is terminated by an entry whose |
105 | .B ch |
106 | member is zero. |
107 | .PP |
108 | The arguments to |
109 | .B traceopt |
110 | are: |
111 | .TP |
112 | .BI "trace_opt *" t |
113 | Pointer to the trace options table. |
114 | .TP |
115 | .BI "const char *" p |
116 | Pointer to the user's option string. |
117 | .TP |
118 | .BI "unsigned " f |
119 | The default trace options, or the previously-set options. |
120 | .TP |
121 | .BI "unsigned " bad |
122 | A bitmask of level bits which should be disallowed. |
123 | .PP |
124 | If the option string |
125 | .I p |
126 | is a null pointer or contains only a |
127 | .RB ` ? ' |
128 | character, a help message is printed and the default is returned. Only |
129 | trace options which contain non-bad bits are displayed. Otherwise the |
130 | string contains option characters together with |
131 | .RB ` + ' |
132 | and |
133 | .RB ` \- ' |
134 | which respectively turn on or off the following options; the default is |
135 | to turn options on. Again, only options which contain non-bad bits are |
136 | allowed. |
137 | .PP |
138 | The `bad bit' mechanism is provided for setuid programs which in their |
139 | normal configuration deal with privileged information which mustn't be |
140 | given out to users. However, if run by someone with appropriate |
141 | privilege such options are safe and may be useful for debugging. The |
142 | program can set the |
143 | .I bad |
144 | mask to prevent access to secret information when running setuid, or to |
145 | zero when not. |
146 | .SS "Macro support for tracing" |
147 | The tracing macros are intended to make insertion of tracing information |
148 | unobtrusive and painless. If the |
149 | .B NTRACE |
150 | macro is defined, all of the tracing macros are disabled and generate no |
151 | code; otherwise they do their normal jobs. |
152 | .PP |
153 | The |
154 | .B T |
155 | macro simply expands to its argument. It may be wrapped around small |
156 | pieces of code which is only needed when compiling with tracing |
157 | enabled. (Larger blocks, of course, should use |
158 | .RB ` #ifndef NTRACE '/` #endif ' |
159 | pairs for clarity's sake.) |
160 | .PP |
161 | For slightly larger code chunks which do some processing to generate |
162 | trace output, the |
163 | .B IF_TRACING |
164 | macro is useful. Its first argument is a message level; if the trace |
165 | level is set such that the message will be printed, the code in the |
166 | second argument is executed. If code is being compiled without tracing, |
167 | of course, the entire contents of the macro is ignored. |
168 | .SH "SEE ALSO" |
169 | .BR mLib (3). |
170 | .SH "AUTHOR" |
9b5ac6ff |
171 | Mark Wooding, <mdw@distorted.org.uk> |