GCOV documentation

Aaron Arvey aarvey at cs.hmc.edu
Mon Apr 18 18:39:27 CDT 2005


Here is a patch which describes how to use gcov with wine.

Changelog:
  * winedev-otherdebug.sgml
    added section "Which code has been tested?" describing gcov usage

Signed-off-by: Aaron Arvey <aarvey at cs.hmc.edu>
-------------- next part --------------
Index: documentation/winedev-otherdebug.sgml
===================================================================
RCS file: /home/wine/wine/documentation/winedev-otherdebug.sgml,v
retrieving revision 1.1
diff -u -3 -p -u -r1.1 winedev-otherdebug.sgml
--- documentation/winedev-otherdebug.sgml	26 Oct 2004 22:45:47 -0000	1.1
+++ documentation/winedev-otherdebug.sgml	18 Apr 2005 23:27:44 -0000
@@ -497,6 +497,183 @@ cvs update -PAd -D "2004-08-23 15:17:25 
 	</listitem>
       </orderedlist>
     </sect1>
+    <sect1>
+      <title>Which code has been tested?</title>
+      <para>
+        Deciding what code should be tested next can be a difficult
+        decision.  And in any given project, there is always code that
+        isn't tested where bugs could be lurking.  This section goes
+        over how to identify these sections using a tool called gcov.
+      </para>
+      <para>
+        To use gcov on wine, do the following:
+      </para>
+      <orderedlist>
+        <listitem>
+         <para>
+           In order to activate code coverage in the wine source code,
+           when running <command>make</command> set
+           <literal>CFLAGS</literal> like so <command>make
+           CFLAGS="-fprofile-arcs -ftest-coverage"</command>.  Note that
+           this can be done at any directory level.  Since compile 
+           and run time are significantly  increased by these flags, you
+           may want to only use these flags inside a given dll directory.
+         </para>
+       </listitem>
+        <listitem>
+         <para>
+           Run any application or test suite.
+         </para>
+       </listitem>
+        <listitem>
+         <para>
+           Run gcov on the file which you would like to know more
+           about code coverage.
+         </para>
+       </listitem>
+      </orderedlist>
+      <para>
+        The following is an example situation when using gcov to
+        determine the coverage of a file could be helpful.  We'll use
+        the <filename>dlls/lzexpand/lzexpand_main.c.</filename> file.
+        At one time the code in this file was not fully tested (as it
+        may still be).  For example at the time of this writing, the
+        function <function>LZOpenFileA</function> had the following
+        lines in it:
+        <screen>
+if ((mode&~0x70)!=OF_READ)
+        return fd;
+if (fd==HFILE_ERROR)
+        return HFILE_ERROR;
+cfd=LZInit(fd);
+if ((INT)cfd <= 0) return fd;
+return cfd;
+        </screen>
+        Currently there are a few tests written to test this function;
+        however, these tests don't check that everything is correct.
+        For instance, <constant>HFILE_ERROR</constant> may be the wrong
+        error code to return.  Using gcov and directed tests, we can
+        validate the correctness of this line of code.  First, we see
+        what has been tested already by running gcov on the file. 
+        To do this, do the following:
+        <screen>
+cvs checkout wine
+mkdir build
+cd build
+../wine/configure
+make depend && make CFLAGS="-fprofile-arcs -ftest-coverage"
+cd dlls/lxexpand/tests
+make test
+cd ..
+gcov ../../../wine/dlls/lzexpand/lzexpand_main.c
+  0.00% of 3 lines executed in file ../../../wine/include/wine/unicode.h
+  Creating unicode.h.gcov.
+  0.00% of 4 lines executed in file /usr/include/ctype.h
+  Creating ctype.h.gcov.
+  0.00% of 6 lines executed in file /usr/include/bits/string2.h
+  Creating string2.h.gcov.
+  100.00% of 3 lines executed in file ../../../wine/include/winbase.h
+  Creating winbase.h.gcov.
+  50.83% of 240 lines executed in file ../../../wine/dlls/lzexpand/lzexpand_main.c
+  Creating lzexpand_main.c.gcov.
+less lzexpand_main.c.gcov
+        </screen>
+        Note that there is more output, but only output of gcov is
+        shown.  The output file
+        <filename>lzexpand_main.c.gcov</filename> looks like this.
+        <screen>
+        9:  545:        if ((mode&~0x70)!=OF_READ)
+        6:  546:                return fd;
+        3:  547:        if (fd==HFILE_ERROR)
+    #####:  548:                return HFILE_ERROR;
+        3:  549:        cfd=LZInit(fd);
+        3:  550:        if ((INT)cfd <= 0) return fd;
+        3:  551:        return cfd;
+        </screen>
+        <command>gcov</command> output consists of three components:
+        the number of times a line was run, the line number, and the
+        actual text of the line.  Note: If a line is optimized out by
+        the compiler, it will appear as if it was never run.  The line
+        of code which returns <constant>HFILE_ERROR</constant> is
+        never executed (and it is highly unlikely that it is optimized
+        out), so we don't know if it is correct.  In order to validate
+        this line, there are two parts of this process.  First we must
+        write the test.  Please see <xref linkend="testing"> to
+        learn more about writing tests.  We insert the following lines
+        into a test case:
+        <screen>
+INT file;
+
+/* Check for non-existent file. */
+file = LZOpenFile("badfilename_", &amp;test, OF_READ);
+ok(file == LZERROR_BADINHANDLE, 
+   "LZOpenFile succeeded on nonexistent file\n");
+LZClose(file);
+       </screen>
+       Once we add in this test case, we now want to know if the line
+       in question is run by this test and works as expected.  You
+       should be in the same directory as you left off in the previous
+       command example.  The only difference is that we have to remove
+       the <filename>*.da</filename> files in order to start the
+       count over (if we leave the files than the number of times the
+       line is run is just added, e.g. line 545 below would be run 19 times)
+       and we remove the <filename>*.gcov</filename> files because
+       they are out of date and need to be recreated.
+      </para>
+      <screen>
+rm *.da *.gcov
+cd tests
+make
+make test
+cd ..
+gcov ../../../wine/dlls/lzexpand/lzexpand_main.c
+  0.00% of 3 lines executed in file ../../../wine/include/wine/unicode.h
+  Creating unicode.h.gcov.
+  0.00% of 4 lines executed in file /usr/include/ctype.h
+  Creating ctype.h.gcov.
+  0.00% of 6 lines executed in file /usr/include/bits/string2.h
+  Creating string2.h.gcov.
+  100.00% of 3 lines executed in file ../../../wine/include/winbase.h
+  Creating winbase.h.gcov.
+  51.67% of 240 lines executed in file ../../../wine/dlls/lzexpand/lzexpand_main.c
+  Creating lzexpand_main.c.gcov.
+less lzexpand_main.c.gcov
+      </screen>
+      <para>
+        Note that there is more output, but only output of gcov is
+        shown.  The output file
+        <filename>lzexpand_main.c.gcov</filename> looks like this.
+      </para>
+      <screen>
+       10:  545:        if ((mode&~0x70)!=OF_READ)
+        6:  546:                return fd;
+        4:  547:        if (fd==HFILE_ERROR)
+        1:  548:                return HFILE_ERROR;
+        3:  549:        cfd=LZInit(fd);
+        3:  550:        if ((INT)cfd <= 0) return fd;
+        3:  551:        return cfd;
+      </screen>
+      <para>
+        Based on gcov, we now know that
+        <constant>HFILE_ERROR</constant> is returned once.  And since
+        all of our other tests have remain unchanged, we can assume
+        that the one time it is returned is to satisfy the one case we
+        added where we check for it.  Thus we have validated a line of
+        code.  While this is a cursory example, it demostrates the
+        potential usefulness of this tool.  
+      </para>
+      <para>
+        For a further in depth description of gcov, the official gcc
+        compiler suite page for gcov is <ulink
+        url="http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Gcov.html">
+        http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Gcov.html</ulink>.
+        There is also an excellent article written by Steve Best for
+        Linux Magazine which describes and illustrates this process
+        very well at
+        <ulink url="http://www.linux-mag.com/2003-07/compile_01.html">
+        http://www.linux-mag.com/2003-07/compile_01.html</ulink>. 
+      </para>
+    </sect1>
 
   </chapter>
 


More information about the wine-patches mailing list