当使用Valgrind运行时,mmap返回EINVAL

时间:2014-12-09 15:28:18

标签: valgrind mmap mips32

针对Valgrind运行的mips32应用程序在mmap函数中失败。如果我单独运行它可以正常工作但是当我对valgrind运行它时,它每次都会失败,并且EINVAL。

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

1 个答案:

答案 0 :(得分:3)

当客户端应用程序针对Valgrind运行时,Valgrind会拦截客户端发出的mmap调用。然后,它通过设置MAP_FIXED标志来调用内核的mmap函数,并指定要映射的内存位置。然后内核将尝试映射到此建议的内存。当建议的位置不可用于映射时,内核返回失败(EINVAL),因为MAP_FIXED标志已设置。上面的函数调用将被翻译成,

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

您可以修改Valgrind的mmap函数来修复此行为。删除MAP_FIXED标志并重试mmap,而不指定建议的内存地址。

--- .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's 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's choice
+
+ /* A refinement: it may be that the kernel refused aspacem's 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. */