Bug 228471

Summary: CALL_FN_W_6W is possibly broken on Darwin
Product: [Developer tools] valgrind Reporter: Alexander Potapenko <glider>
Component: generalAssignee: Julian Seward <jseward>
Status: RESOLVED NOT A BUG    
Severity: normal    
Priority: NOR    
Version: 3.6 SVN   
Target Milestone: ---   
Platform: Unlisted Binaries   
OS: macOS   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: A patch that adds an mmap() interceptor to Helgrind.

Description Alexander Potapenko 2010-02-25 15:57:36 UTC
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.
Comment 1 Julian Seward 2010-02-25 16:05:24 UTC
Does memcheck/tests/wrap6.c work?  In fact you should verify
that all the memcheck/tests/wrap*.c tests work.
Comment 2 Alexander Potapenko 2010-02-25 16:22:47 UTC
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?
Comment 3 Alexander Potapenko 2010-02-25 16:39:43 UTC
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.
Comment 4 Alexander Potapenko 2010-02-25 17:20:38 UTC
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.
Comment 5 Julian Seward 2010-02-25 17:37:05 UTC
CALL_FN_*_** only work for word-sized args.  Are you sure
all the args are 32-bit values?
Comment 6 Alexander Potapenko 2010-02-25 17:43:55 UTC
Oh, looks like the last mmap() argument is a 64-bit value on Darwin.
Is it possible to wrap such a function?
Comment 7 Alexander Potapenko 2010-02-25 17:50:12 UTC
Looks like CALL_FN_W_7W should work for mmap. Sorry for bothering.