1<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Chapter�4.�The samba DEBUG system</title><link rel="stylesheet" href="samba.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.71.0"><link rel="start" href="index.html" title="SAMBA Developers Guide"><link rel="up" href="pt02.html" title="Part�II.�Samba Basics"><link rel="prev" href="architecture.html" title="Chapter�3.�Samba Architecture"><link rel="next" href="internals.html" title="Chapter�5.�Samba Internals"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter�4.�The samba DEBUG system</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="architecture.html">Prev</a>�</td><th width="60%" align="center">Part�II.�Samba Basics</th><td width="20%" align="right">�<a accesskey="n" href="internals.html">Next</a></td></tr></table><hr></div><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="debug"></a>Chapter�4.�The samba DEBUG system</h2></div><div><div class="author"><h3 class="author"><span class="firstname">Chris</span> <span class="surname">Hertel</span></h3></div></div><div><p class="pubdate">July 1998</p></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="debug.html#id322739">New Output Syntax</a></span></dt><dt><span class="sect1"><a href="debug.html#id322834">The DEBUG() Macro</a></span></dt><dt><span class="sect1"><a href="debug.html#id322926">The DEBUGADD() Macro</a></span></dt><dt><span class="sect1"><a href="debug.html#id322958">The DEBUGLVL() Macro</a></span></dt><dt><span class="sect1"><a href="debug.html#id323036">New Functions</a></span></dt><dd><dl><dt><span class="sect2"><a href="debug.html#id323042">dbgtext()</a></span></dt><dt><span class="sect2"><a href="debug.html#id323055">dbghdr()</a></span></dt><dt><span class="sect2"><a href="debug.html#id323071">format_debug_text()</a></span></dt></dl></dd></dl></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id322739"></a>New Output Syntax</h2></div></div></div><p> 2 The syntax of a debugging log file is represented as: 3</p><pre class="programlisting"> 4 >debugfile< :== { >debugmsg< } 5 6 >debugmsg< :== >debughdr< '\n' >debugtext< 7 8 >debughdr< :== '[' TIME ',' LEVEL ']' FILE ':' [FUNCTION] '(' LINE ')' 9 10 >debugtext< :== { >debugline< } 11 12 >debugline< :== TEXT '\n' 13</pre><p> 14TEXT is a string of characters excluding the newline character. 15</p><p> 16LEVEL is the DEBUG level of the message (an integer in the range 17 0..10). 18</p><p> 19TIME is a timestamp. 20</p><p> 21FILE is the name of the file from which the debug message was 22generated. 23</p><p> 24FUNCTION is the function from which the debug message was generated. 25</p><p> 26LINE is the line number of the debug statement that generated the 27message. 28</p><p>Basically, what that all means is:</p><div class="orderedlist"><ol type="1"><li><p> 29A debugging log file is made up of debug messages. 30</p></li><li><p> 31Each debug message is made up of a header and text. The header is 32separated from the text by a newline. 33</p></li><li><p> 34The header begins with the timestamp and debug level of the 35message enclosed in brackets. The filename, function, and line 36number at which the message was generated follow. The filename is 37terminated by a colon, and the function name is terminated by the 38parenthesis which contain the line number. Depending upon the 39compiler, the function name may be missing (it is generated by the 40__FUNCTION__ macro, which is not universally implemented, dangit). 41</p></li><li><p> 42The message text is made up of zero or more lines, each terminated 43by a newline. 44</p></li></ol></div><p>Here's some example output:</p><pre class="programlisting"> 45 [1998/08/03 12:55:25, 1] nmbd.c:(659) 46 Netbios nameserver version 1.9.19-prealpha started. 47 Copyright Andrew Tridgell 1994-1997 48 [1998/08/03 12:55:25, 3] loadparm.c:(763) 49 Initializing global parameters 50</pre><p> 51Note that in the above example the function names are not listed on 52the header line. That's because the example above was generated on an 53SGI Indy, and the SGI compiler doesn't support the __FUNCTION__ macro. 54</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id322834"></a>The DEBUG() Macro</h2></div></div></div><p> 55Use of the DEBUG() macro is unchanged. DEBUG() takes two parameters. 56The first is the message level, the second is the body of a function 57call to the Debug1() function. 58</p><p>That's confusing.</p><p>Here's an example which may help a bit. If you would write</p><pre class="programlisting"> 59printf( "This is a %s message.\n", "debug" ); 60</pre><p> 61to send the output to stdout, then you would write 62</p><pre class="programlisting"> 63DEBUG( 0, ( "This is a %s message.\n", "debug" ) ); 64</pre><p> 65to send the output to the debug file. All of the normal printf() 66formatting escapes work. 67</p><p> 68Note that in the above example the DEBUG message level is set to 0. 69Messages at level 0 always print. Basically, if the message level is 70less than or equal to the global value DEBUGLEVEL, then the DEBUG 71statement is processed. 72</p><p> 73The output of the above example would be something like: 74</p><pre class="programlisting"> 75 [1998/07/30 16:00:51, 0] file.c:function(128) 76 This is a debug message. 77</pre><p> 78Each call to DEBUG() creates a new header *unless* the output produced 79by the previous call to DEBUG() did not end with a '\n'. Output to the 80debug file is passed through a formatting buffer which is flushed 81every time a newline is encountered. If the buffer is not empty when 82DEBUG() is called, the new input is simply appended. 83</p><p> 84...but that's really just a Kludge. It was put in place because 85DEBUG() has been used to write partial lines. Here's a simple (dumb) 86example of the kind of thing I'm talking about: 87</p><pre class="programlisting"> 88 DEBUG( 0, ("The test returned " ) ); 89 if( test() ) 90 DEBUG(0, ("True") ); 91 else 92 DEBUG(0, ("False") ); 93 DEBUG(0, (".\n") ); 94</pre><p> 95Without the format buffer, the output (assuming test() returned true) 96would look like this: 97</p><pre class="programlisting"> 98 [1998/07/30 16:00:51, 0] file.c:function(256) 99 The test returned 100 [1998/07/30 16:00:51, 0] file.c:function(258) 101 True 102 [1998/07/30 16:00:51, 0] file.c:function(261) 103 . 104</pre><p>Which isn't much use. The format buffer kludge fixes this problem. 105</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id322926"></a>The DEBUGADD() Macro</h2></div></div></div><p> 106In addition to the kludgey solution to the broken line problem 107described above, there is a clean solution. The DEBUGADD() macro never 108generates a header. It will append new text to the current debug 109message even if the format buffer is empty. The syntax of the 110DEBUGADD() macro is the same as that of the DEBUG() macro. 111</p><pre class="programlisting"> 112 DEBUG( 0, ("This is the first line.\n" ) ); 113 DEBUGADD( 0, ("This is the second line.\nThis is the third line.\n" ) ); 114</pre><p>Produces</p><pre class="programlisting"> 115 [1998/07/30 16:00:51, 0] file.c:function(512) 116 This is the first line. 117 This is the second line. 118 This is the third line. 119</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id322958"></a>The DEBUGLVL() Macro</h2></div></div></div><p> 120One of the problems with the DEBUG() macro was that DEBUG() lines 121tended to get a bit long. Consider this example from 122nmbd_sendannounce.c: 123</p><pre class="programlisting"> 124 DEBUG(3,("send_local_master_announcement: type %x for name %s on subnet %s for workgroup %s\n", 125 type, global_myname, subrec->subnet_name, work->work_group)); 126</pre><p> 127One solution to this is to break it down using DEBUG() and DEBUGADD(), 128as follows: 129</p><pre class="programlisting"> 130 DEBUG( 3, ( "send_local_master_announcement: " ) ); 131 DEBUGADD( 3, ( "type %x for name %s ", type, global_myname ) ); 132 DEBUGADD( 3, ( "on subnet %s ", subrec->subnet_name ) ); 133 DEBUGADD( 3, ( "for workgroup %s\n", work->work_group ) ); 134</pre><p> 135A similar, but arguably nicer approach is to use the DEBUGLVL() macro. 136This macro returns True if the message level is less than or equal to 137the global DEBUGLEVEL value, so: 138</p><pre class="programlisting"> 139 if( DEBUGLVL( 3 ) ) 140 { 141 dbgtext( "send_local_master_announcement: " ); 142 dbgtext( "type %x for name %s ", type, global_myname ); 143 dbgtext( "on subnet %s ", subrec->subnet_name ); 144 dbgtext( "for workgroup %s\n", work->work_group ); 145 } 146</pre><p>(The dbgtext() function is explained below.)</p><p>There are a few advantages to this scheme:</p><div class="orderedlist"><ol type="1"><li><p> 147The test is performed only once. 148</p></li><li><p> 149You can allocate variables off of the stack that will only be used 150within the DEBUGLVL() block. 151</p></li><li><p> 152Processing that is only relevant to debug output can be contained 153within the DEBUGLVL() block. 154</p></li></ol></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id323036"></a>New Functions</h2></div></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id323042"></a>dbgtext()</h3></div></div></div><p> 155This function prints debug message text to the debug file (and 156possibly to syslog) via the format buffer. The function uses a 157variable argument list just like printf() or Debug1(). The 158input is printed into a buffer using the vslprintf() function, 159and then passed to format_debug_text(). 160 161If you use DEBUGLVL() you will probably print the body of the 162message using dbgtext(). 163</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id323055"></a>dbghdr()</h3></div></div></div><p> 164This is the function that writes a debug message header. 165Headers are not processed via the format buffer. Also note that 166if the format buffer is not empty, a call to dbghdr() will not 167produce any output. See the comments in dbghdr() for more info. 168</p><p> 169It is not likely that this function will be called directly. It 170is used by DEBUG() and DEBUGADD(). 171</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id323071"></a>format_debug_text()</h3></div></div></div><p> 172This is a static function in debug.c. It stores the output text 173for the body of the message in a buffer until it encounters a 174newline. When the newline character is found, the buffer is 175written to the debug file via the Debug1() function, and the 176buffer is reset. This allows us to add the indentation at the 177beginning of each line of the message body, and also ensures 178that the output is written a line at a time (which cleans up 179syslog output). 180</p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="architecture.html">Prev</a>�</td><td width="20%" align="center"><a accesskey="u" href="pt02.html">Up</a></td><td width="40%" align="right">�<a accesskey="n" href="internals.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter�3.�Samba Architecture�</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">�Chapter�5.�Samba Internals</td></tr></table></div></body></html> 181