140266059SGregory Neil Shapiro<html> 240266059SGregory Neil Shapiro<head> 340266059SGregory Neil Shapiro <title>libsm : Debugging and Tracing</title> 440266059SGregory Neil Shapiro</head> 540266059SGregory Neil Shapiro<body> 640266059SGregory Neil Shapiro 740266059SGregory Neil Shapiro<a href="index.html">Back to libsm overview</a> 840266059SGregory Neil Shapiro 940266059SGregory Neil Shapiro<center> 1040266059SGregory Neil Shapiro <h1> libsm : Debugging and Tracing </h1> 11*4313cc83SGregory Neil Shapiro <br> $Id: debug.html,v 1.9 2002-02-02 16:50:56 ca Exp $ 1240266059SGregory Neil Shapiro</center> 1340266059SGregory Neil Shapiro 1440266059SGregory Neil Shapiro<h2> Introduction </h2> 1540266059SGregory Neil Shapiro 1640266059SGregory Neil ShapiroThe debug and trace package provides abstractions for writing trace 1740266059SGregory Neil Shapiromessages, and abstractions for enabling and disabling debug and 1840266059SGregory Neil Shapirotrace code at run time. 1940266059SGregory Neil Shapiro 2040266059SGregory Neil Shapiro<p> 2140266059SGregory Neil ShapiroSendmail 8.11 and earlier has a <tt>-d</tt> option which 2240266059SGregory Neil Shapirolets you turn on debug and trace code. 2340266059SGregory Neil ShapiroDebug categories are integers from 0 to 99, with the sole exception 2440266059SGregory Neil Shapiroof "ANSI", which is a named debug category. 2540266059SGregory Neil Shapiro 2640266059SGregory Neil Shapiro<p> 2740266059SGregory Neil ShapiroThe libsm debug package supports named debug categories. 2840266059SGregory Neil ShapiroDebug category names have the form of C identifiers. 2940266059SGregory Neil ShapiroFor example, <tt>sm_trace_heap</tt> controls the output of trace 3040266059SGregory Neil Shapiromessages from the sm heap package, while <tt>sm_check_heap</tt> 3140266059SGregory Neil Shapirocontrols the argument validity checking and memory leak detection 3240266059SGregory Neil Shapirofeatures of the sm heap package. 3340266059SGregory Neil Shapiro 3440266059SGregory Neil Shapiro<p> 3540266059SGregory Neil ShapiroIn sendmail 8.12, the <tt>-d</tt> flag is generalized 3640266059SGregory Neil Shapiroto support both the original style numeric categories, for backwards 3740266059SGregory Neil Shapirocompatibility, and the new style named categories implemented by libsm. 3840266059SGregory Neil ShapiroWith this change, 3940266059SGregory Neil Shapiro"-dANSI" is implemented using a libsm named debug category. 4040266059SGregory Neil ShapiroYou will be able to set a collection of named debug categories to 4140266059SGregory Neil Shapirothe same activation level by specifying a glob pattern. 4240266059SGregory Neil ShapiroFor example, 4340266059SGregory Neil Shapiro<dl> 4440266059SGregory Neil Shapiro<dt> 4540266059SGregory Neil Shapiro <tt> -dANSI </tt> 4640266059SGregory Neil Shapiro<dd> 4740266059SGregory Neil Shapiro sets the named category "ANSI" to level 1, 4840266059SGregory Neil Shapiro<dt> 4940266059SGregory Neil Shapiro <tt> -dfoo_*.3 </tt> 5040266059SGregory Neil Shapiro<dd> 5140266059SGregory Neil Shapiro sets all named categories matching the glob pattern "foo_*" to level 3, 5240266059SGregory Neil Shapiro<dt> 5340266059SGregory Neil Shapiro <tt> -d0-99.1 </tt> 5440266059SGregory Neil Shapiro<dd> 5540266059SGregory Neil Shapiro sets the numeric categories 0 through 99 to level 1, and 5640266059SGregory Neil Shapiro<dt> 5740266059SGregory Neil Shapiro <tt> -dANSI,foo_*.3,0-99.1 </tt> 5840266059SGregory Neil Shapiro<dd> 5940266059SGregory Neil Shapiro does all of the above. 6040266059SGregory Neil Shapiro</dl> 6140266059SGregory Neil Shapiro 6240266059SGregory Neil Shapiro<h2> Synopsis </h2> 6340266059SGregory Neil Shapiro 6440266059SGregory Neil Shapiro<pre> 6540266059SGregory Neil Shapiro#include <sm/debug.h> 6640266059SGregory Neil Shapiro 6740266059SGregory Neil Shapiro/* 6840266059SGregory Neil Shapiro** abstractions for printing trace messages 6940266059SGregory Neil Shapiro*/ 7040266059SGregory Neil Shapirovoid sm_dprintf(char *fmt, ...) 7140266059SGregory Neil Shapirovoid sm_dflush() 7240266059SGregory Neil Shapirovoid sm_debug_setfile(SM_FILE_T *) 7340266059SGregory Neil Shapiro 7440266059SGregory Neil Shapiro/* 7540266059SGregory Neil Shapiro** abstractions for setting and testing debug activation levels 7640266059SGregory Neil Shapiro*/ 7740266059SGregory Neil Shapirovoid sm_debug_addsettings(char *settings) 7840266059SGregory Neil Shapirovoid sm_debug_addsetting(char *pattern, int level) 7940266059SGregory Neil Shapiro 8040266059SGregory Neil Shapirotypedef struct sm_debug SM_DEBUG_T; 8140266059SGregory Neil ShapiroSM_DEBUG_T dbg = SM_DEBUG_INITIALIZER("name", "@(#)$Debug: name - description $"); 8240266059SGregory Neil Shapiro 8340266059SGregory Neil Shapirobool sm_debug_active(SM_DEBUG_T *debug, int level) 8440266059SGregory Neil Shapiroint sm_debug_level(SM_DEBUG_T *debug) 8540266059SGregory Neil Shapirobool sm_debug_unknown(SM_DEBUG_T *debug) 8640266059SGregory Neil Shapiro</pre> 8740266059SGregory Neil Shapiro 8840266059SGregory Neil Shapiro<h2> Naming Conventions </h2> 8940266059SGregory Neil Shapiro 9040266059SGregory Neil ShapiroAll debug categories defined by libsm have names of the form <tt>sm_*</tt>. 9140266059SGregory Neil ShapiroDebug categories that turn on trace output have names of the form 9240266059SGregory Neil Shapiro<tt>*_trace_*</tt>. 9340266059SGregory Neil ShapiroDebug categories that turn on run time checks have names of the form 9440266059SGregory Neil Shapiro<tt>*_check_*</tt>. 9540266059SGregory Neil ShapiroHere are all of the libsm debug categories as of March 2000: 9640266059SGregory Neil Shapiro 9740266059SGregory Neil Shapiro<table> 9840266059SGregory Neil Shapiro <tr> 9940266059SGregory Neil Shapiro <td>Variable name</td> 10040266059SGregory Neil Shapiro <td>Category name</td> 10140266059SGregory Neil Shapiro <td>Meaning</td> 10240266059SGregory Neil Shapiro </tr> 10340266059SGregory Neil Shapiro <tr> 10440266059SGregory Neil Shapiro <td>SmExpensiveAssert</td> 10540266059SGregory Neil Shapiro <td>sm_check_assert</td> 10640266059SGregory Neil Shapiro <td>enable expensive SM_ASSERT checking</td> 10740266059SGregory Neil Shapiro </tr> 10840266059SGregory Neil Shapiro <tr> 10940266059SGregory Neil Shapiro <td>SmExpensiveRequire</td> 11040266059SGregory Neil Shapiro <td>sm_check_require</td> 11140266059SGregory Neil Shapiro <td>enable expensive SM_REQUIRE checking</td> 11240266059SGregory Neil Shapiro </tr> 11340266059SGregory Neil Shapiro <tr> 11440266059SGregory Neil Shapiro <td>SmExpensiveEnsure</td> 11540266059SGregory Neil Shapiro <td>sm_check_ensure</td> 11640266059SGregory Neil Shapiro <td>enable expensive SM_ENSURE checking</td> 11740266059SGregory Neil Shapiro </tr> 11840266059SGregory Neil Shapiro <tr> 11940266059SGregory Neil Shapiro <td>SmHeapTrace</td> 12040266059SGregory Neil Shapiro <td>sm_trace_heap</td> 12140266059SGregory Neil Shapiro <td>trace sm_{malloc,realloc,free} calls</td> 12240266059SGregory Neil Shapiro </tr> 12340266059SGregory Neil Shapiro <tr> 12440266059SGregory Neil Shapiro <td>SmHeapCheck</td> 12540266059SGregory Neil Shapiro <td>sm_check_heap</td> 12640266059SGregory Neil Shapiro <td>enable checking and memory leak detection in sm_{malloc,realloc,free}</td> 12740266059SGregory Neil Shapiro </tr> 12840266059SGregory Neil Shapiro</table> 12940266059SGregory Neil Shapiro 13040266059SGregory Neil Shapiro<h2> Function Reference </h2> 13140266059SGregory Neil Shapiro 13240266059SGregory Neil Shapiro<dl> 13340266059SGregory Neil Shapiro<dt> 13440266059SGregory Neil Shapiro<tt> SM_DEBUG_INITIALIZER </tt> 13540266059SGregory Neil Shapiro<dd> 13640266059SGregory Neil Shapiro To create a new debug category, use the SM_DEBUG_INITIALIZER macro 13740266059SGregory Neil Shapiro to initialize a static variable of type SM_DEBUG_T. For example, 13840266059SGregory Neil Shapiro<blockquote><pre> 13940266059SGregory Neil ShapiroSM_DEBUG_T ANSI_debug = SM_DEBUG_INITIALIZER("ANSI", 14040266059SGregory Neil Shapiro "@(#)$Debug: ANSI - enable reverse video in debug output $"); 14140266059SGregory Neil Shapiro</pre></blockquote> 14240266059SGregory Neil Shapiro There is no centralized table of category names that needs to 14340266059SGregory Neil Shapiro be edited in order to add a new debug category. 14440266059SGregory Neil Shapiro The sole purpose of the second argument to SM_DEBUG_INITIALIZER 14540266059SGregory Neil Shapiro is to provide an easy way to find out what named debug categories 14640266059SGregory Neil Shapiro are present in a sendmail binary. You can use: 14740266059SGregory Neil Shapiro<blockquote><pre> 14840266059SGregory Neil Shapiroident /usr/sbin/sendmail | grep Debug 14940266059SGregory Neil Shapiro</pre></blockquote> 15040266059SGregory Neil Shapiro or: 15140266059SGregory Neil Shapiro<blockquote><pre> 15240266059SGregory Neil Shapirowhat /usr/sbin/sendmail | grep Debug 15340266059SGregory Neil Shapiro</pre></blockquote> 15440266059SGregory Neil Shapiro 15540266059SGregory Neil Shapiro 15640266059SGregory Neil Shapiro<dt> 15740266059SGregory Neil Shapiro<tt> void sm_debug_addsetting(char *pattern, int level) </tt> 15840266059SGregory Neil Shapiro<dd> 15940266059SGregory Neil Shapiro All debug categories default to activation level 0, which means 16040266059SGregory Neil Shapiro no activity. 16140266059SGregory Neil Shapiro This function updates an internal database of debug settings, 16240266059SGregory Neil Shapiro setting all categories whose name matches the specified glob 16340266059SGregory Neil Shapiro pattern to the specified activation level. The level argument 16440266059SGregory Neil Shapiro must be >= 0. 16540266059SGregory Neil Shapiro <p> 16640266059SGregory Neil Shapiro 16740266059SGregory Neil Shapiro 16840266059SGregory Neil Shapiro<dt> 16940266059SGregory Neil Shapiro<tt> void sm_debug_addsettings(char *settings) </tt> 17040266059SGregory Neil Shapiro<dd> 17140266059SGregory Neil Shapiro This function is used to process the <tt>-d</tt> command line 17240266059SGregory Neil Shapiro option of Sendmail 9.x, and of other programs that support the 17340266059SGregory Neil Shapiro setting of named debug categories. The settings argument is a 17440266059SGregory Neil Shapiro comma-separated list of settings; each setting is a glob pattern, 17540266059SGregory Neil Shapiro optionally followed by a '.' and a decimal numeral. 17640266059SGregory Neil Shapiro <p> 17740266059SGregory Neil Shapiro 17840266059SGregory Neil Shapiro 17940266059SGregory Neil Shapiro<dt> 18040266059SGregory Neil Shapiro<tt> bool sm_debug_active(SM_DEBUG_T *debug, int level) </tt> 18140266059SGregory Neil Shapiro<dd> 18240266059SGregory Neil Shapiro This macro returns <tt>true</tt> if the activation level of 18340266059SGregory Neil Shapiro the statically initialized debug structure <tt>debug</tt> 18440266059SGregory Neil Shapiro is >= the specified level. 18540266059SGregory Neil Shapiro The test is performed very efficiently: in the most common case, 18640266059SGregory Neil Shapiro when the result is <tt>false</tt>, only a single comparison 18740266059SGregory Neil Shapiro operation is performed. 18840266059SGregory Neil Shapiro <p> 18940266059SGregory Neil Shapiro This macro performs a function call only if the debug structure has 19040266059SGregory Neil Shapiro an unknown activation level. All debug structures are in this state 19140266059SGregory Neil Shapiro at the beginning of program execution, and after a call to 19240266059SGregory Neil Shapiro <tt>sm_debug_addsetting</tt>. 19340266059SGregory Neil Shapiro <p> 19440266059SGregory Neil Shapiro 19540266059SGregory Neil Shapiro 19640266059SGregory Neil Shapiro<dt> 19740266059SGregory Neil Shapiro<tt> int sm_debug_level(SM_DEBUG_T *debug) </tt> 19840266059SGregory Neil Shapiro<dd> 19940266059SGregory Neil Shapiro This macro returns the activation level of the specified debug structure. 20040266059SGregory Neil Shapiro The comparison 20140266059SGregory Neil Shapiro<blockquote><pre> 20240266059SGregory Neil Shapirosm_debug_level(debug) >= level 20340266059SGregory Neil Shapiro</pre></blockquote> 20440266059SGregory Neil Shapiro is slightly less efficient than, but otherwise semantically 20540266059SGregory Neil Shapiro equivalent to 20640266059SGregory Neil Shapiro<blockquote><pre> 20740266059SGregory Neil Shapirosm_debug_active(debug, level) 20840266059SGregory Neil Shapiro</pre></blockquote> 20940266059SGregory Neil Shapiro <p> 21040266059SGregory Neil Shapiro 21140266059SGregory Neil Shapiro 21240266059SGregory Neil Shapiro<dt> 21340266059SGregory Neil Shapiro<tt> bool sm_debug_unknown(SM_DEBUG_T *debug) </tt> 21440266059SGregory Neil Shapiro<dd> 21540266059SGregory Neil Shapiro This macro returns true if the activation level of the specified 21640266059SGregory Neil Shapiro debug structure is unknown. 21740266059SGregory Neil Shapiro Here is an example of how the macro might be used: 21840266059SGregory Neil Shapiro<blockquote><pre> 21940266059SGregory Neil Shapiroif (sm_debug_unknown(&FooDebug)) 22040266059SGregory Neil Shapiro{ 22140266059SGregory Neil Shapiro if (sm_debug_active(&FooDebug, 1)) 22240266059SGregory Neil Shapiro { 22340266059SGregory Neil Shapiro ... perform some expensive data structure initializations 22440266059SGregory Neil Shapiro ... in order to enable the "foo" debugging mechanism 22540266059SGregory Neil Shapiro } 22640266059SGregory Neil Shapiro else 22740266059SGregory Neil Shapiro { 22840266059SGregory Neil Shapiro ... disable the "foo" debugging mechanism 22940266059SGregory Neil Shapiro } 23040266059SGregory Neil Shapiro} 23140266059SGregory Neil Shapiro</pre></blockquote> 23240266059SGregory Neil Shapiro The purpose of using <tt>sm_debug_unknown</tt> in the above example 23340266059SGregory Neil Shapiro is to avoid performing the expensive initializations each time through 23440266059SGregory Neil Shapiro the code. So it's a performance hack. 23540266059SGregory Neil Shapiro A debug structure is in the "unknown" state at the beginning of 23640266059SGregory Neil Shapiro program execution, and after a call to <tt>sm_debug_addsetting</tt>. 23740266059SGregory Neil Shapiro A side effect of calling <tt>sm_debug_active</tt> is that the 23840266059SGregory Neil Shapiro activation level becomes known. 23940266059SGregory Neil Shapiro <p> 24040266059SGregory Neil Shapiro 24140266059SGregory Neil Shapiro 24240266059SGregory Neil Shapiro<dt> 24340266059SGregory Neil Shapiro<tt> void sm_dprintf(char *fmt, ...) </tt> 24440266059SGregory Neil Shapiro<dd> 24540266059SGregory Neil Shapiro This function is used to print a debug message. 24640266059SGregory Neil Shapiro The standard idiom is 24740266059SGregory Neil Shapiro<blockquote><pre> 24840266059SGregory Neil Shapiroif (sm_debug_active(&BarDebug, 1)) 24940266059SGregory Neil Shapiro sm_dprintf("bar: about to test tensile strength of bar %d\n", i); 25040266059SGregory Neil Shapiro</pre></blockquote> 25140266059SGregory Neil Shapiro <p> 25240266059SGregory Neil Shapiro 25340266059SGregory Neil Shapiro<dt> 25440266059SGregory Neil Shapiro<tt> void sm_dflush() </tt> 25540266059SGregory Neil Shapiro<dd> 25640266059SGregory Neil Shapiro Flush the debug output stream. 25740266059SGregory Neil Shapiro <p> 25840266059SGregory Neil Shapiro 25940266059SGregory Neil Shapiro<dt> 26040266059SGregory Neil Shapiro<tt> void sm_debug_setfile(SM_FILE_T *file) </tt> 26140266059SGregory Neil Shapiro<dd> 26240266059SGregory Neil Shapiro This function lets you specify where debug output is printed. 26340266059SGregory Neil Shapiro By default, debug output is written to standard output. 26440266059SGregory Neil Shapiro <p> 26540266059SGregory Neil Shapiro We want to allow you to direct debug output to syslog. 26640266059SGregory Neil Shapiro The current plan is to provide a standard interface for 26740266059SGregory Neil Shapiro creating an SM_FILE_T object that writes to syslog. 26840266059SGregory Neil Shapiro 26940266059SGregory Neil Shapiro</dl> 27040266059SGregory Neil Shapiro 27140266059SGregory Neil Shapiro</body> 27240266059SGregory Neil Shapiro</html> 273