2 .TH trace 3 "21 October 1999" "Straylight/Edgeware" "mLib utilities library"
4 trace \- configurable tracing output
17 .B "#include <mLib/trace.h>"
19 .BI "void trace(unsigned " l ", const char *" f ", ...);"
20 .ta \w'\fBvoid trace_block('u
21 .BI "void trace_block(unsigned " l ", const char *" s ,
22 .BI " const void *" b ", size_t " sz );
24 .BI "void trace_on(FILE *" fp ", unsigned " l );
25 .ta \w'\fBvoid trace_custom('u +\w'\fBvoid (*\,\fIfunc\/\fB)('u
26 .BI "void trace_custom(void (*" func ")(const char *" buf ,
27 .BI " size_t " sz ", void *" v ),
29 .BI "void trace_level(unsigned " l );
30 .BI "unsigned tracing(void);"
32 .ta \w'\fBunsigned traceopt('u
33 .BI "unsigned traceopt(const trace_opt *" t ", const char *" p ,
34 .BI " unsigned " f ", unsigned " bad );
36 .BI T( statements\fR... )
37 .BI "IF_TRACING(unsigned " l ", " statements\fR... )
42 header declares some functions and macros for handling trace output.
43 The emphasis for this system is primarily on user configurability of
44 what gets traced rather than where the output goes. That's a project
47 Each trace message is assigned a
49 by the programmer. A tracing level is set during program
50 initialization, usually by the user. A trace message is output if there
51 is a trace destination set, and the result of a bitwise AND between the
52 message level and the overall tracing level is nonzero. The idea is
53 that the programmer assigns a different bit to each group of trace
54 messages, and allows a user to select which ones are wanted.
55 .SS "Producing trace output"
58 It is passed an integer message level and a
60 format string together with arguments for the placeholders and emits the
65 formats an arbitrary block of memory as a hex dump. The arguments are,
66 in order, the message level, a pointer to the header string for the hex
67 dump, the base address of the block to dump, and the size of the block
69 .SS "Configuring trace output"
70 The tracing destination is set with the function
74 stream and a trace level to set. The stream may be null to disable
75 tracing completely (which is the default). The trace level may be set
78 which takes the new level as its single argument. The function
80 returns the current trace level, or zero if there is no trace
83 For more advanced programs, a custom output function may be provided by
85 and passing a function which will write a buffer of data somewhere
87 .SS "Parsing user trace options"
90 may be used to allow a user to set the trace level. It is passed a
91 table describing the available trace level bits, and some other
92 information, and returns a new trace level. The table consists of a
95 structures, each of which describes a bit or selection of bits which may
96 be controlled. The structure contains the following members, in order:
99 The character used to select this bit or collection of bits.
102 The level bits for this option.
104 .B "const char *help;"
105 A help string describing this option.
107 The table is terminated by an entry whose
116 Pointer to the trace options table.
119 Pointer to the user's option string.
122 The default trace options, or the previously-set options.
125 A bitmask of level bits which should be disallowed.
129 is a null pointer or contains only a
131 character, a help message is printed and the default is returned. Only
132 trace options which contain non-bad bits are displayed. Otherwise the
133 string contains option characters together with
137 which respectively turn on or off the following options; the default is
138 to turn options on. Again, only options which contain non-bad bits are
141 The `bad bit' mechanism is provided for setuid programs which in their
142 normal configuration deal with privileged information which mustn't be
143 given out to users. However, if run by someone with appropriate
144 privilege such options are safe and may be useful for debugging. The
147 mask to prevent access to secret information when running setuid, or to
149 .SS "Macro support for tracing"
150 The tracing macros are intended to make insertion of tracing information
151 unobtrusive and painless. If the
153 macro is defined, all of the tracing macros are disabled and generate no
154 code; otherwise they do their normal jobs.
158 macro simply expands to its argument. It may be wrapped around small
159 pieces of code which is only needed when compiling with tracing
160 enabled. (Larger blocks, of course, should use
161 .RB ` "#ifndef NTRACE" '/` #endif '
162 pairs for clarity's sake.)
164 For slightly larger code chunks which do some processing to generate
167 macro is useful. Its first argument is a message level; if the trace
168 level is set such that the message will be printed, the code in the
169 second argument is executed. If code is being compiled without tracing,
170 of course, the entire contents of the macro is ignored.
174 Mark Wooding, <mdw@distorted.org.uk>