Created attachment 41098 [details] A patch that adds an mmap() interceptor to Helgrind. Trying to debug ThreadSanitizer's (http://code.google.com/p/data-race-test) mmap() interceptor on Mac OS I've came up with the following test: ============================= #include <sys/types.h> #include <sys/mman.h> #include <stdio.h> #include <errno.h> int main () { int md; caddr_t virt_addr; md = shm_open ("apple.shm.notification_center", 0, 0); virt_addr = mmap(0, 4096, 1, 1, md, 0); if (virt_addr == (void*) -1) { printf("errno: %d\n", errno); perror("perror"); } printf("mmap: %p\n", virt_addr); return 0; } ============================= When ran natively, mmap succeeds and virt_addr is 0x8000 However, when ran under ThreadSanitizer mmap fails returning -1 and errno is 22 (EINVAL). Other Valgrind tools (Nullgrind, Memcheck, DRD) behave normally, because none of them intercepts mmap(). Disabling the mmap() interceptor fixes the problem, but is unacceptable for us. I've tried adding the WRAP_MMAP macro to Helgrind (see the patch) and managed to reproduce the same behavior: valgrind -v --tool=helgrind ~/src/shm_test/shm ==49272== Helgrind, a thread error detector ... --49272-- REDIR: 0x200af8 (mmap) redirected to 0x17f42 (mmap) errno: 22 --49272-- REDIR: 0x1fff20 (strlen) redirected to 0x1905c (strlen) perror: Invalid argument mmap: 0xffffffff ==49272== ==49272== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6) As the mmap wrapper for Helgrind is really strict and consists of nothing but a call to CALL_FN_W_6W, I believe that CALL_FN_W_6W incorrectly passes the parameters to the original function.
Does memcheck/tests/wrap6.c work? In fact you should verify that all the memcheck/tests/wrap*.c tests work.
Yes, each of them works. I've also tried to make a binary with a 6-args function that prints its own arguments and wrap this function -- the arguments seemed to be passed correctly. Could the system calls like mmap pass their arguments in a different way?
NB: the misbehaviour of mmap is observed iff the file descriptor used by mmap is returned by shm_open called for "apple.shm.notification_center". Maybe the problem is really mmap-specific.
The extract from the Helgrind run with --trace-syscalls: $ valgrind --trace-syscalls=yes -v --tool=helgrind ./shm ... SYSCALL[67703,1](mach: 27) mach_thread_self()[sync] --> Success(0x0:0x50b) thread 0x50b SYSCALL[67703,1](mach: 27) mach_thread_self()[sync] --> Success(0x0:0x50b) thread 0x50b SYSCALL[67703,1](unix:266) shm_open(0x1fc0(apple.shm.notification_center), 0, 0) --> [async] ... SYSCALL[67703,1](unix:266) ... [async] --> Success(0xbffffaec:0x3) SYSCALL[67703,1](unix:339) fstat64 ( 1, 0xbffff254 )[sync] --> Success(0x153:0x0) --67703-- REDIR: 0x200af8 (mmap) redirected to 0x17f42 (mmap) SYSCALL[67703,1](unix:197) mmap ( 0x0, 4096, 1, 1, 3, -4294967296 )[sync] --> Failure(0x16) ... Looks like the last parameter is -0x100000000 instead of 0.
CALL_FN_*_** only work for word-sized args. Are you sure all the args are 32-bit values?
Oh, looks like the last mmap() argument is a 64-bit value on Darwin. Is it possible to wrap such a function?
Looks like CALL_FN_W_7W should work for mmap. Sorry for bothering.