184 lines
5.8 KiB
Plaintext
184 lines
5.8 KiB
Plaintext
@node Running self-tests under valgrind
|
|
@section Running self-tests under valgrind
|
|
|
|
@cindex valgrind
|
|
|
|
For projects written in C or similar languages, running the self-tests
|
|
under Valgrind can reveal hard to find memory issues. Gnulib supports
|
|
two ways to make use of Valgrind: one that enables use of Valgrind at
|
|
configure time, when @code{configure} found it to be present; and one
|
|
at the discretion of the developer.
|
|
|
|
@menu
|
|
* Using valgrind automatically::
|
|
* Valgrind options::
|
|
* Using valgrind manually::
|
|
* Valgrind and shell scripts::
|
|
@end menu
|
|
|
|
@node Using valgrind automatically
|
|
@subsection Using valgrind without developer intervention
|
|
|
|
@mindex valgrind-tests
|
|
The @code{valgrind-tests} module searches for Valgrind at configure time
|
|
and declares the @code{LOG_VALGRIND} automake variable for use with
|
|
automake's @code{LOG_COMPILER}.
|
|
|
|
After importing the @code{valgrind-tests} module to your project, you
|
|
use it by adding the following to the @code{Makefile.am} that runs the
|
|
self-tests:
|
|
|
|
@smallexample
|
|
LOG_COMPILER = $(LOG_VALGRIND)
|
|
@end smallexample
|
|
|
|
This will run all self-checks under valgrind.
|
|
|
|
Replace @code{LOG_COMPILER} with @code{TESTS_ENVIRONMENT} if you are
|
|
using the old serial test harness. The parallel test harness has been
|
|
the default in automake since version 1.11.3, but if you are using an
|
|
older automake, or put @samp{serial-tests} in
|
|
@samp{AM_INIT_AUTOMAKE}/@samp{AUTOMAKE_OPTIONS} you would still be using
|
|
the serial test harness.
|
|
|
|
If you desire a project-wide decision that valgrind is not enabled by
|
|
default, but still allow users to enable it with
|
|
@code{--enable-valgrind-tests} you may put the following in configure.ac
|
|
before gl_INIT.
|
|
|
|
@smallexample
|
|
gl_VALGRIND_TESTS_DEFAULT_NO
|
|
@end smallexample
|
|
|
|
@node Valgrind options
|
|
@subsection Valgrind options
|
|
|
|
The @code{VALGRIND} variable holds the name of the valgrind binary and
|
|
some options passed to valgrind. You may provide additional options
|
|
that are passed to valgrind using the @samp{VALGRINDFLAGS} variable, for
|
|
example:
|
|
|
|
@smallexample
|
|
./configure VALGRINDFLAGS="--suppressions=~/local.supp"
|
|
@end smallexample
|
|
|
|
Alternatively during build phase:
|
|
|
|
@smallexample
|
|
make check VALGRINDFLAGS="--suppressions=~/local.supp"
|
|
@end smallexample
|
|
|
|
This is useful if you have a valgrind suppression files that are needed
|
|
to avoid triggering errors for known errors, typically in system
|
|
libraries.
|
|
|
|
The @code{VALGRIND} variable include options that are useful when
|
|
valgrind is run non-interactively through the test harness. The default
|
|
parameters are @code{-q} to silence the output,
|
|
@code{--error-exitcode=1} to cause valgrind errors to be treated as
|
|
fatal errors, and @code{--leak-check=full} to check for memory leaks.
|
|
|
|
These options can be controlled through the @code{DEFAULT_VALGRINDFLAGS}
|
|
variable. For example, when configuring the package:
|
|
|
|
@smallexample
|
|
./configure DEFAULT_VALGRINDFLAGS="--quiet"
|
|
@end smallexample
|
|
|
|
Alternatively, during the build phase:
|
|
|
|
@smallexample
|
|
make check DEFAULT_VALGRINDFLAGS="--quiet"
|
|
@end smallexample
|
|
|
|
That would have the effect of removing @code{--error-exitcode=1} and
|
|
@code{--leak-check=full} from the default options, thus causing any
|
|
valgrind errors to be silently ignored, instead of causing fatal test
|
|
failures.
|
|
|
|
As a developer you may use the variables in @code{configure.ac} before
|
|
calling @code{gl_INIT}, like this if your program has deeply-nested call
|
|
chains:
|
|
|
|
@smallexample
|
|
gl_EARLY
|
|
...
|
|
VALGRINDFLAGS="$VALGRINDFLAGS --num-callers=42"
|
|
...
|
|
gl_INIT
|
|
@end smallexample
|
|
|
|
Note that any user-supplied @code{VALGRINDFLAGS} value is preserved,
|
|
which is usually what you want.
|
|
|
|
Finally, as a developer you may want to provide additional per-directory
|
|
options to valgrind and the @code{AM_VALGRINDFLAGS} variable can be used
|
|
for this. For example:
|
|
|
|
@smallexample
|
|
AM_VALGRINDFLAGS = --suppressions=$(srcdir)/local-valgrind.supp
|
|
LOG_COMPILER = $(LOG_VALGRIND)
|
|
@end smallexample
|
|
|
|
@node Using valgrind manually
|
|
@subsection Using valgrind at the developer's discretion
|
|
|
|
In this approach, you define a @code{Makefile.am} variable @samp{VALGRIND}
|
|
(or, more abstractly, @samp{CHECKER}), that is usually set to empty.
|
|
When you have configured and built the package and you decide that you want
|
|
to run the tests with valgrind, you do so by modifying the definition of
|
|
@samp{VALGRIND} in the Makefile.
|
|
|
|
@node Valgrind and shell scripts
|
|
@subsection How to use Valgrind with shell scripts
|
|
|
|
It is not desirable to apply valgrind to shell scripts or other non-binaries,
|
|
because
|
|
@itemize @bullet
|
|
@item
|
|
It is wasteful, and you usually don't want to look for memory leaks in bash.
|
|
@item
|
|
On a bi-arch system, you may get an error message such as
|
|
"valgrind: wrong executable class (eg. 32-bit instead of 64-bit)".
|
|
@end itemize
|
|
|
|
There are two ways to avoid this:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
Using the Automake parallel-tests feature, you can use the following instead:
|
|
|
|
@smallexample
|
|
TEST_EXTENSIONS = .pl .sh
|
|
LOG_COMPILER = $(LOG_VALGRIND)
|
|
@end smallexample
|
|
|
|
Then valgrind will only be used for the non-.sh and non-.pl tests.
|
|
|
|
For old automake (before 1.11.3), you will need @code{AUTOMAKE_OPTIONS =
|
|
parallel-tests} to enable the parallel test harness.
|
|
|
|
@item
|
|
You can make use of the @code{build-aux/run-test} script from Gnulib.
|
|
Add these lines to your @code{Makefile.am}:
|
|
|
|
@smallexample
|
|
LOG_COMPILER += $(SHELL) $(top_srcdir)/build-aux/run-test '$(LOG_VALGRIND)'
|
|
@end smallexample
|
|
|
|
Replace @code{LOG_COMPILER} with @code{TESTS_ENVIRONMENT} if you use the
|
|
old serial test harness.
|
|
@end itemize
|
|
|
|
However, with this measure in place, binaries invoked through scripts will
|
|
not be invoked under valgrind. This can be solved by defining environment
|
|
variables in the @code{TESTS_ENVIRONMENT} variable that are then used by the
|
|
shell scripts. For example, add the following:
|
|
|
|
@smallexample
|
|
TESTS_ENVIRONMENT = VALGRIND='$(LOG_VALGRIND)'
|
|
@end smallexample
|
|
|
|
And then modify the shell scripts to invoke the binary prefixed with
|
|
@code{$VALGRIND}.
|