| <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 debuger using the set command. Please see the |
| WineDbg Command Reference section for how to do this. |
| </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: |
| </para> |
| <variablelist> |
| <varlistentry> |
| <term><literal>FIXME</literal></term> |
| <listitem> |
| <para> |
| Messages in this class are meant to signal unimplemented |
| 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. |
| </para> |
| </listitem> |
| </varlistentry> |
| <varlistentry> |
| <term><literal>WARN</literal></term> |
| <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. |
| </para> |
| </listitem> |
| </varlistentry> |
| <varlistentry> |
| <term><literal>TRACE</literal></term> |
| <listitem> |
| <para> |
| These are detailed debugging messages that are mainly |
| useful to debug a component. These are usually turned |
| off. |
| </para> |
| <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. |
| </para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </sect1> |
| |
| <sect1 id="dbg-channels"> |
| <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>. |
| </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: |
| |
| <programlisting> |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(xxx); |
| ... |
| |
| FIXME("some unimplemented feature", ...); |
| ... |
| if (zero != 0) |
| ERR("This should never be non-null: %d", zero); |
| ... |
| </programlisting> |
| </para> |
| <para> |
| In rare situations there is a need to output to more than one |
| debug channel per file. In such cases, you need to declare |
| all the additional channels at the top of the file, and |
| use the _-version of the debugging macros: |
| <programlisting> |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(xxx); |
| WINE_DECLARE_DEBUG_CHANNEL(yyy); |
| WINE_DECLARE_DEBUG_CHANNEL(zzz); |
| ... |
| |
| FIXME("this one goes to xxx channel"); |
| ... |
| FIXME_(yyy)("Some other msg for the yyy channel"); |
| ... |
| WARN_(zzz)("And yet another msg on another channel!"); |
| ... |
| </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> |
| <programlisting> |
| if(TRACE_ON(atom)){ |
| ...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> |
| </sect1> |
| |
| <sect1 id="dbg-resource-ids"> |
| <title>Resource identifiers</title> |
| |
| <para> |
| Resource identifiers can be either strings or numbers. To |
| make life a bit easier for outputting these beasts (and to |
| help you avoid the need to build the message in memory), I |
| introduced a new function called <function>debugres</function>. |
| </para> |
| <para> |
| The function is defined in <filename>wine/debug.h</filename> |
| and has the following prototype: |
| </para> |
| <programlisting> |
| LPSTR debugres(const void *id); |
| </programlisting> |
| <para> |
| It takes a pointer to the resource id and returns a nicely |
| formatted string of the identifier (which can be a string or |
| a number, depending on the value of the high word). |
| Numbers are formatted as such: |
| </para> |
| <programlisting> |
| #xxxx |
| </programlisting> |
| <para> |
| while strings as: |
| </para> |
| <programlisting> |
| 'some-string' |
| </programlisting> |
| <para> |
| Simply use it in your code like this: |
| </para> |
| <programlisting> |
| #include "wine/debug.h" |
| |
| ... |
| |
| TRACE("resource is %s", debugres(myresource)); |
| </programlisting> |
| </sect1> |
| |
| <sect1 id="dbg-param"> |
| <title>The <parameter>--debugmsg</parameter> command line option</title> |
| |
| <para> |
| The <parameter>--debugmsg</parameter> command line |
| option controls the output of the debug messages. |
| It has the following syntax: |
| <parameter>--debugmsg [yyy]#xxx[,[yyy1]#xxx1]*</parameter> |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| where |
| <literal>#</literal> is either <literal>+</literal> or |
| <literal>-</literal> |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| when the optional class argument (<literal>yyy</literal>) |
| is not present, then the statement will |
| enable(<literal>+</literal>)/disable(<literal>-</literal>) |
| all messages for the given channel (<literal>xxx</literal>) |
| on all classes. For example: |
| </para> |
| <programlisting> |
| --debugmsg +reg,-file |
| </programlisting> |
| <para> |
| enables all messages on the <literal>reg</literal> |
| channel and disables all messages on the |
| <literal>file</literal> channel. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| when the optional class argument (<literal>yyy</literal>) |
| is present, then the statement will enable |
| (<literal>+</literal>)/disable(<literal>-</literal>) |
| messages for the given channel (<literal>xxx</literal>) |
| only on the given class. For example: |
| </para> |
| <programlisting> |
| --debugmsg trace+reg,warn-file |
| </programlisting> |
| <para> |
| enables trace messages on the <literal>reg</literal> |
| channel and disables warning messages on the |
| <literal>file</literal> channel. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| also, the pseudo-channel all is also supported and it |
| has the intuitive semantics: |
| </para> |
| <screen> |
| --debugmsg +all -- enables all debug messages |
| --debugmsg -all -- disables all debug messages |
| --debugmsg yyy+all -- enables debug messages for class yyy on all |
| channels. |
| --debugmsg yyy-all -- disables debug messages for class yyy on all |
| channels. |
| </screen> |
| <para> |
| So, for example: |
| </para> |
| <screen> |
| --debugmsg warn-all -- disables all warning messages. |
| </screen> |
| </listitem> |
| </itemizedlist> |
| |
| <para> |
| Also, note that at the moment: |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para>the <literal>FIXME</literal> and <literal>ERR</literal> |
| classes are enabled by default</para> |
| </listitem> |
| <listitem> |
| <para>the <literal>TRACE</literal> and |
| <literal>WARN</literal> classes are disabled by |
| default</para> |
| </listitem> |
| </itemizedlist> |
| </sect1> |
| |
| <sect1 id="dbg-compiling"> |
| <title>Compiling Out Debugging Messages</title> |
| |
| <para> |
| To compile out the debugging messages, provide |
| <command>configure</command> with the following options: |
| </para> |
| <screen> |
| --disable-debug -- turns off TRACE, WARN, and FIXME (and DUMP). |
| --disable-trace -- turns off TRACE only. |
| </screen> |
| <para> |
| This will result in an executable that, when stripped, is |
| about 15%-20% smaller. Note, however, that you will not be |
| able to effectively debug Wine without these messages. |
| </para> |
| <para> |
| This feature has not been extensively tested--it may subtly |
| break some things. |
| </para> |
| </sect1> |
| |
| <sect1 id="dbg-notes"> |
| <title>A Few Notes on Style</title> |
| |
| <para> |
| This new scheme makes certain things more consistent but |
| there is still room for improvement by using a common style |
| of debug messages. Before I continue, let me note that the |
| output format is the following: |
| </para> |
| <screen> |
| yyy:xxx:fff <message> |
| |
| where: |
| yyy = the class (fixme, err, warn, trace) |
| xxx = the channel (atom, win, font, etc) |
| fff = the function name |
| </screen> |
| <para> |
| these fields are output automatically. All you have to |
| provide is the <message> part. |
| </para> |
| <para> |
| So here are some ideas: |
| </para> |
| |
| <itemizedlist> |
| <listitem> |
| <para>do NOT include the name of the function: it is included automatically</para> |
| </listitem> |
| <listitem> |
| <para> |
| if you want to output the parameters of the function, do |
| it as the first thing and include them in parentheses, |
| like this: |
| <programlisting> |
| TRACE("(%d, %p, ...)\n", par1, par2, ...); |
| </programlisting> |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| for stubs, you should output a <literal>FIXME</literal> |
| message. I suggest this style: |
| <programlisting> |
| FIXME("(%x, %d, ...): stub\n", par1, par2, ...); |
| </programlisting> |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| try to output one line per message. That is, the format |
| string should contain only one <literal>\n</literal> and it |
| should always appear at the end of the string. (there are |
| many reasons for this requirement, one of them is that |
| each debug macro adds things to the beginning of the line) |
| </para> |
| </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: |
| <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> |
| </sect1> |
| |
| </chapter> |
| |
| <!-- Keep this comment at the end of the file |
| Local variables: |
| mode: sgml |
| sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "") |
| End: |
| --> |