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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/tracing/common/process_metrics_memory_dump_provider.h" 5 #include "components/tracing/common/process_metrics_memory_dump_provider.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <map> 10 #include <map>
11 11
12 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
13 #include "base/files/scoped_file.h" 13 #include "base/files/scoped_file.h"
14 #include "base/format_macros.h" 14 #include "base/format_macros.h"
15 #include "base/lazy_instance.h" 15 #include "base/lazy_instance.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/memory/ptr_util.h" 17 #include "base/memory/ptr_util.h"
18 #include "base/process/process_metrics.h" 18 #include "base/process/process_metrics.h"
19 #include "base/strings/string_number_conversions.h" 19 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
21 #include "base/trace_event/memory_dump_manager.h" 21 #include "base/trace_event/memory_dump_manager.h"
22 #include "base/trace_event/process_memory_dump.h" 22 #include "base/trace_event/process_memory_dump.h"
23 #include "base/trace_event/process_memory_maps.h" 23 #include "base/trace_event/process_memory_maps.h"
24 #include "base/trace_event/process_memory_totals.h" 24 #include "base/trace_event/process_memory_totals.h"
25 #include "build/build_config.h" 25 #include "build/build_config.h"
26 26
27 #if defined(OS_MACOSX)
28 #include <libproc.h>
29 #include <mach/mach.h>
30 #include <mach/mach_vm.h>
31 #include <sys/param.h>
32
33 #include "base/numerics/safe_math.h"
34 #endif // defined(OS_MACOSX)
35
27 namespace tracing { 36 namespace tracing {
28 37
29 namespace { 38 namespace {
30 39
31 base::LazyInstance< 40 base::LazyInstance<
32 std::map<base::ProcessId, 41 std::map<base::ProcessId,
33 std::unique_ptr<ProcessMetricsMemoryDumpProvider>>>::Leaky 42 std::unique_ptr<ProcessMetricsMemoryDumpProvider>>>::Leaky
34 g_dump_providers_map = LAZY_INSTANCE_INITIALIZER; 43 g_dump_providers_map = LAZY_INSTANCE_INITIALIZER;
35 44
36 #if defined(OS_LINUX) || defined(OS_ANDROID) 45 #if defined(OS_LINUX) || defined(OS_ANDROID)
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 base::ScopedFILE smaps_file(fopen(file_name.c_str(), "r")); 221 base::ScopedFILE smaps_file(fopen(file_name.c_str(), "r"));
213 res = ReadLinuxProcSmapsFile(smaps_file.get(), pmd->process_mmaps()); 222 res = ReadLinuxProcSmapsFile(smaps_file.get(), pmd->process_mmaps());
214 } 223 }
215 224
216 if (res) 225 if (res)
217 pmd->set_has_process_mmaps(); 226 pmd->set_has_process_mmaps();
218 return res; 227 return res;
219 } 228 }
220 #endif // defined(OS_LINUX) || defined(OS_ANDROID) 229 #endif // defined(OS_LINUX) || defined(OS_ANDROID)
221 230
231 #if defined(OS_MACOSX)
232 bool ProcessMetricsMemoryDumpProvider::DumpProcessMemoryMaps(
233 const base::trace_event::MemoryDumpArgs& args,
234 base::trace_event::ProcessMemoryDump* pmd) {
235 const int pid = getpid();
236 task_t task = mach_task_self();
237 using VMRegion = base::trace_event::ProcessMemoryMaps::VMRegion;
238 mach_vm_size_t size = 0;
239 vm_region_submap_info_64 info;
240 natural_t depth = 1;
241 mach_msg_type_number_t count = sizeof(info);
242 for (mach_vm_address_t address = MACH_VM_MIN_ADDRESS;; address += size) {
243 memset(&info, 0, sizeof(info));
244 kern_return_t kr = mach_vm_region_recurse(
245 task, &address, &size, &depth,
246 reinterpret_cast<vm_region_info_t>(&info), &count);
247 if (kr == KERN_INVALID_ADDRESS) // nothing else left
248 break;
249 if (kr != KERN_SUCCESS) // something bad
250 return false;
251 if (info.is_submap) {
252 size = 0;
253 ++depth;
254 continue;
255 }
256
257 if (info.share_mode == SM_COW && info.ref_count == 1)
258 info.share_mode = SM_PRIVATE;
259
260 VMRegion region;
261 uint64_t dirty_bytes = info.pages_dirtied * PAGE_SIZE;
262 uint64_t clean_bytes =
263 (info.pages_resident - info.pages_reusable - info.pages_dirtied) *
264 PAGE_SIZE;
265 switch (info.share_mode) {
266 case SM_LARGE_PAGE:
267 case SM_PRIVATE:
268 region.byte_stats_private_dirty_resident = dirty_bytes;
269 region.byte_stats_private_clean_resident = clean_bytes;
270 break;
271 case SM_COW:
272 region.byte_stats_private_dirty_resident = dirty_bytes;
273 region.byte_stats_shared_clean_resident = clean_bytes;
274 break;
275 case SM_SHARED:
276 case SM_PRIVATE_ALIASED:
277 case SM_TRUESHARED:
278 case SM_SHARED_ALIASED:
279 region.byte_stats_shared_dirty_resident = dirty_bytes;
280 region.byte_stats_shared_clean_resident = clean_bytes;
281 break;
282 case SM_EMPTY:
283 break;
284 default:
285 NOTREACHED();
286 break;
287 }
288
289 if (info.protection & VM_PROT_READ)
290 region.protection_flags |= VMRegion::kProtectionFlagsRead;
291 if (info.protection & VM_PROT_WRITE)
292 region.protection_flags |= VMRegion::kProtectionFlagsWrite;
293 if (info.protection & VM_PROT_EXECUTE)
294 region.protection_flags |= VMRegion::kProtectionFlagsExec;
295
296 char buffer[MAXPATHLEN];
297 int length = proc_regionfilename(pid, address, buffer, MAXPATHLEN);
298 if (length != 0)
299 region.mapped_file.assign(buffer, length);
300
301 region.byte_stats_swapped = info.pages_swapped_out * PAGE_SIZE;
302 region.start_address = address;
303 region.size_in_bytes = size;
304 pmd->process_mmaps()->AddVMRegion(region);
305
306 base::CheckedNumeric<mach_vm_address_t> numeric(address);
307 numeric += size;
308 if (!numeric.IsValid())
309 break;
310 address = numeric.ValueOrDie();
311 }
312
313 pmd->set_has_process_mmaps();
314 return true;
315 }
316 #endif // defined(OS_MACOSX)
317
222 // static 318 // static
223 void ProcessMetricsMemoryDumpProvider::RegisterForProcess( 319 void ProcessMetricsMemoryDumpProvider::RegisterForProcess(
224 base::ProcessId process) { 320 base::ProcessId process) {
225 std::unique_ptr<ProcessMetricsMemoryDumpProvider> metrics_provider( 321 std::unique_ptr<ProcessMetricsMemoryDumpProvider> metrics_provider(
226 new ProcessMetricsMemoryDumpProvider(process)); 322 new ProcessMetricsMemoryDumpProvider(process));
227 base::trace_event::MemoryDumpProvider::Options options; 323 base::trace_event::MemoryDumpProvider::Options options;
228 options.target_pid = process; 324 options.target_pid = process;
229 options.is_fast_polling_supported = true; 325 options.is_fast_polling_supported = true;
230 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( 326 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
231 metrics_provider.get(), "ProcessMemoryMetrics", nullptr, options); 327 metrics_provider.get(), "ProcessMemoryMetrics", nullptr, options);
(...skipping 28 matching lines...) Expand all
260 356
261 ProcessMetricsMemoryDumpProvider::~ProcessMetricsMemoryDumpProvider() {} 357 ProcessMetricsMemoryDumpProvider::~ProcessMetricsMemoryDumpProvider() {}
262 358
263 // Called at trace dump point time. Creates a snapshot of the memory maps for 359 // Called at trace dump point time. Creates a snapshot of the memory maps for
264 // the current process. 360 // the current process.
265 bool ProcessMetricsMemoryDumpProvider::OnMemoryDump( 361 bool ProcessMetricsMemoryDumpProvider::OnMemoryDump(
266 const base::trace_event::MemoryDumpArgs& args, 362 const base::trace_event::MemoryDumpArgs& args,
267 base::trace_event::ProcessMemoryDump* pmd) { 363 base::trace_event::ProcessMemoryDump* pmd) {
268 bool res = DumpProcessTotals(args, pmd); 364 bool res = DumpProcessTotals(args, pmd);
269 365
270 #if defined(OS_LINUX) || defined(OS_ANDROID) 366 #if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_MACOSX)
271 if (args.level_of_detail == 367 if (args.level_of_detail ==
272 base::trace_event::MemoryDumpLevelOfDetail::DETAILED) 368 base::trace_event::MemoryDumpLevelOfDetail::DETAILED)
273 res &= DumpProcessMemoryMaps(args, pmd); 369 res &= DumpProcessMemoryMaps(args, pmd);
274 #endif 370 #endif // defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_MACOSX)
275 return res; 371 return res;
276 } 372 }
277 373
278 bool ProcessMetricsMemoryDumpProvider::DumpProcessTotals( 374 bool ProcessMetricsMemoryDumpProvider::DumpProcessTotals(
279 const base::trace_event::MemoryDumpArgs& args, 375 const base::trace_event::MemoryDumpArgs& args,
280 base::trace_event::ProcessMemoryDump* pmd) { 376 base::trace_event::ProcessMemoryDump* pmd) {
281 const uint64_t rss_bytes = rss_bytes_for_testing 377 const uint64_t rss_bytes = rss_bytes_for_testing
282 ? rss_bytes_for_testing 378 ? rss_bytes_for_testing
283 : process_metrics_->GetWorkingSetSize(); 379 : process_metrics_->GetWorkingSetSize();
284 380
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 #endif 463 #endif
368 } 464 }
369 465
370 void ProcessMetricsMemoryDumpProvider::SuspendFastMemoryPolling() { 466 void ProcessMetricsMemoryDumpProvider::SuspendFastMemoryPolling() {
371 #if defined(OS_LINUX) || defined(OS_ANDROID) 467 #if defined(OS_LINUX) || defined(OS_ANDROID)
372 fast_polling_statm_fd_.reset(); 468 fast_polling_statm_fd_.reset();
373 #endif 469 #endif
374 } 470 }
375 471
376 } // namespace tracing 472 } // namespace tracing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698