~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to docs-xml/Samba3-Developers-Guide/debug.xml

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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>
 
33
TEXT is a string of characters excluding the newline character.
 
34
</para>
 
35
 
 
36
<para>
 
37
LEVEL is the DEBUG level of the message (an integer in the range
 
38
                0..10).
 
39
</para>
 
40
 
 
41
<para>
 
42
TIME is a timestamp.
 
43
</para>
 
44
 
 
45
<para>
 
46
FILE is the name of the file from which the debug message was
 
47
generated.
 
48
</para>
 
49
 
 
50
<para>
 
51
FUNCTION is the function from which the debug message was generated.
 
52
</para>
 
53
 
 
54
<para>
 
55
LINE is the line number of the debug statement that generated the
 
56
message.
 
57
</para>
 
58
 
 
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>
 
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>
 
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>
 
98
 
 
99
</sect1>
 
100
 
 
101
<sect1>
 
102
<title>The DEBUG() Macro</title>
 
103
 
 
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>
 
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>
 
115
printf( "This is a %s message.\n", "debug" );
 
116
</programlisting></para>
 
117
 
 
118
<para>
 
119
to send the output to stdout, then you would write
 
120
</para>
 
121
 
 
122
<para><programlisting>
 
123
DEBUG( 0, ( "This is a %s message.\n", "debug" ) );
 
124
</programlisting></para>
 
125
 
 
126
<para>
 
127
to send the output to the debug file.  All of the normal printf()
 
128
formatting escapes work.
 
129
</para>
 
130
 
 
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>
 
137
 
 
138
<para>
 
139
The 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>
 
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>
 
154
 
 
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>
 
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>
 
171
Without the format buffer, the output (assuming test() returned true)
 
172
would 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>
 
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>
 
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>
 
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>
 
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>
 
231
One solution to this is to break it down using DEBUG() and DEBUGADD(),
 
232
as 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>
 
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>
 
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>
 
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>
 
274
 
 
275
</sect1>
 
276
 
 
277
<sect1>
 
278
<title>New Functions</title>
 
279
 
 
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().
 
288
 
 
289
If you use DEBUGLVL() you will probably print the body of the
 
290
message using dbgtext(). 
 
291
</para>
 
292
</sect2>
 
293
 
 
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>
 
302
 
 
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>
 
308
 
 
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>