debug.html revision 90792
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> 1190792Sgshapiro <br> $Id: debug.html,v 1.8 2000/12/08 21:41:41 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<p> 6390792SgshapiroFor sendmail 9.x, I propose to drop support for numeric debug categories, 6490792Sgshapiroand just use named debug categories. 6590792Sgshapiro 6690792Sgshapiro<h2> Synopsis </h2> 6790792Sgshapiro 6890792Sgshapiro<pre> 6990792Sgshapiro#include <sm/debug.h> 7090792Sgshapiro 7190792Sgshapiro/* 7290792Sgshapiro** abstractions for printing trace messages 7390792Sgshapiro*/ 7490792Sgshapirovoid sm_dprintf(char *fmt, ...) 7590792Sgshapirovoid sm_dflush() 7690792Sgshapirovoid sm_debug_setfile(SM_FILE_T *) 7790792Sgshapiro 7890792Sgshapiro/* 7990792Sgshapiro** abstractions for setting and testing debug activation levels 8090792Sgshapiro*/ 8190792Sgshapirovoid sm_debug_addsettings(char *settings) 8290792Sgshapirovoid sm_debug_addsetting(char *pattern, int level) 8390792Sgshapiro 8490792Sgshapirotypedef struct sm_debug SM_DEBUG_T; 8590792SgshapiroSM_DEBUG_T dbg = SM_DEBUG_INITIALIZER("name", "@(#)$Debug: name - description $"); 8690792Sgshapiro 8790792Sgshapirobool sm_debug_active(SM_DEBUG_T *debug, int level) 8890792Sgshapiroint sm_debug_level(SM_DEBUG_T *debug) 8990792Sgshapirobool sm_debug_unknown(SM_DEBUG_T *debug) 9090792Sgshapiro</pre> 9190792Sgshapiro 9290792Sgshapiro<h2> Naming Conventions </h2> 9390792Sgshapiro 9490792SgshapiroAll debug categories defined by libsm have names of the form <tt>sm_*</tt>. 9590792SgshapiroDebug categories that turn on trace output have names of the form 9690792Sgshapiro<tt>*_trace_*</tt>. 9790792SgshapiroDebug categories that turn on run time checks have names of the form 9890792Sgshapiro<tt>*_check_*</tt>. 9990792SgshapiroHere are all of the libsm debug categories as of March 2000: 10090792Sgshapiro 10190792Sgshapiro<table> 10290792Sgshapiro <tr> 10390792Sgshapiro <td>Variable name</td> 10490792Sgshapiro <td>Category name</td> 10590792Sgshapiro <td>Meaning</td> 10690792Sgshapiro </tr> 10790792Sgshapiro <tr> 10890792Sgshapiro <td>SmExpensiveAssert</td> 10990792Sgshapiro <td>sm_check_assert</td> 11090792Sgshapiro <td>enable expensive SM_ASSERT checking</td> 11190792Sgshapiro </tr> 11290792Sgshapiro <tr> 11390792Sgshapiro <td>SmExpensiveRequire</td> 11490792Sgshapiro <td>sm_check_require</td> 11590792Sgshapiro <td>enable expensive SM_REQUIRE checking</td> 11690792Sgshapiro </tr> 11790792Sgshapiro <tr> 11890792Sgshapiro <td>SmExpensiveEnsure</td> 11990792Sgshapiro <td>sm_check_ensure</td> 12090792Sgshapiro <td>enable expensive SM_ENSURE checking</td> 12190792Sgshapiro </tr> 12290792Sgshapiro <tr> 12390792Sgshapiro <td>SmHeapTrace</td> 12490792Sgshapiro <td>sm_trace_heap</td> 12590792Sgshapiro <td>trace sm_{malloc,realloc,free} calls</td> 12690792Sgshapiro </tr> 12790792Sgshapiro <tr> 12890792Sgshapiro <td>SmHeapCheck</td> 12990792Sgshapiro <td>sm_check_heap</td> 13090792Sgshapiro <td>enable checking and memory leak detection in sm_{malloc,realloc,free}</td> 13190792Sgshapiro </tr> 13290792Sgshapiro</table> 13390792Sgshapiro 13490792Sgshapiro<h2> Function Reference </h2> 13590792Sgshapiro 13690792Sgshapiro<dl> 13790792Sgshapiro<dt> 13890792Sgshapiro<tt> SM_DEBUG_INITIALIZER </tt> 13990792Sgshapiro<dd> 14090792Sgshapiro To create a new debug category, use the SM_DEBUG_INITIALIZER macro 14190792Sgshapiro to initialize a static variable of type SM_DEBUG_T. For example, 14290792Sgshapiro<blockquote><pre> 14390792SgshapiroSM_DEBUG_T ANSI_debug = SM_DEBUG_INITIALIZER("ANSI", 14490792Sgshapiro "@(#)$Debug: ANSI - enable reverse video in debug output $"); 14590792Sgshapiro</pre></blockquote> 14690792Sgshapiro There is no centralized table of category names that needs to 14790792Sgshapiro be edited in order to add a new debug category. 14890792Sgshapiro The sole purpose of the second argument to SM_DEBUG_INITIALIZER 14990792Sgshapiro is to provide an easy way to find out what named debug categories 15090792Sgshapiro are present in a sendmail binary. You can use: 15190792Sgshapiro<blockquote><pre> 15290792Sgshapiroident /usr/sbin/sendmail | grep Debug 15390792Sgshapiro</pre></blockquote> 15490792Sgshapiro or: 15590792Sgshapiro<blockquote><pre> 15690792Sgshapirowhat /usr/sbin/sendmail | grep Debug 15790792Sgshapiro</pre></blockquote> 15890792Sgshapiro 15990792Sgshapiro 16090792Sgshapiro<dt> 16190792Sgshapiro<tt> void sm_debug_addsetting(char *pattern, int level) </tt> 16290792Sgshapiro<dd> 16390792Sgshapiro All debug categories default to activation level 0, which means 16490792Sgshapiro no activity. 16590792Sgshapiro This function updates an internal database of debug settings, 16690792Sgshapiro setting all categories whose name matches the specified glob 16790792Sgshapiro pattern to the specified activation level. The level argument 16890792Sgshapiro must be >= 0. 16990792Sgshapiro <p> 17090792Sgshapiro 17190792Sgshapiro 17290792Sgshapiro<dt> 17390792Sgshapiro<tt> void sm_debug_addsettings(char *settings) </tt> 17490792Sgshapiro<dd> 17590792Sgshapiro This function is used to process the <tt>-d</tt> command line 17690792Sgshapiro option of Sendmail 9.x, and of other programs that support the 17790792Sgshapiro setting of named debug categories. The settings argument is a 17890792Sgshapiro comma-separated list of settings; each setting is a glob pattern, 17990792Sgshapiro optionally followed by a '.' and a decimal numeral. 18090792Sgshapiro <p> 18190792Sgshapiro 18290792Sgshapiro 18390792Sgshapiro<dt> 18490792Sgshapiro<tt> bool sm_debug_active(SM_DEBUG_T *debug, int level) </tt> 18590792Sgshapiro<dd> 18690792Sgshapiro This macro returns <tt>true</tt> if the activation level of 18790792Sgshapiro the statically initialized debug structure <tt>debug</tt> 18890792Sgshapiro is >= the specified level. 18990792Sgshapiro The test is performed very efficiently: in the most common case, 19090792Sgshapiro when the result is <tt>false</tt>, only a single comparison 19190792Sgshapiro operation is performed. 19290792Sgshapiro <p> 19390792Sgshapiro This macro performs a function call only if the debug structure has 19490792Sgshapiro an unknown activation level. All debug structures are in this state 19590792Sgshapiro at the beginning of program execution, and after a call to 19690792Sgshapiro <tt>sm_debug_addsetting</tt>. 19790792Sgshapiro <p> 19890792Sgshapiro 19990792Sgshapiro 20090792Sgshapiro<dt> 20190792Sgshapiro<tt> int sm_debug_level(SM_DEBUG_T *debug) </tt> 20290792Sgshapiro<dd> 20390792Sgshapiro This macro returns the activation level of the specified debug structure. 20490792Sgshapiro The comparison 20590792Sgshapiro<blockquote><pre> 20690792Sgshapirosm_debug_level(debug) >= level 20790792Sgshapiro</pre></blockquote> 20890792Sgshapiro is slightly less efficient than, but otherwise semantically 20990792Sgshapiro equivalent to 21090792Sgshapiro<blockquote><pre> 21190792Sgshapirosm_debug_active(debug, level) 21290792Sgshapiro</pre></blockquote> 21390792Sgshapiro <p> 21490792Sgshapiro 21590792Sgshapiro 21690792Sgshapiro<dt> 21790792Sgshapiro<tt> bool sm_debug_unknown(SM_DEBUG_T *debug) </tt> 21890792Sgshapiro<dd> 21990792Sgshapiro This macro returns true if the activation level of the specified 22090792Sgshapiro debug structure is unknown. 22190792Sgshapiro Here is an example of how the macro might be used: 22290792Sgshapiro<blockquote><pre> 22390792Sgshapiroif (sm_debug_unknown(&FooDebug)) 22490792Sgshapiro{ 22590792Sgshapiro if (sm_debug_active(&FooDebug, 1)) 22690792Sgshapiro { 22790792Sgshapiro ... perform some expensive data structure initializations 22890792Sgshapiro ... in order to enable the "foo" debugging mechanism 22990792Sgshapiro } 23090792Sgshapiro else 23190792Sgshapiro { 23290792Sgshapiro ... disable the "foo" debugging mechanism 23390792Sgshapiro } 23490792Sgshapiro} 23590792Sgshapiro</pre></blockquote> 23690792Sgshapiro The purpose of using <tt>sm_debug_unknown</tt> in the above example 23790792Sgshapiro is to avoid performing the expensive initializations each time through 23890792Sgshapiro the code. So it's a performance hack. 23990792Sgshapiro A debug structure is in the "unknown" state at the beginning of 24090792Sgshapiro program execution, and after a call to <tt>sm_debug_addsetting</tt>. 24190792Sgshapiro A side effect of calling <tt>sm_debug_active</tt> is that the 24290792Sgshapiro activation level becomes known. 24390792Sgshapiro <p> 24490792Sgshapiro 24590792Sgshapiro 24690792Sgshapiro<dt> 24790792Sgshapiro<tt> void sm_dprintf(char *fmt, ...) </tt> 24890792Sgshapiro<dd> 24990792Sgshapiro This function is used to print a debug message. 25090792Sgshapiro The standard idiom is 25190792Sgshapiro<blockquote><pre> 25290792Sgshapiroif (sm_debug_active(&BarDebug, 1)) 25390792Sgshapiro sm_dprintf("bar: about to test tensile strength of bar %d\n", i); 25490792Sgshapiro</pre></blockquote> 25590792Sgshapiro <p> 25690792Sgshapiro 25790792Sgshapiro<dt> 25890792Sgshapiro<tt> void sm_dflush() </tt> 25990792Sgshapiro<dd> 26090792Sgshapiro Flush the debug output stream. 26190792Sgshapiro <p> 26290792Sgshapiro 26390792Sgshapiro<dt> 26490792Sgshapiro<tt> void sm_debug_setfile(SM_FILE_T *file) </tt> 26590792Sgshapiro<dd> 26690792Sgshapiro This function lets you specify where debug output is printed. 26790792Sgshapiro By default, debug output is written to standard output. 26890792Sgshapiro <p> 26990792Sgshapiro We want to allow you to direct debug output to syslog. 27090792Sgshapiro The current plan is to provide a standard interface for 27190792Sgshapiro creating an SM_FILE_T object that writes to syslog. 27290792Sgshapiro 27390792Sgshapiro</dl> 27490792Sgshapiro 27590792Sgshapiro</body> 27690792Sgshapiro</html> 277