source: branches/samba-3.2.x/docs-xml/Samba3-Developers-Guide/debug.xml@ 717

Last change on this file since 717 was 203, checked in by Herwig Bauernfeind, 16 years ago

Missing 3.2.2 client and HOWTO files

File size: 8.8 KB
Line 
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>
10
11<title>The samba DEBUG system</title>
12
13<sect1>
14<title>New Output Syntax</title>
15
16<para>
17 The syntax of a debugging log file is represented as:
18</para>
19
20<para><programlisting>
21 &gt;debugfile&lt; :== { &gt;debugmsg&lt; }
22
23 &gt;debugmsg&lt; :== &gt;debughdr&lt; '\n' &gt;debugtext&lt;
24
25 &gt;debughdr&lt; :== '[' TIME ',' LEVEL ']' FILE ':' [FUNCTION] '(' LINE ')'
26
27 &gt;debugtext&lt; :== { &gt;debugline&lt; }
28
29 &gt;debugline&lt; :== TEXT '\n'
30</programlisting></para>
31
32<para>
33TEXT is a string of characters excluding the newline character.
34</para>
35
36<para>
37LEVEL is the DEBUG level of the message (an integer in the range
38 0..10).
39</para>
40
41<para>
42TIME is a timestamp.
43</para>
44
45<para>
46FILE is the name of the file from which the debug message was
47generated.
48</para>
49
50<para>
51FUNCTION is the function from which the debug message was generated.
52</para>
53
54<para>
55LINE is the line number of the debug statement that generated the
56message.
57</para>
58
59<para>Basically, what that all means is:</para>
60<orderedlist>
61<listitem><para>
62A debugging log file is made up of debug messages.
63</para></listitem>
64<listitem><para>
65Each debug message is made up of a header and text. The header is
66separated from the text by a newline.
67</para></listitem>
68<listitem><para>
69The header begins with the timestamp and debug level of the
70message enclosed in brackets. The filename, function, and line
71number at which the message was generated follow. The filename is
72terminated by a colon, and the function name is terminated by the
73parenthesis which contain the line number. Depending upon the
74compiler, 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>
78The message text is made up of zero or more lines, each terminated
79by a newline.
80</para></listitem>
81</orderedlist>
82
83<para>Here's some example output:</para>
84
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>
92
93<para>
94Note that in the above example the function names are not listed on
95the header line. That's because the example above was generated on an
96SGI Indy, and the SGI compiler doesn't support the __FUNCTION__ macro.
97</para>
98
99</sect1>
100
101<sect1>
102<title>The DEBUG() Macro</title>
103
104<para>
105Use of the DEBUG() macro is unchanged. DEBUG() takes two parameters.
106The first is the message level, the second is the body of a function
107call to the Debug1() function.
108</para>
109
110<para>That's confusing.</para>
111
112<para>Here's an example which may help a bit. If you would write</para>
113
114<para><programlisting>
115printf( "This is a %s message.\n", "debug" );
116</programlisting></para>
117
118<para>
119to send the output to stdout, then you would write
120</para>
121
122<para><programlisting>
123DEBUG( 0, ( "This is a %s message.\n", "debug" ) );
124</programlisting></para>
125
126<para>
127to send the output to the debug file. All of the normal printf()
128formatting escapes work.
129</para>
130
131<para>
132Note that in the above example the DEBUG message level is set to 0.
133Messages at level 0 always print. Basically, if the message level is
134less than or equal to the global value DEBUGLEVEL, then the DEBUG
135statement is processed.
136</para>
137
138<para>
139The output of the above example would be something like:
140</para>
141
142<para><programlisting>
143 [1998/07/30 16:00:51, 0] file.c:function(128)
144 This is a debug message.
145</programlisting></para>
146
147<para>
148Each call to DEBUG() creates a new header *unless* the output produced
149by the previous call to DEBUG() did not end with a '\n'. Output to the
150debug file is passed through a formatting buffer which is flushed
151every time a newline is encountered. If the buffer is not empty when
152DEBUG() is called, the new input is simply appended.
153</para>
154
155<para>
156...but that's really just a Kludge. It was put in place because
157DEBUG() has been used to write partial lines. Here's a simple (dumb)
158example of the kind of thing I'm talking about:
159</para>
160
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>
169
170<para>
171Without the format buffer, the output (assuming test() returned true)
172would look like this:
173</para>
174
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>
183
184<para>Which isn't much use. The format buffer kludge fixes this problem.
185</para>
186
187</sect1>
188
189<sect1>
190<title>The DEBUGADD() Macro</title>
191
192<para>
193In addition to the kludgey solution to the broken line problem
194described above, there is a clean solution. The DEBUGADD() macro never
195generates a header. It will append new text to the current debug
196message even if the format buffer is empty. The syntax of the
197DEBUGADD() macro is the same as that of the DEBUG() macro.
198</para>
199
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>
204
205<para>Produces</para>
206
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>
213
214</sect1>
215
216<sect1>
217<title>The DEBUGLVL() Macro</title>
218
219<para>
220One of the problems with the DEBUG() macro was that DEBUG() lines
221tended to get a bit long. Consider this example from
222nmbd_sendannounce.c:
223</para>
224
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>
229
230<para>
231One solution to this is to break it down using DEBUG() and DEBUGADD(),
232as follows:
233</para>
234
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>
241
242<para>
243A similar, but arguably nicer approach is to use the DEBUGLVL() macro.
244This macro returns True if the message level is less than or equal to
245the global DEBUGLEVEL value, so:
246</para>
247
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>
257
258<para>(The dbgtext() function is explained below.)</para>
259
260<para>There are a few advantages to this scheme:</para>
261<orderedlist>
262<listitem><para>
263The test is performed only once.
264</para></listitem>
265<listitem><para>
266You can allocate variables off of the stack that will only be used
267within the DEBUGLVL() block.
268</para></listitem>
269<listitem><para>
270Processing that is only relevant to debug output can be contained
271within the DEBUGLVL() block.
272</para></listitem>
273</orderedlist>
274
275</sect1>
276
277<sect1>
278<title>New Functions</title>
279
280<sect2>
281<title>dbgtext()</title>
282<para>
283This function prints debug message text to the debug file (and
284possibly to syslog) via the format buffer. The function uses a
285variable argument list just like printf() or Debug1(). The
286input is printed into a buffer using the vslprintf() function,
287and then passed to format_debug_text().
288
289If you use DEBUGLVL() you will probably print the body of the
290message using dbgtext().
291</para>
292</sect2>
293
294<sect2>
295<title>dbghdr()</title>
296<para>
297This is the function that writes a debug message header.
298Headers are not processed via the format buffer. Also note that
299if the format buffer is not empty, a call to dbghdr() will not
300produce any output. See the comments in dbghdr() for more info.
301</para>
302
303<para>
304It is not likely that this function will be called directly. It
305is used by DEBUG() and DEBUGADD().
306</para>
307</sect2>
308
309<sect2>
310<title>format_debug_text()</title>
311<para>
312This is a static function in debug.c. It stores the output text
313for the body of the message in a buffer until it encounters a
314newline. When the newline character is found, the buffer is
315written to the debug file via the Debug1() function, and the
316buffer is reset. This allows us to add the indentation at the
317beginning of each line of the message body, and also ensures
318that the output is written a line at a time (which cleans up
319syslog output).
320</para>
321</sect2>
322</sect1>
323</chapter>
Note: See TracBrowser for help on using the repository browser.