Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Unified Diff: components/tracing/common/process_metrics_memory_dump_provider.cc

Issue 2601193002: Emit VMRegions for macOS when doing process memory dumps. (Closed)
Patch Set: Switch back to region recurse. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/tracing/common/process_metrics_memory_dump_provider.cc
diff --git a/components/tracing/common/process_metrics_memory_dump_provider.cc b/components/tracing/common/process_metrics_memory_dump_provider.cc
index 593755bada11899c83bd93f32689d819cd09fae7..f5a9471be463bd3f8429cc719cd8368f25ad46d5 100644
--- a/components/tracing/common/process_metrics_memory_dump_provider.cc
+++ b/components/tracing/common/process_metrics_memory_dump_provider.cc
@@ -24,6 +24,15 @@
#include "base/trace_event/process_memory_totals.h"
#include "build/build_config.h"
+#if defined(OS_MACOSX)
+#include <libproc.h>
+#include <mach/mach.h>
+#include <mach/mach_vm.h>
+#include <sys/param.h>
+
+#include "base/numerics/safe_math.h"
+#endif // defined(OS_MACOSX)
+
namespace tracing {
namespace {
@@ -219,6 +228,93 @@ bool ProcessMetricsMemoryDumpProvider::DumpProcessMemoryMaps(
}
#endif // defined(OS_LINUX) || defined(OS_ANDROID)
+#if defined(OS_MACOSX)
+bool ProcessMetricsMemoryDumpProvider::DumpProcessMemoryMaps(
+ const base::trace_event::MemoryDumpArgs& args,
+ base::trace_event::ProcessMemoryDump* pmd) {
+ const int pid = getpid();
+ task_t task = mach_task_self();
+ using VMRegion = base::trace_event::ProcessMemoryMaps::VMRegion;
+ mach_vm_size_t size = 0;
+ vm_region_submap_info_64 info;
+ natural_t depth = 1;
+ mach_msg_type_number_t count = sizeof(info);
+ for (mach_vm_address_t address = MACH_VM_MIN_ADDRESS;; address += size) {
+ memset(&info, 0, sizeof(info));
+ kern_return_t kr = mach_vm_region_recurse(
+ task, &address, &size, &depth,
+ reinterpret_cast<vm_region_info_t>(&info), &count);
+ if (kr == KERN_INVALID_ADDRESS) // nothing else left
+ break;
+ if (kr != KERN_SUCCESS) // something bad
+ return false;
+ if (info.is_submap) {
+ size = 0;
+ ++depth;
+ continue;
+ }
+
+ if (info.share_mode == SM_COW && info.ref_count == 1)
+ info.share_mode = SM_PRIVATE;
+
+ VMRegion region;
+ uint64_t dirty_bytes = info.pages_dirtied * PAGE_SIZE;
+ uint64_t clean_bytes =
+ (info.pages_resident - info.pages_reusable - info.pages_dirtied) *
+ PAGE_SIZE;
+ switch (info.share_mode) {
+ case SM_LARGE_PAGE:
+ case SM_PRIVATE:
+ region.byte_stats_private_dirty_resident = dirty_bytes;
+ region.byte_stats_private_clean_resident = clean_bytes;
+ break;
+ case SM_COW:
+ region.byte_stats_private_dirty_resident = dirty_bytes;
+ region.byte_stats_shared_clean_resident = clean_bytes;
+ break;
+ case SM_SHARED:
+ case SM_PRIVATE_ALIASED:
+ case SM_TRUESHARED:
+ case SM_SHARED_ALIASED:
+ region.byte_stats_shared_dirty_resident = dirty_bytes;
+ region.byte_stats_shared_clean_resident = clean_bytes;
+ break;
+ case SM_EMPTY:
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+
+ if (info.protection & VM_PROT_READ)
+ region.protection_flags |= VMRegion::kProtectionFlagsRead;
+ if (info.protection & VM_PROT_WRITE)
+ region.protection_flags |= VMRegion::kProtectionFlagsWrite;
+ if (info.protection & VM_PROT_EXECUTE)
+ region.protection_flags |= VMRegion::kProtectionFlagsExec;
+
+ char buffer[MAXPATHLEN];
+ int length = proc_regionfilename(pid, address, buffer, MAXPATHLEN);
+ if (length != 0)
+ region.mapped_file.assign(buffer, length);
+
+ region.byte_stats_swapped = info.pages_swapped_out * PAGE_SIZE;
+ region.start_address = address;
+ region.size_in_bytes = size;
+ pmd->process_mmaps()->AddVMRegion(region);
+
+ base::CheckedNumeric<mach_vm_address_t> numeric(address);
+ numeric += size;
+ if (!numeric.IsValid())
+ break;
+ address = numeric.ValueOrDie();
+ }
+
+ pmd->set_has_process_mmaps();
+ return true;
+}
+#endif // defined(OS_MACOSX)
+
// static
void ProcessMetricsMemoryDumpProvider::RegisterForProcess(
base::ProcessId process) {
@@ -267,11 +363,11 @@ bool ProcessMetricsMemoryDumpProvider::OnMemoryDump(
base::trace_event::ProcessMemoryDump* pmd) {
bool res = DumpProcessTotals(args, pmd);
-#if defined(OS_LINUX) || defined(OS_ANDROID)
+#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_MACOSX)
if (args.level_of_detail ==
base::trace_event::MemoryDumpLevelOfDetail::DETAILED)
res &= DumpProcessMemoryMaps(args, pmd);
-#endif
+#endif // defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_MACOSX)
return res;
}

Powered by Google App Engine
This is Rietveld 408576698