190792Sgshapiro<html>
290792Sgshapiro<head>
390792Sgshapiro    <title>libsm : Debugging and Tracing</title>
490792Sgshapiro</head>
590792Sgshapiro<body>
690792Sgshapiro
790792Sgshapiro<a href="index.html">Back to libsm overview</a>
890792Sgshapiro
990792Sgshapiro<center>
1090792Sgshapiro    <h1> libsm : Debugging and Tracing </h1>
11266527Sgshapiro    <br> $Id: debug.html,v 1.9 2002-02-02 16:50:56 ca Exp $
1290792Sgshapiro</center>
1390792Sgshapiro
1490792Sgshapiro<h2> Introduction </h2>
1590792Sgshapiro
1690792SgshapiroThe debug and trace package provides abstractions for writing trace
1790792Sgshapiromessages, and abstractions for enabling and disabling debug and
1890792Sgshapirotrace code at run time.
1990792Sgshapiro
2090792Sgshapiro<p>
2190792SgshapiroSendmail 8.11 and earlier has a <tt>-d</tt> option which 
2290792Sgshapirolets you turn on debug and trace code.
2390792SgshapiroDebug categories are integers from 0 to 99, with the sole exception
2490792Sgshapiroof "ANSI", which is a named debug category.
2590792Sgshapiro
2690792Sgshapiro<p>
2790792SgshapiroThe libsm debug package supports named debug categories.
2890792SgshapiroDebug category names have the form of C identifiers.
2990792SgshapiroFor example, <tt>sm_trace_heap</tt> controls the output of trace
3090792Sgshapiromessages from the sm heap package, while <tt>sm_check_heap</tt>
3190792Sgshapirocontrols the argument validity checking and memory leak detection
3290792Sgshapirofeatures of the sm heap package.
3390792Sgshapiro
3490792Sgshapiro<p>
3590792SgshapiroIn sendmail 8.12, the <tt>-d</tt> flag is generalized
3690792Sgshapiroto support both the original style numeric categories, for backwards
3790792Sgshapirocompatibility, and the new style named categories implemented by libsm.
3890792SgshapiroWith this change,
3990792Sgshapiro"-dANSI" is implemented using a libsm named debug category.
4090792SgshapiroYou will be able to set a collection of named debug categories to
4190792Sgshapirothe same activation level by specifying a glob pattern.
4290792SgshapiroFor example,
4390792Sgshapiro<dl>
4490792Sgshapiro<dt>
4590792Sgshapiro    <tt> -dANSI </tt>
4690792Sgshapiro<dd>
4790792Sgshapiro    sets the named category "ANSI" to level 1,
4890792Sgshapiro<dt>
4990792Sgshapiro    <tt> -dfoo_*.3 </tt>
5090792Sgshapiro<dd>
5190792Sgshapiro    sets all named categories matching the glob pattern "foo_*" to level 3,
5290792Sgshapiro<dt>
5390792Sgshapiro    <tt> -d0-99.1 </tt>
5490792Sgshapiro<dd>
5590792Sgshapiro    sets the numeric categories 0 through 99 to level 1, and
5690792Sgshapiro<dt>
5790792Sgshapiro    <tt> -dANSI,foo_*.3,0-99.1 </tt>
5890792Sgshapiro<dd>
5990792Sgshapiro    does all of the above.
6090792Sgshapiro</dl>
6190792Sgshapiro
6290792Sgshapiro<h2> Synopsis </h2>
6390792Sgshapiro
6490792Sgshapiro<pre>
6590792Sgshapiro#include &lt;sm/debug.h&gt;
6690792Sgshapiro
6790792Sgshapiro/*
6890792Sgshapiro**  abstractions for printing trace messages
6990792Sgshapiro*/
7090792Sgshapirovoid sm_dprintf(char *fmt, ...)
7190792Sgshapirovoid sm_dflush()
7290792Sgshapirovoid sm_debug_setfile(SM_FILE_T *)
7390792Sgshapiro
7490792Sgshapiro/*
7590792Sgshapiro**  abstractions for setting and testing debug activation levels
7690792Sgshapiro*/
7790792Sgshapirovoid sm_debug_addsettings(char *settings)
7890792Sgshapirovoid sm_debug_addsetting(char *pattern, int level)
7990792Sgshapiro
8090792Sgshapirotypedef struct sm_debug SM_DEBUG_T;
8190792SgshapiroSM_DEBUG_T dbg = SM_DEBUG_INITIALIZER("name", "@(#)$Debug: name - description $");
8290792Sgshapiro
8390792Sgshapirobool sm_debug_active(SM_DEBUG_T *debug, int level)
8490792Sgshapiroint  sm_debug_level(SM_DEBUG_T *debug)
8590792Sgshapirobool sm_debug_unknown(SM_DEBUG_T *debug)
8690792Sgshapiro</pre>
8790792Sgshapiro
8890792Sgshapiro<h2> Naming Conventions </h2>
8990792Sgshapiro
9090792SgshapiroAll debug categories defined by libsm have names of the form <tt>sm_*</tt>.
9190792SgshapiroDebug categories that turn on trace output have names of the form
9290792Sgshapiro<tt>*_trace_*</tt>.
9390792SgshapiroDebug categories that turn on run time checks have names of the form
9490792Sgshapiro<tt>*_check_*</tt>.
9590792SgshapiroHere are all of the libsm debug categories as of March 2000:
9690792Sgshapiro
9790792Sgshapiro<table>
9890792Sgshapiro  <tr>
9990792Sgshapiro    <td>Variable name</td>
10090792Sgshapiro    <td>Category name</td>
10190792Sgshapiro    <td>Meaning</td>
10290792Sgshapiro  </tr>
10390792Sgshapiro  <tr>
10490792Sgshapiro    <td>SmExpensiveAssert</td>
10590792Sgshapiro    <td>sm_check_assert</td>
10690792Sgshapiro    <td>enable expensive SM_ASSERT checking</td>
10790792Sgshapiro  </tr>
10890792Sgshapiro  <tr>
10990792Sgshapiro    <td>SmExpensiveRequire</td>
11090792Sgshapiro    <td>sm_check_require</td>
11190792Sgshapiro    <td>enable expensive SM_REQUIRE checking</td>
11290792Sgshapiro  </tr>
11390792Sgshapiro  <tr>
11490792Sgshapiro    <td>SmExpensiveEnsure</td>
11590792Sgshapiro    <td>sm_check_ensure</td>
11690792Sgshapiro    <td>enable expensive SM_ENSURE checking</td>
11790792Sgshapiro  </tr>
11890792Sgshapiro  <tr>
11990792Sgshapiro    <td>SmHeapTrace</td>
12090792Sgshapiro    <td>sm_trace_heap</td>
12190792Sgshapiro    <td>trace sm_{malloc,realloc,free} calls</td>
12290792Sgshapiro  </tr>
12390792Sgshapiro  <tr>
12490792Sgshapiro    <td>SmHeapCheck</td>
12590792Sgshapiro    <td>sm_check_heap</td>
12690792Sgshapiro    <td>enable checking and memory leak detection in sm_{malloc,realloc,free}</td>
12790792Sgshapiro  </tr>
12890792Sgshapiro</table>
12990792Sgshapiro
13090792Sgshapiro<h2> Function Reference </h2>
13190792Sgshapiro
13290792Sgshapiro<dl>
13390792Sgshapiro<dt>
13490792Sgshapiro<tt> SM_DEBUG_INITIALIZER </tt>
13590792Sgshapiro<dd>
13690792Sgshapiro    To create a new debug category, use the SM_DEBUG_INITIALIZER macro
13790792Sgshapiro    to initialize a static variable of type SM_DEBUG_T.  For example,
13890792Sgshapiro<blockquote><pre>
13990792SgshapiroSM_DEBUG_T ANSI_debug = SM_DEBUG_INITIALIZER("ANSI",
14090792Sgshapiro	    "@(#)$Debug: ANSI - enable reverse video in debug output $");
14190792Sgshapiro</pre></blockquote>
14290792Sgshapiro    There is no centralized table of category names that needs to
14390792Sgshapiro    be edited in order to add a new debug category.
14490792Sgshapiro    The sole purpose of the second argument to SM_DEBUG_INITIALIZER
14590792Sgshapiro    is to provide an easy way to find out what named debug categories
14690792Sgshapiro    are present in a sendmail binary.  You can use:
14790792Sgshapiro<blockquote><pre>
14890792Sgshapiroident /usr/sbin/sendmail | grep Debug
14990792Sgshapiro</pre></blockquote>
15090792Sgshapiro    or:
15190792Sgshapiro<blockquote><pre>
15290792Sgshapirowhat /usr/sbin/sendmail | grep Debug
15390792Sgshapiro</pre></blockquote>
15490792Sgshapiro
15590792Sgshapiro
15690792Sgshapiro<dt>
15790792Sgshapiro<tt> void sm_debug_addsetting(char *pattern, int level) </tt>
15890792Sgshapiro<dd>
15990792Sgshapiro    All debug categories default to activation level 0, which means
16090792Sgshapiro    no activity.
16190792Sgshapiro    This function updates an internal database of debug settings,
16290792Sgshapiro    setting all categories whose name matches the specified glob
16390792Sgshapiro    pattern to the specified activation level.  The level argument
16490792Sgshapiro    must be &gt;= 0.
16590792Sgshapiro    <p>
16690792Sgshapiro
16790792Sgshapiro
16890792Sgshapiro<dt>
16990792Sgshapiro<tt> void sm_debug_addsettings(char *settings) </tt>
17090792Sgshapiro<dd>
17190792Sgshapiro    This function is used to process the <tt>-d</tt> command line
17290792Sgshapiro    option of Sendmail 9.x, and of other programs that support the
17390792Sgshapiro    setting of named debug categories.  The settings argument is a
17490792Sgshapiro    comma-separated list of settings; each setting is a glob pattern,
17590792Sgshapiro    optionally followed by a '.' and a decimal numeral.
17690792Sgshapiro    <p>
17790792Sgshapiro
17890792Sgshapiro
17990792Sgshapiro<dt>
18090792Sgshapiro<tt> bool sm_debug_active(SM_DEBUG_T *debug, int level) </tt>
18190792Sgshapiro<dd>
18290792Sgshapiro    This macro returns <tt>true</tt> if the activation level of
18390792Sgshapiro    the statically initialized debug structure <tt>debug</tt>
18490792Sgshapiro    is &gt;= the specified level.
18590792Sgshapiro    The test is performed very efficiently: in the most common case,
18690792Sgshapiro    when the result is <tt>false</tt>, only a single comparison
18790792Sgshapiro    operation is performed.
18890792Sgshapiro    <p>
18990792Sgshapiro    This macro performs a function call only if the debug structure has
19090792Sgshapiro    an unknown activation level.  All debug structures are in this state
19190792Sgshapiro    at the beginning of program execution, and after a call to
19290792Sgshapiro    <tt>sm_debug_addsetting</tt>.
19390792Sgshapiro    <p>
19490792Sgshapiro
19590792Sgshapiro
19690792Sgshapiro<dt>
19790792Sgshapiro<tt> int sm_debug_level(SM_DEBUG_T *debug) </tt>
19890792Sgshapiro<dd>
19990792Sgshapiro    This macro returns the activation level of the specified debug structure.
20090792Sgshapiro    The comparison
20190792Sgshapiro<blockquote><pre>
20290792Sgshapirosm_debug_level(debug) &gt;= level
20390792Sgshapiro</pre></blockquote>
20490792Sgshapiro    is slightly less efficient than, but otherwise semantically
20590792Sgshapiro    equivalent to
20690792Sgshapiro<blockquote><pre>
20790792Sgshapirosm_debug_active(debug, level)
20890792Sgshapiro</pre></blockquote>
20990792Sgshapiro    <p>
21090792Sgshapiro
21190792Sgshapiro
21290792Sgshapiro<dt>
21390792Sgshapiro<tt> bool sm_debug_unknown(SM_DEBUG_T *debug) </tt>
21490792Sgshapiro<dd>
21590792Sgshapiro    This macro returns true if the activation level of the specified
21690792Sgshapiro    debug structure is unknown.
21790792Sgshapiro    Here is an example of how the macro might be used:
21890792Sgshapiro<blockquote><pre>
21990792Sgshapiroif (sm_debug_unknown(&FooDebug))
22090792Sgshapiro{
22190792Sgshapiro	if (sm_debug_active(&FooDebug, 1))
22290792Sgshapiro	{
22390792Sgshapiro		... perform some expensive data structure initializations
22490792Sgshapiro		... in order to enable the "foo" debugging mechanism
22590792Sgshapiro	}
22690792Sgshapiro	else
22790792Sgshapiro	{
22890792Sgshapiro		... disable the "foo" debugging mechanism
22990792Sgshapiro	}
23090792Sgshapiro}
23190792Sgshapiro</pre></blockquote>
23290792Sgshapiro    The purpose of using <tt>sm_debug_unknown</tt> in the above example
23390792Sgshapiro    is to avoid performing the expensive initializations each time through
23490792Sgshapiro    the code.  So it's a performance hack.
23590792Sgshapiro    A debug structure is in the "unknown" state at the beginning of
23690792Sgshapiro    program execution, and after a call to <tt>sm_debug_addsetting</tt>.
23790792Sgshapiro    A side effect of calling <tt>sm_debug_active</tt> is that the
23890792Sgshapiro    activation level becomes known.
23990792Sgshapiro    <p>
24090792Sgshapiro
24190792Sgshapiro
24290792Sgshapiro<dt>
24390792Sgshapiro<tt> void sm_dprintf(char *fmt, ...) </tt>
24490792Sgshapiro<dd>
24590792Sgshapiro    This function is used to print a debug message.
24690792Sgshapiro    The standard idiom is
24790792Sgshapiro<blockquote><pre>
24890792Sgshapiroif (sm_debug_active(&BarDebug, 1))
24990792Sgshapiro	sm_dprintf("bar: about to test tensile strength of bar %d\n", i);
25090792Sgshapiro</pre></blockquote>
25190792Sgshapiro    <p>
25290792Sgshapiro
25390792Sgshapiro<dt>
25490792Sgshapiro<tt> void sm_dflush() </tt>
25590792Sgshapiro<dd>
25690792Sgshapiro    Flush the debug output stream.
25790792Sgshapiro    <p>
25890792Sgshapiro
25990792Sgshapiro<dt>
26090792Sgshapiro<tt> void sm_debug_setfile(SM_FILE_T *file) </tt>
26190792Sgshapiro<dd>
26290792Sgshapiro    This function lets you specify where debug output is printed.
26390792Sgshapiro    By default, debug output is written to standard output.
26490792Sgshapiro    <p>
26590792Sgshapiro    We want to allow you to direct debug output to syslog.
26690792Sgshapiro    The current plan is to provide a standard interface for
26790792Sgshapiro    creating an SM_FILE_T object that writes to syslog.
26890792Sgshapiro
26990792Sgshapiro</dl>
27090792Sgshapiro
27190792Sgshapiro</body>
27290792Sgshapiro</html>
273