Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Valgrind documentation/testsuite improvements #10216

Merged
merged 5 commits into from
Feb 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion doc/devdocs/valgrind.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,38 @@ Using Valgrind with Julia

`Valgrind <http:https://valgrind.org/>`_ is a tool for memory debugging, memory leak detection, and profiling. This section describes things to keep in mind when using Valgrind to debug memory issues with Julia.

General considerations
----------------------

By default, Valgrind assumes that there is no self modifying code in the programs it runs. This assumption works fine in most instances but fails miserably for a just-in-time compiler like ``julia``. For this reason it is crucial to pass ``--smc-check=all-non-file`` to ``valgrind``, else code may crash or behave unexpectedly (often in subtle ways).

In some cases, to better detect memory errors using Valgrind it can help to compile ``julia`` with memory pools disabled. The compile-time flag ``MEMDEBUG`` disables memory pools in Julia, and ``MEMDEBUG2`` disables memory pools in FemtoLisp. To build ``julia`` with both flags, add the following line to ``Make.user``::

CFLAGS = -DMEMDEBUG -DMEMDEBUG2

Another thing to note: if your program uses multiple workers processes, it is likely that you want all such worker processes to run under Valgrind, not just the parent process. To do this, pass ``--trace-children=yes`` to ``valgrind``.

Suppressions
------------

Valgrind will typically display spurious warnings as it runs. To reduce the number of such warnings, it helps to provide a `suppressions file <http:https://valgrind.org/docs/manual/manual-core.html#manual-core.suppress>`_ to Valgrind. A sample suppressions file is included in the Julia source distribution at ``contrib/valgrind-julia.supp``.

The suppressions file can be used from the ``julia/`` source directory as follows::

$ valgrind --suppressions=contrib/valgrind-julia.supp ./julia progname.jl
$ valgrind --smc-check=all-non-file --suppressions=contrib/valgrind-julia.supp ./julia progname.jl

Any memory errors that are displayed should either be reported as bugs or contributed as additional suppressions. Note that some versions of Valgrind are `shipped with insufficient default suppressions <https://github.com/JuliaLang/julia/issues/8314#issuecomment-55766210>`_, so that may be one thing to consider before submitting any bugs.

Running the Julia test suite under Valgrind
-------------------------------------------

It is possible to run the entire Julia test suite under Valgrind, but it does take quite some time (typically several hours). To do so, run the following command from the ``julia/test/`` directory::

valgrind --smc-check=all-non-file --trace-children=yes --suppressions=$PWD/../contrib/valgrind-julia.supp ../julia runtests.jl all

Caveats
-------

Valgrind currently `does not support multiple rounding modes <https://bugs.kde.org/show_bug.cgi?id=136779>`_, so code that adjusts the rounding mode will behave differently when run under Valgrind.

In general, if after setting ``--smc-check=all-non-file`` you find that your program behaves differently when run under Valgrind, it may help to pass ``--tool=none`` to ``valgrind`` as you investigate further. This will enable the minimal Valgrind machinery but will also run much faster than when the full memory checker is enabled.
5 changes: 5 additions & 0 deletions test/choosetests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ function choosetests(choices = [])
net_on = false
end

if ccall(:jl_running_on_valgrind,Cint,()) != 0 && "rounding" in tests
warn("Running under valgrind: Skipping rounding tests")
filter!(x -> x != "rounding", tests)
end

if !net_on
filter!(x -> !(x in net_required_for), tests)
end
Expand Down
2 changes: 1 addition & 1 deletion test/examples.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ include(joinpath(dir, "queens.jl"))
@unix_only begin
script = joinpath(dir, "clustermanager/simple/test_simple.jl")
cmd = `$(joinpath(JULIA_HOME,Base.julia_exename())) $script`
if !success(cmd)
if !success(cmd) && ccall(:jl_running_on_valgrind,Cint,()) == 0
error("UnixDomainCM failed test, cmd : $cmd")
end
end
Expand Down
4 changes: 3 additions & 1 deletion test/repl.jl
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,9 @@ wait(p)

ccall(:close,Cint,(Cint,),fds)
output = readall(master)
@test output == "julia> 1\r\nquit()\r\n1\r\n\r\njulia> "
if ccall(:jl_running_on_valgrind,Cint,()) == 0
@test output == "julia> 1\r\nquit()\r\n1\r\n\r\njulia> "
end
close(master)

end
Expand Down
15 changes: 13 additions & 2 deletions test/spawn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#TODO:
# - Windows:
# - Add a test whether coreutils are available and skip tests if not

valgrind_off = ccall(:jl_running_on_valgrind,Cint,()) == 0

yes = `perl -le 'while (1) {print STDOUT "y"}'`

#### Examples used in the manual ####
Expand Down Expand Up @@ -38,7 +41,11 @@ begin
kill(p)
end

@test_throws Base.UVError run(`foo_is_not_a_valid_command`)
if valgrind_off
# If --trace-children=yes is passed to valgrind, valgrind will
# exit here with an error code, and no UVError will be raised.
@test_throws Base.UVError run(`foo_is_not_a_valid_command`)
end

if false
prefixer(prefix, sleep) = `perl -nle '$|=1; print "'$prefix' ", $_; sleep '$sleep';'`
Expand Down Expand Up @@ -154,7 +161,11 @@ close(sock)

# issue #4535
exename=joinpath(JULIA_HOME,(ccall(:jl_is_debugbuild,Cint,())==0?"julia":"julia-debug"))
@test readall(pipe(`$exename -f -e 'println(STDERR,"Hello World")'`, stderr=`cat`)) == "Hello World\n"
if valgrind_off
# If --trace-children=yes is passed to valgrind, we will get a
# valgrind banner here, not "Hello World\n".
@test readall(pipe(`$exename -f -e 'println(STDERR,"Hello World")'`, stderr=`cat`)) == "Hello World\n"
end

# issue #6310
@test readall(pipe(`echo "2+2"`, `$exename -f`)) == "4\n"
Expand Down