Big update to the debug logging section.
This commit is contained in:
parent
3d0e432678
commit
036bb85bb5
|
@ -1,33 +1,36 @@
|
|||
<chapter id="debugging">
|
||||
<title>Debug Logging</title>
|
||||
|
||||
<para>
|
||||
Written by &name-dimitrie-paun; <email>&email-dimitrie-paun;</email>, 28 Mar 1998
|
||||
</para>
|
||||
<para>
|
||||
(Extracted from <filename>wine/documentation/debug-msgs</filename>)
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
It is possible to turn on and of debugging output from
|
||||
within the debugger using the set command. Please see the
|
||||
WineDbg Command Reference section for how to do this.
|
||||
To better manage the large volume of debugging messages that
|
||||
Wine can generate, we divide the messages on a component basis,
|
||||
and classify them based on the severity of the reported problem.
|
||||
Therefore a message belongs to a <emphasis>channel</emphasis>
|
||||
and a <emphasis>class</emphasis> respectively.
|
||||
</para>
|
||||
<para>
|
||||
This section will describe the debugging classes, how you can
|
||||
create a new debugging channel, what the debugging API is,
|
||||
and how you can control the debugging output. A picture is
|
||||
worth a thousand words, so here are a few examples of the
|
||||
debugging API in action:
|
||||
<screen>
|
||||
ERR("lock_count == 0 ... please report\n");
|
||||
FIXME("Unsupported RTL style!\n");
|
||||
WARN(": file seems to be truncated!\n");
|
||||
TRACE("[%p]: new horz extent = %d\n", hwnd, extent );
|
||||
MESSAGE( "Could not create graphics driver '%s'\n", buffer );
|
||||
</screen>
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<important>
|
||||
<para>
|
||||
At the end of the document, there is a "Style Guide" for
|
||||
debugging messages. Please read it.
|
||||
</para>
|
||||
</important>
|
||||
|
||||
<sect1 id="dbg-classes">
|
||||
<title>Debugging classes</title>
|
||||
|
||||
<para>
|
||||
There are 4 types (or classes) of messages:
|
||||
A debugging class categorizes a message based on the severity
|
||||
of the reported problem. There is a fixed set of classes, and
|
||||
you must carefuly choose the appropriate one for your messages.
|
||||
There are five classes of messages:
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
|
@ -38,22 +41,15 @@
|
|||
features, known bugs, etc. They serve as a constant and
|
||||
active reminder of what needs to be done.
|
||||
</para>
|
||||
<para>
|
||||
Examples: stubs, semi-implemented features, etc.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>ERR</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Messages in this class relate to serious errors in
|
||||
Wine. This sort of messages signal an inconsistent
|
||||
internal state, or more general, a condition which
|
||||
should never happen by design.
|
||||
</para>
|
||||
<para>
|
||||
Examples: unexpected change in internal state, etc.
|
||||
Messages in this class indicate serious errors in
|
||||
Wine, such as as conditions that should never happen
|
||||
by design.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -62,15 +58,11 @@
|
|||
<listitem>
|
||||
<para>
|
||||
These are warning messages. You should report a
|
||||
warning when something unwanted happen but the
|
||||
function behaves properly. That is, output a warning
|
||||
when you encounter something unexpected (ex: could not
|
||||
open a file) but the function deals correctly with the
|
||||
situation (that is, according to the docs). If you do
|
||||
not deal correctly with it, output a fixme.
|
||||
</para>
|
||||
<para>
|
||||
Examples: fail to access a resource required by the app.
|
||||
warning when something unwanted happens, and the
|
||||
function can not deal with the condition. This
|
||||
is seldomly used since proper functions can usually
|
||||
report failures back to the caller. Think twice before
|
||||
making the message a warning.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -79,13 +71,18 @@
|
|||
<listitem>
|
||||
<para>
|
||||
These are detailed debugging messages that are mainly
|
||||
useful to debug a component. These are usually turned
|
||||
off.
|
||||
useful to debug a component. These are turned off unless
|
||||
explicitly enabled.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>MESSAGE</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Examples: everything else that does not fall in one of
|
||||
the above mentioned categories and the user does not
|
||||
need to know about it.
|
||||
There messages are intended for the end user. They do not
|
||||
belong to any channel. As with warnings, you will seldomly
|
||||
need to output such messages.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -96,35 +93,18 @@
|
|||
<title>Debugging channels</title>
|
||||
|
||||
<para>
|
||||
To better manage the large volume of debugging messages that
|
||||
Wine can generate, we divide them also on a component basis.
|
||||
Each component is assigned a debugging channel. The
|
||||
identifier of the channel must be a valid C identifier but
|
||||
note that it may also be a reserved word like
|
||||
<type>int</type> or <type>static</type>.
|
||||
identifier of the channel must be a valid C identifier
|
||||
(reserved word like <type>int</type> or <type>static</type>
|
||||
are premitted). To use a new channel, simply use it in
|
||||
your code. It will be picked up automatically by the build process.
|
||||
</para>
|
||||
<para>
|
||||
Examples of debugging channels:
|
||||
<simplelist type="inline">
|
||||
<member><literal>reg</literal></member>
|
||||
<member><literal>updown</literal></member>
|
||||
<member><literal>string</literal></member>
|
||||
</simplelist>
|
||||
</para>
|
||||
<para>
|
||||
We will refer to a generic channel as <literal>xxx</literal>.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="dbg-using">
|
||||
<title>How to use it</title>
|
||||
|
||||
<para>
|
||||
Typically, a file contains code pertaining to only one component,
|
||||
and as such, there is only one channel to output to. To simplify
|
||||
usage, you can declare that channel at the beginning of the file,
|
||||
and simply write FIXMEs, ERRs, etc. as such:
|
||||
|
||||
and as such, there is only one channel to output to. You can declare
|
||||
a default chanel for the file using the
|
||||
<symbol>WINE_DEFAULT_DEBUG_CHANNEL()</symbol> macro:
|
||||
<programlisting>
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
@ -160,48 +140,29 @@ WINE_DECLARE_DEBUG_CHANNEL(zzz);
|
|||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you need to declare a new debugging channel, simply use it in
|
||||
your code. It will be picked up automatically by the build process.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="dbg-checking">
|
||||
<title>Are we debugging?</title>
|
||||
|
||||
<para>
|
||||
To test whether the debugging output of class
|
||||
<literal>yyy</literal> on channel <literal>xxx</literal> is
|
||||
enabled, use:
|
||||
</para>
|
||||
<screen>
|
||||
TRACE_ON to test if TRACE is enabled
|
||||
WARN_ON to test if WARN is enabled
|
||||
FIXME_ON to test if FIXME is enabled
|
||||
ERR_ON to test if ERR is enabled
|
||||
</screen>
|
||||
<para>
|
||||
Examples:
|
||||
</para>
|
||||
To test whether the debugging channel <literal>xxx</literal> is
|
||||
enabled, use the <symbol>TRACE_ON</symbol>, <symbol>WARN_ON</symbol>,
|
||||
<symbol>FIXME_ON</symbol>, or <symbol>ERR_ON</symbol> macros. For
|
||||
example:
|
||||
<programlisting>
|
||||
if(TRACE_ON(atom)){
|
||||
...blah...
|
||||
...blah...
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
You should normally need to test only if
|
||||
<literal>TRACE_ON</literal>. At present, none of the other
|
||||
3 tests (except for <literal>ERR_ON</literal> which is
|
||||
used only once!) are used in Wine.
|
||||
</para>
|
||||
</note>
|
||||
You should normally need to test only if <literal>TRACE_ON</literal>,
|
||||
all the others are very seldomly used. With careful coding, you
|
||||
can avoid the use of these macros, which is generally desired.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="dbg-resource-ids">
|
||||
<title>Resource identifiers</title>
|
||||
<sect1 id="dbg-helpers">
|
||||
<title>Helper functions</title>
|
||||
|
||||
<para>
|
||||
Resource identifiers can be either strings or numbers. To
|
||||
|
@ -241,10 +202,32 @@ LPSTR debugres(const void *id);
|
|||
|
||||
TRACE("resource is %s", debugres(myresource));
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Many times strings need to be massaged before output:
|
||||
they may be <literal>NULL</literal>, contain control
|
||||
characters, or they may be too long. Similarly, Unicode
|
||||
strings need to be converted to ASCII for usage with
|
||||
the debugging API. For all this, you can use the
|
||||
<function>debugstr_[aw]n?</function> familly of functions:
|
||||
<programlisting>
|
||||
HANDLE32 WINAPI YourFunc(LPCSTR s)
|
||||
{
|
||||
FIXME("(%s): stub\n", debugstr_a(s));
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="dbg-param">
|
||||
<title>The <parameter>--debugmsg</parameter> command line option</title>
|
||||
<sect1 id="dbg-control">
|
||||
<title>Controlling the debugging output</title>
|
||||
|
||||
<para>
|
||||
It is possible to turn on and off debugging output from
|
||||
within the debugger using the set command. Please see the
|
||||
WineDbg Command Reference section for how to do this.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <parameter>--debugmsg</parameter> command line
|
||||
|
@ -385,7 +368,7 @@ where:
|
|||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
do NOT include the name of the function: it is included automatically
|
||||
do not include the name of the function: it is included automatically
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
@ -418,99 +401,10 @@ FIXME("(%x, %d, ...): stub\n", par1, par2, ...);
|
|||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
if you want to name a value, use <literal>=</literal> and
|
||||
NOT <literal>:</literal>. That is, instead of saying:
|
||||
<programlisting>
|
||||
FIXME("(fd: %d, file: %s): stub\n", fd, name);
|
||||
</programlisting>
|
||||
say:
|
||||
if you want to name a parameter, use <literal>=</literal> :
|
||||
<programlisting>
|
||||
FIXME("(fd=%d, file=%s): stub\n", fd, name);
|
||||
</programlisting>
|
||||
use <literal>:</literal> to separate categories.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
try to avoid the style:
|
||||
<programlisting>
|
||||
FIXME(xxx, "(fd=%d, file=%s)\n", fd, name);
|
||||
</programlisting>
|
||||
instead use:
|
||||
<programlisting>
|
||||
FIXME(xxx, "(fd=%d, file=%s): stub\n", fd, name);
|
||||
</programlisting>
|
||||
The reason is that if you want to <command>grep</command>
|
||||
for things, you would search for <literal>FIXME</literal>
|
||||
but in the first case there is no additional information
|
||||
available, where in the second one, there is (e.g. the word
|
||||
stub)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
if you output a string s that might contain control
|
||||
characters, or if <parameter>s</parameter> may be
|
||||
<literal>NULL</literal>, use
|
||||
<function>debugstr_a</function> (for ASCII strings, or
|
||||
<function>debugstr_w</function> for Unicode strings) to
|
||||
convert <parameter>s</parameter> to a C string, like this:
|
||||
<programlisting>
|
||||
HANDLE32 WINAPI YourFunc(LPCSTR s)
|
||||
{
|
||||
FIXME("(%s): stub\n", debugstr_a(s));
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
if you want to output a resource identifier, use debugres to
|
||||
convert it to a string first, like this:
|
||||
<programlisting>
|
||||
HANDLE32 WINAPI YourFunc(LPCSTR res)
|
||||
{
|
||||
FIXME("(res=%s): stub\n", debugres(s));
|
||||
}
|
||||
</programlisting>
|
||||
if the resource identifier is a <type>SEGPTR</type>, use
|
||||
<function>PTR_SEG_TO_LIN</function> to get a
|
||||
liner pointer first:
|
||||
<programlisting>
|
||||
HRSRC16 WINAPI FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type )
|
||||
{
|
||||
[...]
|
||||
TRACE(resource, "module=%04x name=%s type=%s\n",
|
||||
hModule, debugres(PTR_SEG_TO_LIN(name)),
|
||||
debugres(PTR_SEG_TO_LIN(type)) );
|
||||
[...]
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
for messages intended for the user (specifically those that
|
||||
report errors in the wine config file), use the
|
||||
<literal>MSG</literal> macro. Use it like a
|
||||
<function>printf</function>:
|
||||
<programlisting>
|
||||
MSG( "Definition of drive %d is incorrect!\n", drive );
|
||||
</programlisting>
|
||||
However, note that there are <emphasis>very</emphasis> few
|
||||
valid uses of this macro. Most messages are debugging
|
||||
messages, so chances are you will not need to use this
|
||||
macro. Grep the source to get an idea where it is
|
||||
appropriate to use it.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
For structure dumps, use the <function>DUMP</function>
|
||||
macro. Use it like a <function>printf</function>, just like
|
||||
the <literal>MSG</literal> macro. Similarly, there are only
|
||||
a few valid uses of this macro. Grep the source to see when
|
||||
to use it.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
|
Loading…
Reference in New Issue