Using and understanding the Valgrind core
--smc-check=<none|stack|all|all-non-file> [default:
stack]
This option controls Valgrind’s detection of self-modifying code. If no checking is done, if a program executes some
code, then overwrites it with new code, and executes the new code, Valgrind will continue to execute the translations
it made for the old code. This will likely lead to incorrect behaviour and/or crashes.
Valgrind has four levels of self-modifying code detection: no detection, detect self-modifying code on the stack
(which is used by GCC to implement nested functions), detect self-modifying code everywhere, and detect self-
modifying code everywhere except in file-backed mappings. Note that the default option will catch the vast majority
of cases.
The main case it will not catch is programs such as JIT compilers that dynamically generate code
and
subsequently overwrite part or all of it.
Running with
all
will slow Valgrind down noticeably. Running
with
none
will rarely speed things up, since very little code gets put on the stack for most programs.
The
VALGRIND_DISCARD_TRANSLATIONS
client request is an alternative to
--smc-check=all
that requires more
programmer effort but allows Valgrind to run your program faster, by telling it precisely when translations need to be
re-made.
--smc-check=all-non-file
provides a cheaper but more limited version of
--smc-check=all
.
It adds
checks to any translations that do not originate from file-backed memory mappings. Typical applications that generate
code, for example JITs in web browsers, generate code into anonymous mmaped areas, whereas the "fixed" code
of the browser always lives in file-backed mappings.
--smc-check=all-non-file
takes advantage of this
observation, limiting the overhead of checking to code which is likely to be JIT generated.
Some architectures (including ppc32, ppc64, ARM and MIPS) require programs which create code at runtime to
flush the instruction cache in between code generation and first use. Valgrind observes and honours such instructions.
Hence, on ppc32/Linux, ppc64/Linux and ARM/Linux, Valgrind always provides complete, transparent support for
self-modifying code.
It is only on platforms such as x86/Linux, AMD64/Linux, x86/Darwin and AMD64/Darwin
that you need to use this option.
--read-var-info=<yes|no> [default:
no]
When enabled, Valgrind will read information about variable types and locations from DWARF3 debug info. This
slows Valgrind down and makes it use more memory, but for the tools that can take advantage of it (Memcheck,
Helgrind, DRD) it can result in more precise error messages. For example, here are some standard errors issued by
Memcheck:
==15516== Uninitialised byte(s) found during client check request
==15516==
at 0x400633: croak (varinfo1.c:28)
==15516==
by 0x4006B2: main (varinfo1.c:55)
==15516==
Address 0x60103b is 7 bytes inside data symbol "global_i2"
==15516==
==15516== Uninitialised byte(s) found during client check request
==15516==
at 0x400633: croak (varinfo1.c:28)
==15516==
by 0x4006BC: main (varinfo1.c:56)
==15516==
Address 0x7fefffefc is on thread 1’s stack
And here are the same errors with
--read-var-info=yes
:
17