mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 10:05:29 +00:00
Allows to run regression tests in an outer/inner setup.
A '3 lines how to':
perl tests/vg_regtest --outer-valgrind=../trunk_untouched/install/bin/valgrind --all
(the outer results for a test xxx is in xxx.outer.log)
To run with another tool (e.g. drd), add the argument --outer-tool=drd
Still to do/things to improve:
* Most (inner) tests are successful when running under an outer
memcheck. Need to analyse the reasons of remaining failures.
* The memcheck annotations in m_mallocfree.c can be improved:
- A superblock is marked 'undefined', it should rather be marked
'no access'.
- When a free block is splitted, the remaining free block is
not made 'no access'. Instead, it is made 'undefined'.
=> this decreases the chance to find bugs.
=> this is not very efficient (e.g. the rest of a superblock
is often marked undefined repetitively).
Similarly, the free block created by VG_(arena_memalign)
is marked 'undefined'. 'No access' would be preferrable.
- mkInuseBlock marks the new block as undefined. This is probably
not needed, as VALGRIND_MALLOCLIKE_BLOCK will do it already.
- VG_(arena_malloc) should give the requested size to
VALGRIND_MALLOCLIKE_BLOCK, not the malloc usable size,
as this decreases the chance to find buffer overrun bugs.
But giving the requested size is tricky (see comments in
the code).
* need to do memcheck annotations in m_poolalloc.c
so as to allow leak checking for pool allocated elements.
* vg_regtest.in
- should analyse the results of the outer and should
produce a separate result for the tests for which
the outer detects an error or a memory leak or ...
Changes done:
README_DEVELOPERS: document the new outer/inner features.
manual-core.xml: document the new sim-hint no-inner-prefix
tests/outer_inner.supp: new file, containing the suppressions for inner.
vg_regtest.in: implement new args --outer-valgrind, --outer-tool, --outer-args.
m_mallocfree.c: annotations for memcheck.
m_libcprint.c: handle the new sim-hint no-inner-prefix
m_main.c: do an (early) parse of --sim-hints
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12441
This commit is contained in:
parent
12633f0117
commit
aa50a7e4df
2
NEWS
2
NEWS
@ -36,6 +36,8 @@ Release 3.8.0 (????)
|
||||
and scheduling of multithreaded applications (in particular
|
||||
on multiprocessor/multicore systems).
|
||||
|
||||
* Support to run Valgrind on Valgrind has been improved.
|
||||
|
||||
* ==================== FIXED BUGS ====================
|
||||
|
||||
The following bugs have been fixed or resolved. Note that "n-i-bz"
|
||||
|
||||
@ -141,8 +141,7 @@ To run Valgrind under Valgrind:
|
||||
(1) Check out 2 trees, "Inner" and "Outer". Inner runs the app
|
||||
directly. Outer runs Inner.
|
||||
|
||||
(2) Configure inner with --enable-inner and build/install as
|
||||
usual.
|
||||
(2) Configure inner with --enable-inner and build/install as usual.
|
||||
|
||||
(3) Configure Outer normally and build/install as usual.
|
||||
|
||||
@ -169,15 +168,48 @@ Debugging the whole thing might imply to use up to 3 GDB:
|
||||
The whole thing is fragile, confusing and slow, but it does work well enough
|
||||
for you to get some useful performance data. Inner has most of
|
||||
its output (ie. those lines beginning with "==<pid>==") prefixed with a '>',
|
||||
which helps a lot.
|
||||
which helps a lot. However, when running regression tests in an Outer/Inner
|
||||
setup, this prefix causes the reg test diff to fail. Give
|
||||
--sim-hints=no-inner-prefix to the Inner to disable the production
|
||||
of the prefix in the stdout/stderr output of Inner.
|
||||
|
||||
At the time of writing the allocator is not annotated with client requests
|
||||
so Memcheck is not as useful as it could be. It also has not been tested
|
||||
much, so don't be surprised if you hit problems.
|
||||
The allocator (coregrind/m_mallocfree.c) is annotated with client requests
|
||||
so Memcheck can be used to find leaks and use after free in an Inner
|
||||
Valgrind.
|
||||
|
||||
The Valgrind "big lock" is annotated with helgrind client requests
|
||||
so helgrind and drd can be used to find race conditions in an Inner
|
||||
Valgrind.
|
||||
|
||||
All this has not been tested much, so don't be surprised if you hit problems.
|
||||
|
||||
When using self-hosting with an outer Callgrind tool, use '--pop-on-jump'
|
||||
(on the outer). Otherwise, Callgrind has much higher memory requirements.
|
||||
|
||||
Regression tests in an outer/inner setup:
|
||||
To run all the regression tests with an outer memcheck, do :
|
||||
perl test/vg_regtest --outer-valgrind=../outer/.../bin/valgrind \
|
||||
--all
|
||||
|
||||
To run a specific regression tests with an outer memcheck, do:
|
||||
perl test/vg_regtest --outer-valgrind=../outer/.../bin/valgrind \
|
||||
none/tests/args.vgtest
|
||||
|
||||
To run regression tests with another outer tool:
|
||||
perl tests/vg_regtest --outer-valgrind=../outer/.../bin/valgrind \
|
||||
--outer-tool=helgrind " --all
|
||||
|
||||
--outer-args allows to give specific arguments to the outer tool,
|
||||
replacing the default one provided by vg_regtest.
|
||||
|
||||
When an outer valgrind runs an inner valgrind, a regression test
|
||||
produces one additional file <testname>.outer.log which contains the
|
||||
errors detected by the outer valgrind. E.g. for an outer memcheck, it
|
||||
contains the leaks found in the inner, for an outer helgrind or drd,
|
||||
it contains the detected race conditions.
|
||||
|
||||
The file tests/outer_inner.supp contains suppressions for
|
||||
the irrelevant or benign errors found in the inner.
|
||||
|
||||
Printing out problematic blocks
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -396,11 +396,16 @@ static void add_to__vmessage_buf ( HChar c, void *p )
|
||||
|
||||
// Print one '>' in front of the messages for each level of
|
||||
// self-hosting being performed.
|
||||
// Do not print such '>' if sim hint "no-inner-prefix" given
|
||||
// (useful to run regression tests in an outer/inner setup
|
||||
// and avoid the diff failing due to these unexpected '>').
|
||||
depth = RUNNING_ON_VALGRIND;
|
||||
if (depth > 10)
|
||||
depth = 10; // ?!?!
|
||||
for (i = 0; i < depth; i++) {
|
||||
b->buf[b->buf_used++] = '>';
|
||||
if (depth > 0 && !VG_(strstr)(VG_(clo_sim_hints), "no-inner-prefix")) {
|
||||
if (depth > 10)
|
||||
depth = 10; // ?!?!
|
||||
for (i = 0; i < depth; i++) {
|
||||
b->buf[b->buf_used++] = '>';
|
||||
}
|
||||
}
|
||||
|
||||
if (Vg_FailMsg == b->kind) {
|
||||
|
||||
@ -294,6 +294,7 @@ static void usage_NORETURN ( Bool debug_help )
|
||||
- get the toolname (--tool=)
|
||||
- set VG_(clo_max_stackframe) (--max-stackframe=)
|
||||
- set VG_(clo_main_stacksize) (--main-stacksize=)
|
||||
- set VG_(clo_sim_hints) (--sim-hints=)
|
||||
|
||||
That's all it does. The main command line processing is done below
|
||||
by main_process_cmd_line_options. Note that
|
||||
@ -334,6 +335,11 @@ static void early_process_cmd_line_options ( /*OUT*/Int* need_help,
|
||||
// before main_process_cmd_line_options().
|
||||
else if VG_INT_CLO(str, "--max-stackframe", VG_(clo_max_stackframe)) {}
|
||||
else if VG_INT_CLO(str, "--main-stacksize", VG_(clo_main_stacksize)) {}
|
||||
|
||||
// Set up VG_(clo_sim_hints). This is needed a.o. for an inner
|
||||
// running in an outer, to have "no-inner-prefix" enabled
|
||||
// as early as possible.
|
||||
else if VG_STR_CLO (str, "--sim-hints", VG_(clo_sim_hints)) {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -451,6 +457,7 @@ void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
|
||||
else if VG_STREQ( arg, "-d") {}
|
||||
else if VG_STREQN(16, arg, "--max-stackframe") {}
|
||||
else if VG_STREQN(16, arg, "--main-stacksize") {}
|
||||
else if VG_STREQN(11, arg, "--sim-hints") {}
|
||||
else if VG_STREQN(14, arg, "--profile-heap") {}
|
||||
|
||||
// These options are new.
|
||||
@ -514,7 +521,6 @@ void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
|
||||
else if VG_BOOL_CLO(arg, "--trace-syscalls", VG_(clo_trace_syscalls)) {}
|
||||
else if VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb)) {}
|
||||
else if VG_STR_CLO (arg, "--db-command", VG_(clo_db_command)) {}
|
||||
else if VG_STR_CLO (arg, "--sim-hints", VG_(clo_sim_hints)) {}
|
||||
else if VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets)) {}
|
||||
else if VG_BOOL_CLO(arg, "--read-var-info", VG_(clo_read_var_info)) {}
|
||||
|
||||
|
||||
@ -42,9 +42,11 @@
|
||||
#include "pub_core_threadstate.h" // For VG_INVALID_THREADID
|
||||
#include "pub_core_transtab.h"
|
||||
#include "pub_core_tooliface.h"
|
||||
#include "valgrind.h"
|
||||
|
||||
//zz#include "memcheck/memcheck.h"
|
||||
#include "pub_tool_inner.h"
|
||||
#if defined(ENABLE_INNER_CLIENT_REQUEST)
|
||||
#include "memcheck/memcheck.h"
|
||||
#endif
|
||||
|
||||
// #define DEBUG_MALLOC // turn on heavyweight debugging machinery
|
||||
// #define VERBOSE_MALLOC // make verbose, esp. in debugging machinery
|
||||
@ -776,7 +778,7 @@ Superblock* newSuperblock ( Arena* a, SizeT cszB )
|
||||
}
|
||||
}
|
||||
vg_assert(NULL != sb);
|
||||
//zzVALGRIND_MAKE_MEM_UNDEFINED(sb, cszB);
|
||||
INNER_REQUEST(VALGRIND_MAKE_MEM_UNDEFINED(sb, cszB));
|
||||
vg_assert(0 == (Addr)sb % VG_MIN_MALLOC_SZB);
|
||||
sb->n_payload_bytes = cszB - sizeof(Superblock);
|
||||
sb->unsplittable = (unsplittable ? sb : NULL);
|
||||
@ -1042,6 +1044,12 @@ Bool blockSane ( Arena* a, Block* b )
|
||||
// The lo and hi size fields will be checked (indirectly) by the call
|
||||
// to get_rz_hi_byte().
|
||||
if (!a->clientmem && is_inuse_block(b)) {
|
||||
// In the inner, for memcheck sake, temporarily mark redzone accessible.
|
||||
INNER_REQUEST(VALGRIND_MAKE_MEM_DEFINED
|
||||
(b + hp_overhead_szB() + sizeof(SizeT), a->rz_szB));
|
||||
INNER_REQUEST(VALGRIND_MAKE_MEM_DEFINED
|
||||
(b + get_bszB(b)
|
||||
- sizeof(SizeT) - a->rz_szB, a->rz_szB));
|
||||
for (i = 0; i < a->rz_szB; i++) {
|
||||
if (get_rz_lo_byte(b, i) !=
|
||||
(UByte)(((Addr)b&0xff) ^ REDZONE_LO_MASK))
|
||||
@ -1050,6 +1058,11 @@ Bool blockSane ( Arena* a, Block* b )
|
||||
(UByte)(((Addr)b&0xff) ^ REDZONE_HI_MASK))
|
||||
{BLEAT("redzone-hi");return False;}
|
||||
}
|
||||
INNER_REQUEST(VALGRIND_MAKE_MEM_NOACCESS
|
||||
(b + hp_overhead_szB() + sizeof(SizeT), a->rz_szB));
|
||||
INNER_REQUEST(VALGRIND_MAKE_MEM_NOACCESS
|
||||
(b + get_bszB(b)
|
||||
- sizeof(SizeT) - a->rz_szB, a->rz_szB));
|
||||
}
|
||||
return True;
|
||||
# undef BLEAT
|
||||
@ -1338,7 +1351,7 @@ void mkFreeBlock ( Arena* a, Block* b, SizeT bszB, UInt b_lno )
|
||||
{
|
||||
SizeT pszB = bszB_to_pszB(a, bszB);
|
||||
vg_assert(b_lno == pszB_to_listNo(pszB));
|
||||
//zzVALGRIND_MAKE_MEM_UNDEFINED(b, bszB);
|
||||
INNER_REQUEST(VALGRIND_MAKE_MEM_UNDEFINED(b, bszB));
|
||||
// Set the size fields and indicate not-in-use.
|
||||
set_bszB(b, mk_free_bszB(bszB));
|
||||
|
||||
@ -1367,7 +1380,7 @@ void mkInuseBlock ( Arena* a, Block* b, SizeT bszB )
|
||||
{
|
||||
UInt i;
|
||||
vg_assert(bszB >= min_useful_bszB(a));
|
||||
//zzVALGRIND_MAKE_MEM_UNDEFINED(b, bszB);
|
||||
INNER_REQUEST(VALGRIND_MAKE_MEM_UNDEFINED(b, bszB));
|
||||
set_bszB(b, mk_inuse_bszB(bszB));
|
||||
set_prev_b(b, NULL); // Take off freelist
|
||||
set_next_b(b, NULL); // ditto
|
||||
@ -1594,7 +1607,26 @@ void* VG_(arena_malloc) ( ArenaId aid, HChar* cc, SizeT req_pszB )
|
||||
v = get_block_payload(a, b);
|
||||
vg_assert( (((Addr)v) & (VG_MIN_MALLOC_SZB-1)) == 0 );
|
||||
|
||||
/* VALGRIND_MALLOCLIKE_BLOCK(v, req_pszB, 0, False); */
|
||||
// Which size should we pass to VALGRIND_MALLOCLIKE_BLOCK ?
|
||||
// We have 2 possible options:
|
||||
// 1. The final resulting usable size.
|
||||
// 2. The initial (non-aligned) req_pszB.
|
||||
// Memcheck implements option 2 easily, as the initial requested size
|
||||
// is maintained in the mc_chunk data structure.
|
||||
// This is not as easy in the core, as there is no such structure.
|
||||
// (note: using the aligned req_pszB is not simpler than 2, as
|
||||
// requesting an aligned req_pszB might still be satisfied by returning
|
||||
// a (slightly) bigger block than requested if the remaining part of
|
||||
// of a free block is not big enough to make a free block by itself).
|
||||
// Implement Sol 2 can be done the following way:
|
||||
// After having called VALGRIND_MALLOCLIKE_BLOCK, the non accessible
|
||||
// redzone just after the block can be used to determine the
|
||||
// initial requested size.
|
||||
// Currently, not implemented => we use Option 1.
|
||||
INNER_REQUEST
|
||||
(VALGRIND_MALLOCLIKE_BLOCK(v,
|
||||
VG_(arena_malloc_usable_size)(aid, v),
|
||||
a->rz_szB, False));
|
||||
|
||||
/* For debugging/testing purposes, fill the newly allocated area
|
||||
with a definite value in an attempt to shake out any
|
||||
@ -1788,6 +1820,31 @@ void VG_(arena_free) ( ArenaId aid, void* ptr )
|
||||
deferred_reclaimSuperblock (a, sb);
|
||||
}
|
||||
|
||||
// Inform that ptr has been released. We give redzone size
|
||||
// 0 instead of a->rz_szB as proper accessibility is done just after.
|
||||
INNER_REQUEST(VALGRIND_FREELIKE_BLOCK(ptr, 0));
|
||||
|
||||
// We need to (re-)establish the minimum accessibility needed
|
||||
// for free list management. E.g. if block ptr has been put in a free
|
||||
// list and a neighbour block is released afterwards, the
|
||||
// "lo" and "hi" portions of the block ptr will be accessed to
|
||||
// glue the 2 blocks together.
|
||||
// We could mark the whole block as not accessible, and each time
|
||||
// transiently mark accessible the needed lo/hi parts. Not done as this
|
||||
// is quite complex, for very little expected additional bug detection.
|
||||
// fully unaccessible. Note that the below marks the (possibly) merged
|
||||
// block, not the block corresponding to the ptr argument.
|
||||
|
||||
// First mark the whole block unaccessible.
|
||||
INNER_REQUEST(VALGRIND_MAKE_MEM_NOACCESS(b, b_bszB));
|
||||
// Then mark the relevant administrative headers as defined.
|
||||
// No need to mark the heap profile portion as defined, this is not
|
||||
// used for free blocks.
|
||||
INNER_REQUEST(VALGRIND_MAKE_MEM_DEFINED(b + hp_overhead_szB(),
|
||||
sizeof(SizeT) + sizeof(void*)));
|
||||
INNER_REQUEST(VALGRIND_MAKE_MEM_DEFINED(b + b_bszB
|
||||
- sizeof(SizeT) - sizeof(void*),
|
||||
sizeof(SizeT) + sizeof(void*)));
|
||||
} else {
|
||||
// b must be first block (i.e. no unused bytes at the beginning)
|
||||
vg_assert((Block*)sb_start == b);
|
||||
@ -1796,6 +1853,12 @@ void VG_(arena_free) ( ArenaId aid, void* ptr )
|
||||
other_b = b + b_bszB;
|
||||
vg_assert(other_b-1 == (Block*)sb_end);
|
||||
|
||||
// Inform that ptr has been released. Redzone size value
|
||||
// is not relevant (so we give 0 instead of a->rz_szB)
|
||||
// as it is expected that the aspacemgr munmap will be used by
|
||||
// outer to mark the whole superblock as unaccessible.
|
||||
INNER_REQUEST(VALGRIND_FREELIKE_BLOCK(ptr, 0));
|
||||
|
||||
// Reclaim immediately the unsplittable superblock sb.
|
||||
reclaimSuperblock (a, sb);
|
||||
}
|
||||
@ -1804,7 +1867,6 @@ void VG_(arena_free) ( ArenaId aid, void* ptr )
|
||||
sanity_check_malloc_arena(aid);
|
||||
# endif
|
||||
|
||||
//zzVALGRIND_FREELIKE_BLOCK(ptr, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -1897,6 +1959,11 @@ void* VG_(arena_memalign) ( ArenaId aid, HChar* cc,
|
||||
/* Give up if we couldn't allocate enough space */
|
||||
if (base_p == 0)
|
||||
return 0;
|
||||
/* base_p was marked as allocated by VALGRIND_MALLOCLIKE_BLOCK
|
||||
inside VG_(arena_malloc). We need to indicate it is free, then
|
||||
we need to mark it undefined to allow the below code to access is. */
|
||||
INNER_REQUEST(VALGRIND_FREELIKE_BLOCK(base_p, a->rz_szB));
|
||||
INNER_REQUEST(VALGRIND_MAKE_MEM_UNDEFINED(base_p, base_pszB_req));
|
||||
|
||||
/* Block ptr for the block we are going to split. */
|
||||
base_b = get_payload_block ( a, base_p );
|
||||
@ -1949,7 +2016,8 @@ void* VG_(arena_memalign) ( ArenaId aid, HChar* cc,
|
||||
|
||||
vg_assert( (((Addr)align_p) % req_alignB) == 0 );
|
||||
|
||||
//zzVALGRIND_MALLOCLIKE_BLOCK(align_p, req_pszB, 0, False);
|
||||
INNER_REQUEST(VALGRIND_MALLOCLIKE_BLOCK(align_p,
|
||||
req_pszB, a->rz_szB, False));
|
||||
|
||||
return align_p;
|
||||
}
|
||||
@ -2041,8 +2109,6 @@ void* VG_(arena_calloc) ( ArenaId aid, HChar* cc,
|
||||
|
||||
VG_(memset)(p, 0, size);
|
||||
|
||||
//zzVALGRIND_MALLOCLIKE_BLOCK(p, size, 0, True);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
@ -1646,6 +1646,15 @@ need to use these.</para>
|
||||
magic needed when the program being run is itself
|
||||
Valgrind.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><option>no-inner-prefix: </option> Disable printing
|
||||
a prefix <option>></option> in front of each stdout or
|
||||
stderr output line in an inner Valgrind being run by an
|
||||
outer Valgrind. This is useful when running Valgrind
|
||||
regression tests in an outer/inner setup. Note that the
|
||||
prefix <option>></option> will always be printed in
|
||||
front of the inner debug logging lines.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><option>fuse-compatible: </option> Enable special
|
||||
handling for certain system calls that may block in a FUSE
|
||||
|
||||
46
tests/outer_inner.supp
Normal file
46
tests/outer_inner.supp
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
# errors to suppress when an outer runs an inner.
|
||||
|
||||
# ==31040== 16 bytes in 1 blocks are definitely lost in loss record 10 of 106
|
||||
# ==31040== at 0x2803A367: vgPlain_arena_malloc (m_mallocfree.c:1599)
|
||||
# ==31040== by 0x2803ADE3: vgPlain_strdup (m_mallocfree.c:2140)
|
||||
# ==31040== by 0x2803208A: valgrind_main (m_main.c:437)
|
||||
# ==31040== by 0x28035F3C: _start_in_C_linux (m_main.c:2799)
|
||||
# ==31040== by 0x28030B4B: ??? (in install/lib/valgrind/memcheck-x86-linux)
|
||||
{
|
||||
"keep duplicated args forever as tools can make copies"
|
||||
Memcheck:Leak
|
||||
fun:vgPlain_arena_malloc
|
||||
fun:vgPlain_strdup
|
||||
fun:valgrind_main
|
||||
}
|
||||
|
||||
# ==31040== 392 bytes in 1 blocks are definitely lost in loss record 58 of 106
|
||||
# ==31040== at 0x2803A367: vgPlain_arena_malloc (m_mallocfree.c:1599)
|
||||
# ==31040== by 0x2803A9CF: vgPlain_malloc (m_mallocfree.c:2156)
|
||||
# ==31040== by 0x280738F0: vgPlain_ii_create_image (initimg-linux.c:202)
|
||||
# ==31040== by 0x280327CF: valgrind_main (m_main.c:1718)
|
||||
# ==31040== by 0x28035F3C: _start_in_C_linux (m_main.c:2799)
|
||||
# ==31040== by 0x28030B4B: ??? (in install/lib/valgrind/memcheck-x86-linux)
|
||||
{
|
||||
"LD_PRELOAD_STRING inserted in env, difficult to free"
|
||||
Memcheck:Leak
|
||||
fun:vgPlain_arena_malloc
|
||||
fun:vgPlain_malloc
|
||||
fun:vgPlain_ii_create_image
|
||||
fun:valgrind_main
|
||||
}
|
||||
|
||||
# ==32749== 400 bytes in 1 blocks are definitely lost in loss record 47 of 96
|
||||
# ==32749== at 0x2803D0D7: vgPlain_arena_malloc (m_mallocfree.c:1599)
|
||||
# ==32749== by 0x28072DAB: vgPlain_ii_create_image (initimg-linux.c:202)
|
||||
# ==32749== by 0x28036264: valgrind_main (m_main.c:1718)
|
||||
# ==32749== by 0x280392FC: _start_in_C_linux (m_main.c:2799)
|
||||
# ==32749== by 0x28034920: ??? (in install/lib/valgrind/memcheck-amd64-linux)
|
||||
{
|
||||
"LD_PRELOAD_STRING inserted in env, difficult to free"
|
||||
Memcheck:Leak
|
||||
fun:vgPlain_arena_malloc
|
||||
fun:vgPlain_ii_create_image
|
||||
fun:valgrind_main
|
||||
}
|
||||
@ -40,6 +40,11 @@
|
||||
# --keep-unfiltered: keep a copy of the unfiltered output/error output
|
||||
# of each test by adding an extension .unfiltered.out
|
||||
#
|
||||
# --outer-valgrind: run this valgrind under the given outer valgrind.
|
||||
# This valgrind must be configured with --enable-inner.
|
||||
# --outer-tool: tool to use by the outer valgrind (default memcheck).
|
||||
# --outer-args: use this as outer tool args.
|
||||
#
|
||||
# The easiest way is to run all tests in valgrind/ with (assuming you installed
|
||||
# in $PREFIX):
|
||||
#
|
||||
@ -120,7 +125,8 @@ use strict;
|
||||
#----------------------------------------------------------------------------
|
||||
my $usage="\n"
|
||||
. "Usage:\n"
|
||||
. " vg_regtest [--all, --valgrind, --valgrind-lib, --keep-unfiltered]\n"
|
||||
. " vg_regtest [--all, --valgrind, --valgrind-lib, --keep-unfiltered\n"
|
||||
. " --outer-valgrind, --outer-tool, --outer-args]\n"
|
||||
. " Use EXTRA_REGTEST_OPTS to supply extra args for all tests\n"
|
||||
. "\n";
|
||||
|
||||
@ -157,6 +163,13 @@ my $valgrind = "./coregrind/valgrind";
|
||||
|
||||
chomp(my $tests_dir = `pwd`);
|
||||
|
||||
# Outer valgrind to use, and args to use for it.
|
||||
# If this is set, --valgrind should be set to the installed inner valgrind,
|
||||
# and --valgrind-lib will be ignore
|
||||
my $outer_valgrind;
|
||||
my $outer_tool = "memcheck";
|
||||
my $outer_args;
|
||||
|
||||
my $valgrind_lib = "$tests_dir/.in_place";
|
||||
my $keepunfiltered = 0;
|
||||
|
||||
@ -205,6 +218,12 @@ sub process_command_line()
|
||||
$alldirs = 1;
|
||||
} elsif ($arg =~ /^--valgrind=(.*)$/) {
|
||||
$valgrind = $1;
|
||||
} elsif ($arg =~ /^--outer-valgrind=(.*)$/) {
|
||||
$outer_valgrind = $1;
|
||||
} elsif ($arg =~ /^--outer-tool=(.*)$/) {
|
||||
$outer_tool = $1;
|
||||
} elsif ($arg =~ /^--outer-args=(.*)$/) {
|
||||
$outer_args = $1;
|
||||
} elsif ($arg =~ /^--valgrind-lib=(.*)$/) {
|
||||
$valgrind_lib = $1;
|
||||
} elsif ($arg =~ /^--keep-unfiltered$/) {
|
||||
@ -217,6 +236,20 @@ sub process_command_line()
|
||||
}
|
||||
}
|
||||
$valgrind = validate_program($tests_dir, $valgrind, 1, 0);
|
||||
|
||||
if (defined $outer_valgrind) {
|
||||
$outer_valgrind = validate_program($tests_dir, $outer_valgrind, 1, 0);
|
||||
if (not defined $outer_args) {
|
||||
$outer_args =
|
||||
" --command-line-only=yes"
|
||||
. " --run-libc-freeres=no --sim-hints=enable-outer"
|
||||
. " --vgdb=no --trace-children=yes --read-var-info=no"
|
||||
. " --suppressions="
|
||||
. validate_program($tests_dir,"./tests/outer_inner.supp",1,0)
|
||||
. " --memcheck:leak-check=full --memcheck:show-reachable=no"
|
||||
. " ";
|
||||
}
|
||||
}
|
||||
|
||||
if ($alldirs) {
|
||||
@fs = ();
|
||||
@ -428,10 +461,21 @@ sub do_one_test($$)
|
||||
# VALGRIND_LIB_INNER in case this Valgrind was configured with
|
||||
# --enable-inner.
|
||||
my $tool=determine_tool();
|
||||
mysystem("VALGRIND_LIB=$valgrind_lib VALGRIND_LIB_INNER=$valgrind_lib "
|
||||
. "$valgrind --command-line-only=yes --memcheck:leak-check=no "
|
||||
. "--tool=$tool $extraopts $vgopts "
|
||||
. "$prog $args > $name.stdout.out 2> $name.stderr.out");
|
||||
if (defined $outer_valgrind ) {
|
||||
mysystem("$outer_valgrind "
|
||||
. "--tool=" . $outer_tool . " "
|
||||
. "$outer_args "
|
||||
. "--log-file=" . "$name.outer.log "
|
||||
. "$valgrind --command-line-only=yes --memcheck:leak-check=no "
|
||||
. "--sim-hints=no-inner-prefix "
|
||||
. "--tool=$tool $extraopts $vgopts "
|
||||
. "$prog $args > $name.stdout.out 2> $name.stderr.out");
|
||||
} else {
|
||||
mysystem("VALGRIND_LIB=$valgrind_lib VALGRIND_LIB_INNER=$valgrind_lib "
|
||||
. "$valgrind --command-line-only=yes --memcheck:leak-check=no "
|
||||
. "--tool=$tool $extraopts $vgopts "
|
||||
. "$prog $args > $name.stdout.out 2> $name.stderr.out");
|
||||
}
|
||||
|
||||
# Filter stdout
|
||||
if (defined $stdout_filter) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user