Hi, some of our servers use a feature we call "virtual ringbuffer" where we have a ringbuffer that guarantees to always offer its free space as one contiguous block to write to/read from. For this we use a somewhat undocumented feature of the linux kernel (see http://lkml.org/lkml/2004/1/12/265 and/or kernel sources) where mremap when the source size parameter is 0, really does not move the mapping but duplicates it (for MAP_SHARED mappings). Unfortunately valgrind does not seem to implement this, and when run under valgrind the attached program returns -1 from mremap (and sets errno to 22). I tried to run it on some february checkout of valgrind svn (everything 64bit here), and could not run it on a recent checkout since for some reason it does not compile here (lots of undefined references for symbols with s390 in the name).
(In reply to plasmahh from comment #0) > Hi, > > some of our servers use a feature we call "virtual ringbuffer" where we have > a ringbuffer that guarantees to always offer its free space as one > contiguous block to write to/read from. For this we use a somewhat > undocumented feature of the linux kernel (see > http://lkml.org/lkml/2004/1/12/265 and/or kernel sources) where mremap when > the source size parameter is 0, really does not move the mapping but > duplicates it (for MAP_SHARED mappings). > > Unfortunately valgrind does not seem to implement this, and when run under > valgrind the attached program returns -1 from mremap (and sets errno to 22). > > I tried to run it on some february checkout of valgrind svn (everything > 64bit here), and could not run it on a recent checkout since for some reason > it does not compile here (lots of undefined references for symbols with s390 > in the name).
Created attachment 121729 [details] mremap test program
I added a test case for this issue (see attachment). This is NOT an undocumented feature: If the value of old_size is zero, and old_address refers to a shareable mapping (see mmap(2) MAP_SHARED), then mremap() will create a new mapping of the same pages. new_size will be the size of the new mapping and the location of the new mapping may be specified with new_address; see the description of MREMAP_FIXED below. If a new mapping is requested via this method, then the MREMAP_MAYMOVE flag must also be specified. Run the program, you get: Initial map virtual address: 0x7f1498f8a000 Alias map virtual address : 0x7f1498f89000 Value at map : 0 Value at alias: 0 Value at map : 123 Value at alias: 123 Value at map : 456 Value at alias: 456 Run it in memcheck, you get EINVAL at the mremap. Regards, Eric
It's simply not implemented... Line 312 in coregrind/m_syswrap/syswrap-generic.c /* kernel doesn't reject this, but we do. */ if (old_len == 0) goto eINVAL; This behavior had been added to Linux man pages in Sept 2017 https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/commit/man2/mremap.2?id=aa002e8145e643dd7f3a6a1cbe20d5291738438a