s4-heimdal: Fix typo in comment.
[Samba/gbeck.git] / docs-xml / Samba3-Developers-Guide / debug.xml
bloba55facedff48baad64f8d84815d2543170ea7619
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE chapter PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc">
3 <chapter id="debug">
4 <chapterinfo>
5         <author>
6                 <firstname>Chris</firstname><surname>Hertel</surname>
7         </author>
8         <pubdate>July 1998</pubdate>
9 </chapterinfo>
11 <title>The samba DEBUG system</title>
13 <sect1>
14 <title>New Output Syntax</title>
16 <para>
17    The syntax of a debugging log file is represented as:
18 </para>
20 <para><programlisting>
21   &gt;debugfile&lt; :== { &gt;debugmsg&lt; }
23   &gt;debugmsg&lt;  :== &gt;debughdr&lt; '\n' &gt;debugtext&lt;
25   &gt;debughdr&lt;  :== '[' TIME ',' LEVEL ']' FILE ':' [FUNCTION] '(' LINE ')'
27   &gt;debugtext&lt; :== { &gt;debugline&lt; }
29   &gt;debugline&lt; :== TEXT '\n'
30 </programlisting></para>
32 <para>
33 TEXT is a string of characters excluding the newline character.
34 </para>
36 <para>
37 LEVEL is the DEBUG level of the message (an integer in the range
38                 0..10).
39 </para>
41 <para>
42 TIME is a timestamp.
43 </para>
45 <para>
46 FILE is the name of the file from which the debug message was
47 generated.
48 </para>
50 <para>
51 FUNCTION is the function from which the debug message was generated.
52 </para>
54 <para>
55 LINE is the line number of the debug statement that generated the
56 message.
57 </para>
59 <para>Basically, what that all means is:</para>
60 <orderedlist>
61 <listitem><para>
62 A debugging log file is made up of debug messages.
63 </para></listitem>
64 <listitem><para>
65 Each debug message is made up of a header and text. The header is
66 separated from the text by a newline.
67 </para></listitem>
68 <listitem><para>
69 The header begins with the timestamp and debug level of the
70 message enclosed in brackets. The filename, function, and line
71 number at which the message was generated follow. The filename is
72 terminated by a colon, and the function name is terminated by the
73 parenthesis which contain the line number. Depending upon the
74 compiler, the function name may be missing (it is generated by the
75 __FUNCTION__ macro, which is not universally implemented, dangit).
76 </para></listitem>
77 <listitem><para>
78 The message text is made up of zero or more lines, each terminated
79 by a newline.
80 </para></listitem>
81 </orderedlist>
83 <para>Here's some example output:</para>
85 <para><programlisting>
86     [1998/08/03 12:55:25, 1] nmbd.c:(659)
87       Netbios nameserver version 1.9.19-prealpha started.
88       Copyright Andrew Tridgell 1994-1997
89     [1998/08/03 12:55:25, 3] loadparm.c:(763)
90       Initializing global parameters
91 </programlisting></para>
93 <para>
94 Note that in the above example the function names are not listed on
95 the header line. That's because the example above was generated on an
96 SGI Indy, and the SGI compiler doesn't support the __FUNCTION__ macro.
97 </para>
99 </sect1>
101 <sect1>
102 <title>The DEBUG() Macro</title>
104 <para>
105 Use of the DEBUG() macro is unchanged. DEBUG() takes two parameters.
106 The first is the message level, the second is the body of a function
107 call to the Debug1() function.
108 </para>
110 <para>That's confusing.</para>
112 <para>Here's an example which may help a bit. If you would write</para>
114 <para><programlisting>
115 printf( "This is a %s message.\n", "debug" );
116 </programlisting></para>
118 <para>
119 to send the output to stdout, then you would write
120 </para>
122 <para><programlisting>
123 DEBUG( 0, ( "This is a %s message.\n", "debug" ) );
124 </programlisting></para>
126 <para>
127 to send the output to the debug file.  All of the normal printf()
128 formatting escapes work.
129 </para>
131 <para>
132 Note that in the above example the DEBUG message level is set to 0.
133 Messages at level 0 always print.  Basically, if the message level is
134 less than or equal to the global value DEBUGLEVEL, then the DEBUG
135 statement is processed.
136 </para>
138 <para>
139 The output of the above example would be something like:
140 </para>
142 <para><programlisting>
143     [1998/07/30 16:00:51, 0] file.c:function(128)
144       This is a debug message.
145 </programlisting></para>
147 <para>
148 Each call to DEBUG() creates a new header *unless* the output produced
149 by the previous call to DEBUG() did not end with a '\n'. Output to the
150 debug file is passed through a formatting buffer which is flushed
151 every time a newline is encountered. If the buffer is not empty when
152 DEBUG() is called, the new input is simply appended.
153 </para>
155 <para>
156 ...but that's really just a Kludge. It was put in place because
157 DEBUG() has been used to write partial lines. Here's a simple (dumb)
158 example of the kind of thing I'm talking about:
159 </para>
161 <para><programlisting>
162     DEBUG( 0, ("The test returned " ) );
163     if( test() )
164       DEBUG(0, ("True") );
165     else
166       DEBUG(0, ("False") );
167     DEBUG(0, (".\n") );
168 </programlisting></para>
170 <para>
171 Without the format buffer, the output (assuming test() returned true)
172 would look like this:
173 </para>
175 <para><programlisting>
176     [1998/07/30 16:00:51, 0] file.c:function(256)
177       The test returned
178     [1998/07/30 16:00:51, 0] file.c:function(258)
179       True
180     [1998/07/30 16:00:51, 0] file.c:function(261)
181       .
182 </programlisting></para>
184 <para>Which isn't much use. The format buffer kludge fixes this problem.
185 </para>
187 </sect1>
189 <sect1>
190 <title>The DEBUGADD() Macro</title>
192 <para>
193 In addition to the kludgey solution to the broken line problem
194 described above, there is a clean solution. The DEBUGADD() macro never
195 generates a header. It will append new text to the current debug
196 message even if the format buffer is empty. The syntax of the
197 DEBUGADD() macro is the same as that of the DEBUG() macro.
198 </para>
200 <para><programlisting>
201     DEBUG( 0, ("This is the first line.\n" ) );
202     DEBUGADD( 0, ("This is the second line.\nThis is the third line.\n" ) );
203 </programlisting></para>
205 <para>Produces</para>
207 <para><programlisting>
208     [1998/07/30 16:00:51, 0] file.c:function(512)
209       This is the first line.
210       This is the second line.
211       This is the third line.
212 </programlisting></para>
214 </sect1>
216 <sect1>
217 <title>The DEBUGLVL() Macro</title>
219 <para>
220 One of the problems with the DEBUG() macro was that DEBUG() lines
221 tended to get a bit long. Consider this example from
222 nmbd_sendannounce.c:
223 </para>
225 <para><programlisting>
226   DEBUG(3,("send_local_master_announcement: type %x for name %s on subnet %s for workgroup %s\n",
227             type, global_myname, subrec->subnet_name, work->work_group));
228 </programlisting></para>
230 <para>
231 One solution to this is to break it down using DEBUG() and DEBUGADD(),
232 as follows:
233 </para>
235 <para><programlisting>
236   DEBUG( 3, ( "send_local_master_announcement: " ) );
237   DEBUGADD( 3, ( "type %x for name %s ", type, global_myname ) );
238   DEBUGADD( 3, ( "on subnet %s ", subrec->subnet_name ) );
239   DEBUGADD( 3, ( "for workgroup %s\n", work->work_group ) );
240 </programlisting></para>
242 <para>
243 A similar, but arguably nicer approach is to use the DEBUGLVL() macro.
244 This macro returns True if the message level is less than or equal to
245 the global DEBUGLEVEL value, so:
246 </para>
248 <para><programlisting>
249   if( DEBUGLVL( 3 ) )
250     {
251     dbgtext( "send_local_master_announcement: " );
252     dbgtext( "type %x for name %s ", type, global_myname );
253     dbgtext( "on subnet %s ", subrec->subnet_name );
254     dbgtext( "for workgroup %s\n", work->work_group );
255     }
256 </programlisting></para>
258 <para>(The dbgtext() function is explained below.)</para>
260 <para>There are a few advantages to this scheme:</para>
261 <orderedlist>
262 <listitem><para>
263 The test is performed only once.
264 </para></listitem>
265 <listitem><para>
266 You can allocate variables off of the stack that will only be used
267 within the DEBUGLVL() block.
268 </para></listitem>
269 <listitem><para>
270 Processing that is only relevant to debug output can be contained
271 within the DEBUGLVL() block.
272 </para></listitem>
273 </orderedlist>
275 </sect1>
277 <sect1>
278 <title>New Functions</title>
280 <sect2>
281 <title>dbgtext()</title>
282 <para>
283 This function prints debug message text to the debug file (and
284 possibly to syslog) via the format buffer. The function uses a
285 variable argument list just like printf() or Debug1(). The
286 input is printed into a buffer using the vslprintf() function,
287 and then passed to format_debug_text().
289 If you use DEBUGLVL() you will probably print the body of the
290 message using dbgtext(). 
291 </para>
292 </sect2>
294 <sect2>
295 <title>dbghdr()</title>
296 <para>
297 This is the function that writes a debug message header.
298 Headers are not processed via the format buffer. Also note that
299 if the format buffer is not empty, a call to dbghdr() will not
300 produce any output. See the comments in dbghdr() for more info.
301 </para>
303 <para>
304 It is not likely that this function will be called directly. It
305 is used by DEBUG() and DEBUGADD().
306 </para>
307 </sect2>
309 <sect2>
310 <title>format_debug_text()</title>
311 <para>
312 This is a static function in debug.c. It stores the output text
313 for the body of the message in a buffer until it encounters a
314 newline. When the newline character is found, the buffer is
315 written to the debug file via the Debug1() function, and the
316 buffer is reset. This allows us to add the indentation at the
317 beginning of each line of the message body, and also ensures
318 that the output is written a line at a time (which cleans up
319 syslog output).
320 </para>
321 </sect2>
322 </sect1>
323 </chapter>