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}
diff --git a/base/trace_event/process_memory_dump.cc b/base/trace_event/process_memory_dump.cc
index 2fbe531d..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 @@
 
 #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);