]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
kludge to bypass inner valgrind mmap failing due to not observed outer mmap
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Mon, 12 Aug 2013 22:17:47 +0000 (22:17 +0000)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Mon, 12 Aug 2013 22:17:47 +0000 (22:17 +0000)
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.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13495

coregrind/m_aspacemgr/aspacemgr-linux.c
coregrind/m_mallocfree.c

index 9db3820a23ee89821a49af90d741a817c1753c03..970979300fd1d104528d24f8f829da6bcd8b8b96 100644 (file)
@@ -2448,14 +2448,27 @@ SysRes VG_(am_mmap_anon_float_valgrind)( SizeT length )
       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, 
              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 @@ SysRes VG_(am_mmap_anon_float_valgrind)( SizeT length )
    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
index 16bc81d536e66ff6bb3a210aa359b9c741faabac..d9e10e25ff543ae76f1eccc75f3e572dcca17e59 100644 (file)
@@ -762,6 +762,10 @@ void VG_(out_of_memory_NORETURN) ( const HChar* who, SizeT szB )
          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);