summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorpkl <pkl@chromium.org>2016-03-16 09:57:29 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-16 16:59:33 +0000
commit0b19e32e90d7affe4fcee8b2613392a1c20fdf0d (patch)
tree2d8c4a009371937a6c503891f14ac698d4db1612 /base
parent3f9f32bb241cc088ecdbc2547ce3cb4b703d1c9a (diff)
downloadchromium_src-0b19e32e90d7affe4fcee8b2613392a1c20fdf0d.zip
chromium_src-0b19e32e90d7affe4fcee8b2613392a1c20fdf0d.tar.gz
chromium_src-0b19e32e90d7affe4fcee8b2613392a1c20fdf0d.tar.bz2
Use sysctlbyname() to get kernel page size.
This allows enabling of COUNT_RESIDENT_BYTES_SUPPORTED tests. It is also possible to change iOS' implementation of base::GetPageSize() implementation to use sysctlbyname() instead of getpagesize(), but since it is only the use of mincore() that requires the use of kernel page size, it is better to have a smaller change than a more invasive change to base::GetPageSize(). I'm concerned that changing GetPageSize() to return 4KB (what sysctlbyname returns) instead of 16KB (what getpagesize returns) may have some unknown side effects. BUG=542671 Review URL: https://codereview.chromium.org/1793943002 Cr-Commit-Position: refs/heads/master@{#381475}
Diffstat (limited to 'base')
-rw-r--r--base/trace_event/process_memory_dump.cc25
-rw-r--r--base/trace_event/process_memory_dump.h11
-rw-r--r--base/trace_event/process_memory_dump_unittest.cc2
3 files changed, 32 insertions, 6 deletions
diff --git a/base/trace_event/process_memory_dump.cc b/base/trace_event/process_memory_dump.cc
index 2fbe531..74cbcc29 100644
--- a/base/trace_event/process_memory_dump.cc
+++ b/base/trace_event/process_memory_dump.cc
@@ -12,6 +12,10 @@
#include "base/trace_event/trace_event_argument.h"
#include "build/build_config.h"
+#if defined(OS_IOS)
+#include <sys/sysctl.h>
+#endif
+
#if defined(OS_POSIX)
#include <sys/mman.h>
#endif
@@ -42,9 +46,28 @@ size_t GetSystemPageCount(size_t mapped_size, size_t page_size) {
#if defined(COUNT_RESIDENT_BYTES_SUPPORTED)
// static
+size_t ProcessMemoryDump::GetSystemPageSize() {
+#if defined(OS_IOS)
+ // On iOS, getpagesize() returns the user page sizes, but for allocating
+ // arrays for mincore(), kernel page sizes is needed. sysctlbyname() should
+ // be used for this. Refer to crbug.com/542671 and Apple rdar://23651782
+ int pagesize;
+ size_t pagesize_len;
+ int status = sysctlbyname("vm.pagesize", NULL, &pagesize_len, nullptr, 0);
+ if (!status && pagesize_len == sizeof(pagesize)) {
+ if (!sysctlbyname("vm.pagesize", &pagesize, &pagesize_len, nullptr, 0))
+ return pagesize;
+ }
+ LOG(ERROR) << "sysctlbyname(\"vm.pagesize\") failed.";
+ // Falls back to getpagesize() although it may be wrong in certain cases.
+#endif // defined(OS_IOS)
+ return base::GetPageSize();
+}
+
+// static
size_t ProcessMemoryDump::CountResidentBytes(void* start_address,
size_t mapped_size) {
- const size_t page_size = GetPageSize();
+ const size_t page_size = GetSystemPageSize();
const uintptr_t start_pointer = reinterpret_cast<uintptr_t>(start_address);
DCHECK_EQ(0u, start_pointer % page_size);
diff --git a/base/trace_event/process_memory_dump.h b/base/trace_event/process_memory_dump.h
index e2503c5..37c0aa1 100644
--- a/base/trace_event/process_memory_dump.h
+++ b/base/trace_event/process_memory_dump.h
@@ -23,10 +23,7 @@
// Define COUNT_RESIDENT_BYTES_SUPPORTED if platform supports counting of the
// resident memory.
-// TODO(crbug.com/542671): COUNT_RESIDENT_BYTES_SUPPORTED is disabled on iOS
-// as it cause memory corruption on iOS 9.0+ devices.
-#if (defined(OS_POSIX) && !defined(OS_NACL) && !defined(OS_IOS)) || \
- defined(OS_WIN)
+#if (defined(OS_POSIX) && !defined(OS_NACL)) || defined(OS_WIN)
#define COUNT_RESIDENT_BYTES_SUPPORTED
#endif
@@ -56,6 +53,12 @@ class BASE_EXPORT ProcessMemoryDump {
using HeapDumpsMap = std::unordered_map<std::string, scoped_ptr<TracedValue>>;
#if defined(COUNT_RESIDENT_BYTES_SUPPORTED)
+ // Returns the number of bytes in a kernel memory page. Some platforms may
+ // have a different value for kernel page sizes from user page sizes. It is
+ // important to use kernel memory page sizes for resident bytes calculation.
+ // In most cases, the two are the same.
+ static size_t GetSystemPageSize();
+
// Returns the total bytes resident for a virtual address range, with given
// |start_address| and |mapped_size|. |mapped_size| is specified in bytes. The
// value returned is valid only if the given range is currently mmapped by the
diff --git a/base/trace_event/process_memory_dump_unittest.cc b/base/trace_event/process_memory_dump_unittest.cc
index cf87c94..e7fe960 100644
--- a/base/trace_event/process_memory_dump_unittest.cc
+++ b/base/trace_event/process_memory_dump_unittest.cc
@@ -223,7 +223,7 @@ TEST(ProcessMemoryDumpTest, GlobalAllocatorDumpTest) {
#if defined(COUNT_RESIDENT_BYTES_SUPPORTED)
TEST(ProcessMemoryDumpTest, CountResidentBytes) {
- const size_t page_size = base::GetPageSize();
+ const size_t page_size = ProcessMemoryDump::GetSystemPageSize();
// Allocate few page of dirty memory and check if it is resident.
const size_t size1 = 5 * page_size;