summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2016-02-24 10:09:23 -0800
committer Mathieu Chartier <mathieuc@google.com> 2016-02-24 10:59:00 -0800
commit83723aedac536fd8a3cd6e1662dbd6260e576194 (patch)
treeb49882ff8afa010fcdc06b4d58212f13ab646acf
parentc37a3eb8180d6488466961239eabc9ab0712bd05 (diff)
Add MapAnonymous handling for null error_str
We use MapAnonymous with null error_str for app image loading when we want to fail quickly. Also avoid doing CheckNonOverlapping in CheckMapRequest if error_msg is null. The result from CheckNonOverlapping is unused and CheckNonOverlapping is slow since it creates a backtrace map. Bug: 22858531 Bug: 26746779 Change-Id: I8605ec0b9d9ae554a4b74f2606fa7dd81ade9021
-rw-r--r--runtime/mem_map.cc34
-rw-r--r--runtime/mem_map_test.cc13
2 files changed, 33 insertions, 14 deletions
diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc
index c908b3920a..11156c6229 100644
--- a/runtime/mem_map.cc
+++ b/runtime/mem_map.cc
@@ -230,17 +230,16 @@ static bool CheckMapRequest(uint8_t* expected_ptr, void* actual_ptr, size_t byte
PLOG(WARNING) << StringPrintf("munmap(%p, %zd) failed", actual_ptr, byte_count);
}
- // We call this here so that we can try and generate a full error
- // message with the overlapping mapping. There's no guarantee that
- // that there will be an overlap though, since
- // - The kernel is not *required* to honor expected_ptr unless MAP_FIXED is
- // true, even if there is no overlap
- // - There might have been an overlap at the point of mmap, but the
- // overlapping region has since been unmapped.
- std::string error_detail;
- CheckNonOverlapping(expected, limit, &error_detail);
-
if (error_msg != nullptr) {
+ // We call this here so that we can try and generate a full error
+ // message with the overlapping mapping. There's no guarantee that
+ // that there will be an overlap though, since
+ // - The kernel is not *required* to honor expected_ptr unless MAP_FIXED is
+ // true, even if there is no overlap
+ // - There might have been an overlap at the point of mmap, but the
+ // overlapping region has since been unmapped.
+ std::string error_detail;
+ CheckNonOverlapping(expected, limit, &error_detail);
std::ostringstream os;
os << StringPrintf("Failed to mmap at expected address, mapped at "
"0x%08" PRIxPTR " instead of 0x%08" PRIxPTR,
@@ -338,11 +337,18 @@ MemMap* MemMap::MapAnonymous(const char* name,
saved_errno = errno;
if (actual == MAP_FAILED) {
- PrintFileToLog("/proc/self/maps", LogSeverity::WARNING);
+ if (error_msg != nullptr) {
+ PrintFileToLog("/proc/self/maps", LogSeverity::WARNING);
- *error_msg = StringPrintf("Failed anonymous mmap(%p, %zd, 0x%x, 0x%x, %d, 0): %s. See process "
- "maps in the log.", expected_ptr, page_aligned_byte_count, prot,
- flags, fd.get(), strerror(saved_errno));
+ *error_msg = StringPrintf("Failed anonymous mmap(%p, %zd, 0x%x, 0x%x, %d, 0): %s. "
+ "See process maps in the log.",
+ expected_ptr,
+ page_aligned_byte_count,
+ prot,
+ flags,
+ fd.get(),
+ strerror(saved_errno));
+ }
return nullptr;
}
std::ostringstream check_map_request_error_msg;
diff --git a/runtime/mem_map_test.cc b/runtime/mem_map_test.cc
index 81c855e736..e703b78cfa 100644
--- a/runtime/mem_map_test.cc
+++ b/runtime/mem_map_test.cc
@@ -164,6 +164,19 @@ TEST_F(MemMapTest, MapAnonymousEmpty) {
ASSERT_TRUE(error_msg.empty());
}
+TEST_F(MemMapTest, MapAnonymousFailNullError) {
+ CommonInit();
+ // Test that we don't crash with a null error_str when mapping at an invalid location.
+ std::unique_ptr<MemMap> map(MemMap::MapAnonymous("MapAnonymousInvalid",
+ reinterpret_cast<uint8_t*>(kPageSize),
+ 0x20000,
+ PROT_READ | PROT_WRITE,
+ false,
+ false,
+ nullptr));
+ ASSERT_EQ(nullptr, map.get());
+}
+
#ifdef __LP64__
TEST_F(MemMapTest, MapAnonymousEmpty32bit) {
CommonInit();