mmap 返回 EINVAL 当与 Valgrind 一起运行时



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

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

当客户端应用程序针对 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. */

相关内容

最新更新