|
From: <sv...@va...> - 2013-08-12 22:17:57
|
philippe 2013-08-12 23:17:47 +0100 (Mon, 12 Aug 2013)
New Revision: 13495
Log:
kludge to bypass inner valgrind mmap failing due to not observed outer mmap
Some tests are failing in an "outer/inner" setup with an "out of memory"
situation reported by the inner (e.g. memcheck/tests/err_disable4.vgtest).
Looks like this is because the inner valgrind aspacemgr believes
a segment is free and can be used, but segment is in fact used by the outer.
This can happen as the inner cannot observe the outer mmap, and so
inner aspacemgr can be out of sync with the kernel and the outer.
This kludge bypasses the problem: if the fixed mmap fails in the inner,
the inner retries without the fixed.
This is a kludge as the proper solution would be to have a correct
state of aspacemgr in the inner. This however implies a more in-depth surgery
in the outer/inner setup (to have e.g. the outer informing the inner of
its own mmap or alternatively having the inner asking the outer about the
mmap advisory).
Kludge is preferred (at least now) as this kludge is activated only
for the inner (and for darwin, but that was already like that).
Of course, this kludge does not the state of the inner aspacemgr
matching the outer and kernel state.
So, other problems might be detected e.g. if inner aspacemgr does a check
comparing its status with kernel status.
The patch also ensures the inner reports the memory status of the
outer (using a client request) when an out of memory situation is detected.
This helps understanding what goes wrong.
Modified files:
trunk/coregrind/m_aspacemgr/aspacemgr-linux.c
trunk/coregrind/m_mallocfree.c
Modified: trunk/coregrind/m_aspacemgr/aspacemgr-linux.c (+18 -3)
===================================================================
--- trunk/coregrind/m_aspacemgr/aspacemgr-linux.c 2013-08-12 19:04:22 +01:00 (rev 13494)
+++ trunk/coregrind/m_aspacemgr/aspacemgr-linux.c 2013-08-12 23:17:47 +01:00 (rev 13495)
@@ -2448,7 +2448,19 @@
another thread can pre-empt our spot. [At one point on the DARWIN
branch the VKI_MAP_FIXED was commented out; unclear if this is
necessary or not given the second Darwin-only call that immediately
- follows if this one fails. --njn] */
+ follows if this one fails. --njn]
+ Also, an inner valgrind cannot observe the mmap syscalls done by
+ the outer valgrind. The outer Valgrind might make the mmap
+ fail here, as the inner valgrind believes that a segment is free,
+ while it is in fact used by the outer valgrind.
+ So, for an inner valgrind, similarly to DARWIN, if the fixed mmap
+ fails, retry the mmap without map fixed.
+ This is a kludge which on linux is only activated for the inner.
+ The state of the inner aspacemgr is not made correct by this kludge
+ and so a.o. VG_(am_do_sync_check) could fail.
+ A proper solution implies a better collaboration between the
+ inner and the outer (e.g. inner VG_(am_get_advisory) should do
+ a client request to call the outer VG_(am_get_advisory). */
sres = VG_(am_do_mmap_NO_NOTIFY)(
advised, length,
VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
@@ -2455,7 +2467,8 @@
VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS,
VM_TAG_VALGRIND, 0
);
-#if defined(VGO_darwin)
+#if defined(VGO_darwin) || defined(ENABLE_INNER)
+ /* Kludge on Darwin and inner linux if the fixed mmap failed. */
if (sr_isError(sres)) {
/* try again, ignoring the advisory */
sres = VG_(am_do_mmap_NO_NOTIFY)(
@@ -2469,7 +2482,9 @@
if (sr_isError(sres))
return sres;
-#if defined(VGO_linux)
+#if defined(VGO_linux) && !defined(ENABLE_INNER)
+ /* Doing the check only in linux not inner, as the below
+ check can fail when the kludge above has been used. */
if (sr_Res(sres) != advised) {
/* I don't think this can happen. It means the kernel made a
fixed map succeed but not at the requested location. Try to
Modified: trunk/coregrind/m_mallocfree.c (+4 -0)
===================================================================
--- trunk/coregrind/m_mallocfree.c 2013-08-12 19:04:22 +01:00 (rev 13494)
+++ trunk/coregrind/m_mallocfree.c 2013-08-12 23:17:47 +01:00 (rev 13495)
@@ -762,6 +762,10 @@
VG_(print_all_arena_stats) ();
if (VG_(clo_profile_heap))
VG_(print_arena_cc_analysis) ();
+ /* In case we are an inner valgrind, asks the outer to report
+ its memory state in its log output. */
+ INNER_REQUEST(VALGRIND_MONITOR_COMMAND("v.set log_output"));
+ INNER_REQUEST(VALGRIND_MONITOR_COMMAND("v.info memory aspacemgr"));
}
outputTrial++;
VG_(message)(Vg_UserMsg, s1, who, (ULong)szB, tot_alloc);
|