Mmap returns EINVAL when run with Valgrind

The mips32 application running against Valgrind crashes in the mmap function. It works fine if I run it separately, but when I run it against valgrind it fails with EINVAL every time.

   void * mem = (uint32_t *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, <fd>,
                                 mmap_size);

      

+3


source to share


1 answer


When a client application is launched against Valgrind, Valgrind intercepts the mmap call made by the client. It then calls the kernel mmap function, setting the MAP_FIXED flag, and specifying the memory location to map. The kernel will then try to map this recommended memory. When the recommended location is not available for mapping, the kernel returns EINVAL because the MAP_FIXED flag is set. The above function call will translate to

void * mem = (uint32_t *)mmap( advised_memory, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, <fd>,
                                               mmap_size);

      



You can modify Valgrind's mmap function to fix this behavior. Remove the MAP_FIXED flag and repeat mmap without specifying the recommended memory address.

--- .coregrind/m_syswrap/syswrap-mips32-linux.c 2014-09-08 13:28:45.000000000 +0100
+++ coregrind/m_syswrap/syswrap-mips32-linux.c 2014-11-19 12:12:43.000000000 +0000
@@ -452,10 +452,11 @@
/* Otherwise we're OK (so far). Install aspacem choice of
address, and let the mmap go through. */
sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
- arg4 | VKI_MAP_FIXED,
+ arg4,
arg5, arg6);

- /* A refinement: it may be that the kernel refused aspacem choice
+
+ /* A refinement: it may be that the kernel refused aspacem choice
of address. If we were originally asked for a hinted mapping,
there is still a last chance: try again at any address.
Hence: */
@@ -470,10 +471,20 @@
}
/* and try again with the kernel */
sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
- arg4 | VKI_MAP_FIXED,
+ arg4,
+ arg5, arg6);
+
+ if( sr_isError(sres) )
+ sres = VG_(am_do_mmap_NO_NOTIFY)(NULL, arg2, arg3,
+ arg4,
arg5, arg6);
}

+ if( sr_isError(sres) )
+ sres = VG_(am_do_mmap_NO_NOTIFY)(NULL, arg2, arg3,
+ arg4,
+ arg5, arg6);
+ 
if (!sr_isError(sres)) {
ULong di_handle;
/* Notify aspacem. */

      

+2


source







All Articles