sendmail transition: Do not pre-generate sendmail.cf
[dragonfly.git] / contrib / sendmail-8.14 / libsm / debug.html
1 <html>
2 <head>
3     <title>libsm : Debugging and Tracing</title>
4 </head>
5 <body>
6
7 <a href="index.html">Back to libsm overview</a>
8
9 <center>
10     <h1> libsm : Debugging and Tracing </h1>
11     <br> $Id: debug.html,v 1.9 2002/02/02 16:50:56 ca Exp $
12 </center>
13
14 <h2> Introduction </h2>
15
16 The debug and trace package provides abstractions for writing trace
17 messages, and abstractions for enabling and disabling debug and
18 trace code at run time.
19
20 <p>
21 Sendmail 8.11 and earlier has a <tt>-d</tt> option which 
22 lets you turn on debug and trace code.
23 Debug categories are integers from 0 to 99, with the sole exception
24 of "ANSI", which is a named debug category.
25
26 <p>
27 The libsm debug package supports named debug categories.
28 Debug category names have the form of C identifiers.
29 For example, <tt>sm_trace_heap</tt> controls the output of trace
30 messages from the sm heap package, while <tt>sm_check_heap</tt>
31 controls the argument validity checking and memory leak detection
32 features of the sm heap package.
33
34 <p>
35 In sendmail 8.12, the <tt>-d</tt> flag is generalized
36 to support both the original style numeric categories, for backwards
37 compatibility, and the new style named categories implemented by libsm.
38 With this change,
39 "-dANSI" is implemented using a libsm named debug category.
40 You will be able to set a collection of named debug categories to
41 the same activation level by specifying a glob pattern.
42 For example,
43 <dl>
44 <dt>
45     <tt> -dANSI </tt>
46 <dd>
47     sets the named category "ANSI" to level 1,
48 <dt>
49     <tt> -dfoo_*.3 </tt>
50 <dd>
51     sets all named categories matching the glob pattern "foo_*" to level 3,
52 <dt>
53     <tt> -d0-99.1 </tt>
54 <dd>
55     sets the numeric categories 0 through 99 to level 1, and
56 <dt>
57     <tt> -dANSI,foo_*.3,0-99.1 </tt>
58 <dd>
59     does all of the above.
60 </dl>
61
62 <h2> Synopsis </h2>
63
64 <pre>
65 #include &lt;sm/debug.h&gt;
66
67 /*
68 **  abstractions for printing trace messages
69 */
70 void sm_dprintf(char *fmt, ...)
71 void sm_dflush()
72 void sm_debug_setfile(SM_FILE_T *)
73
74 /*
75 **  abstractions for setting and testing debug activation levels
76 */
77 void sm_debug_addsettings(char *settings)
78 void sm_debug_addsetting(char *pattern, int level)
79
80 typedef struct sm_debug SM_DEBUG_T;
81 SM_DEBUG_T dbg = SM_DEBUG_INITIALIZER("name", "@(#)$Debug: name - description $");
82
83 bool sm_debug_active(SM_DEBUG_T *debug, int level)
84 int  sm_debug_level(SM_DEBUG_T *debug)
85 bool sm_debug_unknown(SM_DEBUG_T *debug)
86 </pre>
87
88 <h2> Naming Conventions </h2>
89
90 All debug categories defined by libsm have names of the form <tt>sm_*</tt>.
91 Debug categories that turn on trace output have names of the form
92 <tt>*_trace_*</tt>.
93 Debug categories that turn on run time checks have names of the form
94 <tt>*_check_*</tt>.
95 Here are all of the libsm debug categories as of March 2000:
96
97 <table>
98   <tr>
99     <td>Variable name</td>
100     <td>Category name</td>
101     <td>Meaning</td>
102   </tr>
103   <tr>
104     <td>SmExpensiveAssert</td>
105     <td>sm_check_assert</td>
106     <td>enable expensive SM_ASSERT checking</td>
107   </tr>
108   <tr>
109     <td>SmExpensiveRequire</td>
110     <td>sm_check_require</td>
111     <td>enable expensive SM_REQUIRE checking</td>
112   </tr>
113   <tr>
114     <td>SmExpensiveEnsure</td>
115     <td>sm_check_ensure</td>
116     <td>enable expensive SM_ENSURE checking</td>
117   </tr>
118   <tr>
119     <td>SmHeapTrace</td>
120     <td>sm_trace_heap</td>
121     <td>trace sm_{malloc,realloc,free} calls</td>
122   </tr>
123   <tr>
124     <td>SmHeapCheck</td>
125     <td>sm_check_heap</td>
126     <td>enable checking and memory leak detection in sm_{malloc,realloc,free}</td>
127   </tr>
128 </table>
129
130 <h2> Function Reference </h2>
131
132 <dl>
133 <dt>
134 <tt> SM_DEBUG_INITIALIZER </tt>
135 <dd>
136     To create a new debug category, use the SM_DEBUG_INITIALIZER macro
137     to initialize a static variable of type SM_DEBUG_T.  For example,
138 <blockquote><pre>
139 SM_DEBUG_T ANSI_debug = SM_DEBUG_INITIALIZER("ANSI",
140             "@(#)$Debug: ANSI - enable reverse video in debug output $");
141 </pre></blockquote>
142     There is no centralized table of category names that needs to
143     be edited in order to add a new debug category.
144     The sole purpose of the second argument to SM_DEBUG_INITIALIZER
145     is to provide an easy way to find out what named debug categories
146     are present in a sendmail binary.  You can use:
147 <blockquote><pre>
148 ident /usr/sbin/sendmail | grep Debug
149 </pre></blockquote>
150     or:
151 <blockquote><pre>
152 what /usr/sbin/sendmail | grep Debug
153 </pre></blockquote>
154
155
156 <dt>
157 <tt> void sm_debug_addsetting(char *pattern, int level) </tt>
158 <dd>
159     All debug categories default to activation level 0, which means
160     no activity.
161     This function updates an internal database of debug settings,
162     setting all categories whose name matches the specified glob
163     pattern to the specified activation level.  The level argument
164     must be &gt;= 0.
165     <p>
166
167
168 <dt>
169 <tt> void sm_debug_addsettings(char *settings) </tt>
170 <dd>
171     This function is used to process the <tt>-d</tt> command line
172     option of Sendmail 9.x, and of other programs that support the
173     setting of named debug categories.  The settings argument is a
174     comma-separated list of settings; each setting is a glob pattern,
175     optionally followed by a '.' and a decimal numeral.
176     <p>
177
178
179 <dt>
180 <tt> bool sm_debug_active(SM_DEBUG_T *debug, int level) </tt>
181 <dd>
182     This macro returns <tt>true</tt> if the activation level of
183     the statically initialized debug structure <tt>debug</tt>
184     is &gt;= the specified level.
185     The test is performed very efficiently: in the most common case,
186     when the result is <tt>false</tt>, only a single comparison
187     operation is performed.
188     <p>
189     This macro performs a function call only if the debug structure has
190     an unknown activation level.  All debug structures are in this state
191     at the beginning of program execution, and after a call to
192     <tt>sm_debug_addsetting</tt>.
193     <p>
194
195
196 <dt>
197 <tt> int sm_debug_level(SM_DEBUG_T *debug) </tt>
198 <dd>
199     This macro returns the activation level of the specified debug structure.
200     The comparison
201 <blockquote><pre>
202 sm_debug_level(debug) &gt;= level
203 </pre></blockquote>
204     is slightly less efficient than, but otherwise semantically
205     equivalent to
206 <blockquote><pre>
207 sm_debug_active(debug, level)
208 </pre></blockquote>
209     <p>
210
211
212 <dt>
213 <tt> bool sm_debug_unknown(SM_DEBUG_T *debug) </tt>
214 <dd>
215     This macro returns true if the activation level of the specified
216     debug structure is unknown.
217     Here is an example of how the macro might be used:
218 <blockquote><pre>
219 if (sm_debug_unknown(&FooDebug))
220 {
221         if (sm_debug_active(&FooDebug, 1))
222         {
223                 ... perform some expensive data structure initializations
224                 ... in order to enable the "foo" debugging mechanism
225         }
226         else
227         {
228                 ... disable the "foo" debugging mechanism
229         }
230 }
231 </pre></blockquote>
232     The purpose of using <tt>sm_debug_unknown</tt> in the above example
233     is to avoid performing the expensive initializations each time through
234     the code.  So it's a performance hack.
235     A debug structure is in the "unknown" state at the beginning of
236     program execution, and after a call to <tt>sm_debug_addsetting</tt>.
237     A side effect of calling <tt>sm_debug_active</tt> is that the
238     activation level becomes known.
239     <p>
240
241
242 <dt>
243 <tt> void sm_dprintf(char *fmt, ...) </tt>
244 <dd>
245     This function is used to print a debug message.
246     The standard idiom is
247 <blockquote><pre>
248 if (sm_debug_active(&BarDebug, 1))
249         sm_dprintf("bar: about to test tensile strength of bar %d\n", i);
250 </pre></blockquote>
251     <p>
252
253 <dt>
254 <tt> void sm_dflush() </tt>
255 <dd>
256     Flush the debug output stream.
257     <p>
258
259 <dt>
260 <tt> void sm_debug_setfile(SM_FILE_T *file) </tt>
261 <dd>
262     This function lets you specify where debug output is printed.
263     By default, debug output is written to standard output.
264     <p>
265     We want to allow you to direct debug output to syslog.
266     The current plan is to provide a standard interface for
267     creating an SM_FILE_T object that writes to syslog.
268
269 </dl>
270
271 </body>
272 </html>