| 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.74.0"><link rel="home" 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#id2556945">New Output Syntax</a></span></dt><dt><span class="sect1"><a href="debug.html#id2557054">The DEBUG() Macro</a></span></dt><dt><span class="sect1"><a href="debug.html#id2557160">The DEBUGADD() Macro</a></span></dt><dt><span class="sect1"><a href="debug.html#id2557196">The DEBUGLVL() Macro</a></span></dt><dt><span class="sect1"><a href="debug.html#id2557287">New Functions</a></span></dt><dd><dl><dt><span class="sect2"><a href="debug.html#id2557292">dbgtext()</a></span></dt><dt><span class="sect2"><a href="debug.html#id2557308">dbghdr()</a></span></dt><dt><span class="sect2"><a href="debug.html#id2557327">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="id2556945"></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>
|
|---|
| 14 | TEXT is a string of characters excluding the newline character.
|
|---|
| 15 | </p><p>
|
|---|
| 16 | LEVEL is the DEBUG level of the message (an integer in the range
|
|---|
| 17 | 0..10).
|
|---|
| 18 | </p><p>
|
|---|
| 19 | TIME is a timestamp.
|
|---|
| 20 | </p><p>
|
|---|
| 21 | FILE is the name of the file from which the debug message was
|
|---|
| 22 | generated.
|
|---|
| 23 | </p><p>
|
|---|
| 24 | FUNCTION is the function from which the debug message was generated.
|
|---|
| 25 | </p><p>
|
|---|
| 26 | LINE is the line number of the debug statement that generated the
|
|---|
| 27 | message.
|
|---|
| 28 | </p><p>Basically, what that all means is:</p><div class="orderedlist"><ol type="1"><li><p>
|
|---|
| 29 | A debugging log file is made up of debug messages.
|
|---|
| 30 | </p></li><li><p>
|
|---|
| 31 | Each debug message is made up of a header and text. The header is
|
|---|
| 32 | separated from the text by a newline.
|
|---|
| 33 | </p></li><li><p>
|
|---|
| 34 | The header begins with the timestamp and debug level of the
|
|---|
| 35 | message enclosed in brackets. The filename, function, and line
|
|---|
| 36 | number at which the message was generated follow. The filename is
|
|---|
| 37 | terminated by a colon, and the function name is terminated by the
|
|---|
| 38 | parenthesis which contain the line number. Depending upon the
|
|---|
| 39 | compiler, 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>
|
|---|
| 42 | The message text is made up of zero or more lines, each terminated
|
|---|
| 43 | by 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>
|
|---|
| 51 | Note that in the above example the function names are not listed on
|
|---|
| 52 | the header line. That's because the example above was generated on an
|
|---|
| 53 | SGI 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="id2557054"></a>The DEBUG() Macro</h2></div></div></div><p>
|
|---|
| 55 | Use of the DEBUG() macro is unchanged. DEBUG() takes two parameters.
|
|---|
| 56 | The first is the message level, the second is the body of a function
|
|---|
| 57 | call 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">
|
|---|
| 59 | printf( "This is a %s message.\n", "debug" );
|
|---|
| 60 | </pre><p>
|
|---|
| 61 | to send the output to stdout, then you would write
|
|---|
| 62 | </p><pre class="programlisting">
|
|---|
| 63 | DEBUG( 0, ( "This is a %s message.\n", "debug" ) );
|
|---|
| 64 | </pre><p>
|
|---|
| 65 | to send the output to the debug file. All of the normal printf()
|
|---|
| 66 | formatting escapes work.
|
|---|
| 67 | </p><p>
|
|---|
| 68 | Note that in the above example the DEBUG message level is set to 0.
|
|---|
| 69 | Messages at level 0 always print. Basically, if the message level is
|
|---|
| 70 | less than or equal to the global value DEBUGLEVEL, then the DEBUG
|
|---|
| 71 | statement is processed.
|
|---|
| 72 | </p><p>
|
|---|
| 73 | The 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>
|
|---|
| 78 | Each call to DEBUG() creates a new header *unless* the output produced
|
|---|
| 79 | by the previous call to DEBUG() did not end with a '\n'. Output to the
|
|---|
| 80 | debug file is passed through a formatting buffer which is flushed
|
|---|
| 81 | every time a newline is encountered. If the buffer is not empty when
|
|---|
| 82 | DEBUG() 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
|
|---|
| 85 | DEBUG() has been used to write partial lines. Here's a simple (dumb)
|
|---|
| 86 | example 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>
|
|---|
| 95 | Without the format buffer, the output (assuming test() returned true)
|
|---|
| 96 | would 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="id2557160"></a>The DEBUGADD() Macro</h2></div></div></div><p>
|
|---|
| 106 | In addition to the kludgey solution to the broken line problem
|
|---|
| 107 | described above, there is a clean solution. The DEBUGADD() macro never
|
|---|
| 108 | generates a header. It will append new text to the current debug
|
|---|
| 109 | message even if the format buffer is empty. The syntax of the
|
|---|
| 110 | DEBUGADD() 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="id2557196"></a>The DEBUGLVL() Macro</h2></div></div></div><p>
|
|---|
| 120 | One of the problems with the DEBUG() macro was that DEBUG() lines
|
|---|
| 121 | tended to get a bit long. Consider this example from
|
|---|
| 122 | nmbd_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>
|
|---|
| 127 | One solution to this is to break it down using DEBUG() and DEBUGADD(),
|
|---|
| 128 | as follows:
|
|---|
| 129 | </p><pre class="programlisting">
|
|---|
|
|---|