mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-07 10:04:07 +00:00
Big update to the debug logging section.
This commit is contained in:
parent
3d0e432678
commit
036bb85bb5
|
@ -1,33 +1,36 @@
|
||||||
<chapter id="debugging">
|
<chapter id="debugging">
|
||||||
<title>Debug Logging</title>
|
<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>
|
<para>
|
||||||
It is possible to turn on and of debugging output from
|
To better manage the large volume of debugging messages that
|
||||||
within the debugger using the set command. Please see the
|
Wine can generate, we divide the messages on a component basis,
|
||||||
WineDbg Command Reference section for how to do this.
|
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>
|
</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">
|
<sect1 id="dbg-classes">
|
||||||
<title>Debugging classes</title>
|
<title>Debugging classes</title>
|
||||||
|
|
||||||
<para>
|
<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>
|
</para>
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
@ -38,22 +41,15 @@
|
||||||
features, known bugs, etc. They serve as a constant and
|
features, known bugs, etc. They serve as a constant and
|
||||||
active reminder of what needs to be done.
|
active reminder of what needs to be done.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
|
||||||
Examples: stubs, semi-implemented features, etc.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>ERR</literal></term>
|
<term><literal>ERR</literal></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Messages in this class relate to serious errors in
|
Messages in this class indicate serious errors in
|
||||||
Wine. This sort of messages signal an inconsistent
|
Wine, such as as conditions that should never happen
|
||||||
internal state, or more general, a condition which
|
by design.
|
||||||
should never happen by design.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Examples: unexpected change in internal state, etc.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -62,15 +58,11 @@
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
These are warning messages. You should report a
|
These are warning messages. You should report a
|
||||||
warning when something unwanted happen but the
|
warning when something unwanted happens, and the
|
||||||
function behaves properly. That is, output a warning
|
function can not deal with the condition. This
|
||||||
when you encounter something unexpected (ex: could not
|
is seldomly used since proper functions can usually
|
||||||
open a file) but the function deals correctly with the
|
report failures back to the caller. Think twice before
|
||||||
situation (that is, according to the docs). If you do
|
making the message a warning.
|
||||||
not deal correctly with it, output a fixme.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Examples: fail to access a resource required by the app.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -79,13 +71,18 @@
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
These are detailed debugging messages that are mainly
|
These are detailed debugging messages that are mainly
|
||||||
useful to debug a component. These are usually turned
|
useful to debug a component. These are turned off unless
|
||||||
off.
|
explicitly enabled.
|
||||||
</para>
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>MESSAGE</literal></term>
|
||||||
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Examples: everything else that does not fall in one of
|
There messages are intended for the end user. They do not
|
||||||
the above mentioned categories and the user does not
|
belong to any channel. As with warnings, you will seldomly
|
||||||
need to know about it.
|
need to output such messages.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -96,35 +93,18 @@
|
||||||
<title>Debugging channels</title>
|
<title>Debugging channels</title>
|
||||||
|
|
||||||
<para>
|
<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
|
Each component is assigned a debugging channel. The
|
||||||
identifier of the channel must be a valid C identifier but
|
identifier of the channel must be a valid C identifier
|
||||||
note that it may also be a reserved word like
|
(reserved word like <type>int</type> or <type>static</type>
|
||||||
<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>
|
||||||
<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>
|
<para>
|
||||||
Typically, a file contains code pertaining to only one component,
|
Typically, a file contains code pertaining to only one component,
|
||||||
and as such, there is only one channel to output to. To simplify
|
and as such, there is only one channel to output to. You can declare
|
||||||
usage, you can declare that channel at the beginning of the file,
|
a default chanel for the file using the
|
||||||
and simply write FIXMEs, ERRs, etc. as such:
|
<symbol>WINE_DEFAULT_DEBUG_CHANNEL()</symbol> macro:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
@ -160,48 +140,29 @@ WINE_DECLARE_DEBUG_CHANNEL(zzz);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</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>
|
||||||
|
|
||||||
<sect1 id="dbg-checking">
|
<sect1 id="dbg-checking">
|
||||||
<title>Are we debugging?</title>
|
<title>Are we debugging?</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
To test whether the debugging output of class
|
To test whether the debugging channel <literal>xxx</literal> is
|
||||||
<literal>yyy</literal> on channel <literal>xxx</literal> is
|
enabled, use the <symbol>TRACE_ON</symbol>, <symbol>WARN_ON</symbol>,
|
||||||
enabled, use:
|
<symbol>FIXME_ON</symbol>, or <symbol>ERR_ON</symbol> macros. For
|
||||||
</para>
|
example:
|
||||||
<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>
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
if(TRACE_ON(atom)){
|
if(TRACE_ON(atom)){
|
||||||
...blah...
|
...blah...
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
You should normally need to test only if <literal>TRACE_ON</literal>,
|
||||||
<note>
|
all the others are very seldomly used. With careful coding, you
|
||||||
<para>
|
can avoid the use of these macros, which is generally desired.
|
||||||
You should normally need to test only if
|
</para>
|
||||||
<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>
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="dbg-resource-ids">
|
<sect1 id="dbg-helpers">
|
||||||
<title>Resource identifiers</title>
|
<title>Helper functions</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Resource identifiers can be either strings or numbers. To
|
Resource identifiers can be either strings or numbers. To
|
||||||
|
@ -241,10 +202,32 @@ LPSTR debugres(const void *id);
|
||||||
|
|
||||||
TRACE("resource is %s", debugres(myresource));
|
TRACE("resource is %s", debugres(myresource));
|
||||||
</programlisting>
|
</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>
|
||||||
|
|
||||||
<sect1 id="dbg-param">
|
<sect1 id="dbg-control">
|
||||||
<title>The <parameter>--debugmsg</parameter> command line option</title>
|
<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>
|
<para>
|
||||||
The <parameter>--debugmsg</parameter> command line
|
The <parameter>--debugmsg</parameter> command line
|
||||||
|
@ -385,7 +368,7 @@ where:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<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>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -418,99 +401,10 @@ FIXME("(%x, %d, ...): stub\n", par1, par2, ...);
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
if you want to name a value, use <literal>=</literal> and
|
if you want to name a parameter, use <literal>=</literal> :
|
||||||
NOT <literal>:</literal>. That is, instead of saying:
|
|
||||||
<programlisting>
|
|
||||||
FIXME("(fd: %d, file: %s): stub\n", fd, name);
|
|
||||||
</programlisting>
|
|
||||||
say:
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
FIXME("(fd=%d, file=%s): stub\n", fd, name);
|
FIXME("(fd=%d, file=%s): stub\n", fd, name);
|
||||||
</programlisting>
|
</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>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
Loading…
Reference in a new issue