Fix valgrind errors with MemMap::Sync().
This fixes valgrind-test-art-host-gtest-oat_test and one error in
valgrind-test-art-host-gtest-image_test32.
Valgrind doesn't like it if an address range that contains noaccess or
uninitialized memory is passed to msync(). Temporarily lift the noaccess
protection of the lower-end redzone because msync accepts a page-aligned
base address only and exclude the higher-end noaccess redzone from the
range.
Bug: 27552451
Bug: 27384445
Change-Id: I8ccbd04c62eb30f6c6d5c732f1eb254fa09a417a
diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc
index 11156c6..421641c 100644
--- a/runtime/mem_map.cc
+++ b/runtime/mem_map.cc
@@ -590,7 +590,19 @@
}
bool MemMap::Sync() {
- return msync(BaseBegin(), BaseSize(), MS_SYNC) == 0;
+ bool result;
+ if (redzone_size_ != 0) {
+ // To avoid valgrind errors, temporarily lift the lower-end noaccess protection before passing
+ // it to msync() as it only accepts page-aligned base address, and exclude the higher-end
+ // noaccess protection from the msync range. b/27552451.
+ uint8_t* base_begin = reinterpret_cast<uint8_t*>(base_begin_);
+ MEMORY_TOOL_MAKE_DEFINED(base_begin, begin_ - base_begin);
+ result = msync(BaseBegin(), End() - base_begin, MS_SYNC) == 0;
+ MEMORY_TOOL_MAKE_NOACCESS(base_begin, begin_ - base_begin);
+ } else {
+ result = msync(BaseBegin(), BaseSize(), MS_SYNC) == 0;
+ }
+ return result;
}
bool MemMap::Protect(int prot) {