Support null error_msg for select MemMap functions
In the failure case, reading proc maps takes 30ms. This is too slow
for app images.
Bug: 22858531
Change-Id: Ib6998cf82116720b23faec89d011fb7197c3d1cb
diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc
index 4b2ac20..e133847 100644
--- a/runtime/mem_map.cc
+++ b/runtime/mem_map.cc
@@ -154,8 +154,10 @@
}
std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true));
- if (map.get() == nullptr) {
- *error_msg = StringPrintf("Failed to build process map");
+ if (map == nullptr) {
+ if (error_msg != nullptr) {
+ *error_msg = StringPrintf("Failed to build process map");
+ }
return false;
}
for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) {
@@ -164,9 +166,11 @@
return true;
}
}
- PrintFileToLog("/proc/self/maps", LogSeverity::ERROR);
- *error_msg = StringPrintf("Requested region 0x%08" PRIxPTR "-0x%08" PRIxPTR " does not overlap "
- "any existing map. See process maps in the log.", begin, end);
+ if (error_msg != nullptr) {
+ PrintFileToLog("/proc/self/maps", LogSeverity::ERROR);
+ *error_msg = StringPrintf("Requested region 0x%08" PRIxPTR "-0x%08" PRIxPTR " does not overlap "
+ "any existing map. See process maps in the log.", begin, end);
+ }
return false;
}
@@ -239,15 +243,16 @@
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,
- actual, expected);
- if (!error_detail.empty()) {
- os << " : " << error_detail;
+ if (error_msg != nullptr) {
+ std::ostringstream os;
+ os << StringPrintf("Failed to mmap at expected address, mapped at "
+ "0x%08" PRIxPTR " instead of 0x%08" PRIxPTR,
+ actual, expected);
+ if (!error_detail.empty()) {
+ os << " : " << error_detail;
+ }
+ *error_msg = os.str();
}
-
- *error_msg = os.str();
return false;
}
@@ -379,7 +384,8 @@
// Only use this if you actually made the page reservation yourself.
CHECK(expected_ptr != nullptr);
- DCHECK(ContainedWithinExistingMap(expected_ptr, byte_count, error_msg)) << *error_msg;
+ DCHECK(ContainedWithinExistingMap(expected_ptr, byte_count, error_msg))
+ << ((error_msg != nullptr) ? *error_msg : std::string());
flags |= MAP_FIXED;
} else {
CHECK_EQ(0, flags & MAP_FIXED);
@@ -414,15 +420,17 @@
page_aligned_offset,
low_4gb));
if (actual == MAP_FAILED) {
- auto saved_errno = errno;
+ if (error_msg != nullptr) {
+ auto saved_errno = errno;
- PrintFileToLog("/proc/self/maps", LogSeverity::WARNING);
+ PrintFileToLog("/proc/self/maps", LogSeverity::WARNING);
- *error_msg = StringPrintf("mmap(%p, %zd, 0x%x, 0x%x, %d, %" PRId64
- ") of file '%s' failed: %s. See process maps in the log.",
- page_aligned_expected, page_aligned_byte_count, prot, flags, fd,
- static_cast<int64_t>(page_aligned_offset), filename,
- strerror(saved_errno));
+ *error_msg = StringPrintf("mmap(%p, %zd, 0x%x, 0x%x, %d, %" PRId64
+ ") of file '%s' failed: %s. See process maps in the log.",
+ page_aligned_expected, page_aligned_byte_count, prot, flags, fd,
+ static_cast<int64_t>(page_aligned_offset), filename,
+ strerror(saved_errno));
+ }
return nullptr;
}
std::ostringstream check_map_request_error_msg;
diff --git a/runtime/mem_map.h b/runtime/mem_map.h
index a67a925..efce09a 100644
--- a/runtime/mem_map.h
+++ b/runtime/mem_map.h
@@ -99,11 +99,12 @@
error_msg);
}
- // Map part of a file, taking care of non-page aligned offsets. The
- // "start" offset is absolute, not relative. This version allows
- // requesting a specific address for the base of the
- // mapping. "reuse" allows us to create a view into an existing
- // mapping where we do not take ownership of the memory.
+ // Map part of a file, taking care of non-page aligned offsets. The "start" offset is absolute,
+ // not relative. This version allows requesting a specific address for the base of the mapping.
+ // "reuse" allows us to create a view into an existing mapping where we do not take ownership of
+ // the memory. If error_msg is null then we do not print /proc/maps to the log if
+ // MapFileAtAddress fails. This helps improve performance of the fail case since reading and
+ // printing /proc/maps takes several milliseconds in the worst case.
//
// On success, returns returns a MemMap instance. On failure, returns null.
static MemMap* MapFileAtAddress(uint8_t* addr,