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