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

Side by Side Diff: components/tracing/common/process_metrics_memory_dump_provider.cc

Issue 2696923002: Update logic for emitting region information from dyld. (Closed)
Patch Set: 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>
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 264
265 // The public definition for dyld_all_image_infos/dyld_image_info is wrong 265 // The public definition for dyld_all_image_infos/dyld_image_info is wrong
266 // for 64-bit platforms. We explicitly cast to struct mach_header_64 even 266 // for 64-bit platforms. We explicitly cast to struct mach_header_64 even
267 // though the public definition claims that this is a struct mach_header. 267 // though the public definition claims that this is a struct mach_header.
268 const struct mach_header_64* const header = 268 const struct mach_header_64* const header =
269 reinterpret_cast<const struct mach_header_64* const>( 269 reinterpret_cast<const struct mach_header_64* const>(
270 all_image_infos->infoArray[i].imageLoadAddress); 270 all_image_infos->infoArray[i].imageLoadAddress);
271 271
272 uint64_t next_command = reinterpret_cast<uint64_t>(header + 1); 272 uint64_t next_command = reinterpret_cast<uint64_t>(header + 1);
273 uint64_t command_end = next_command + header->sizeofcmds; 273 uint64_t command_end = next_command + header->sizeofcmds;
274 for (unsigned int i = 0; i < header->ncmds; ++i) { 274 uint64_t slide = 0;
275 for (unsigned int j = 0; j < header->ncmds; ++j) {
275 // Ensure that next_command doesn't run past header->sizeofcmds. 276 // Ensure that next_command doesn't run past header->sizeofcmds.
276 if (next_command + sizeof(struct load_command) > command_end) 277 if (next_command + sizeof(struct load_command) > command_end)
277 return false; 278 return false;
278 const struct load_command* load_cmd = 279 const struct load_command* load_cmd =
279 reinterpret_cast<const struct load_command*>(next_command); 280 reinterpret_cast<const struct load_command*>(next_command);
280 next_command += load_cmd->cmdsize; 281 next_command += load_cmd->cmdsize;
281 282
282 if (load_cmd->cmd == LC_SEGMENT_64) { 283 if (load_cmd->cmd == LC_SEGMENT_64) {
283 if (load_cmd->cmdsize < sizeof(segment_command_64)) 284 if (load_cmd->cmdsize < sizeof(segment_command_64))
284 return false; 285 return false;
285 const segment_command_64* seg = 286 const segment_command_64* seg =
286 reinterpret_cast<const segment_command_64*>(load_cmd); 287 reinterpret_cast<const segment_command_64*>(load_cmd);
287 if (strcmp(seg->segname, SEG_PAGEZERO) == 0) 288 if (strcmp(seg->segname, SEG_PAGEZERO) == 0)
288 continue; 289 continue;
290 if (strcmp(seg->segname, SEG_TEXT) == 0) {
291 slide = reinterpret_cast<uint64_t>(header) - seg->vmaddr;
292 }
293
294 // Avoid emitting LINKEDIT regions in the dyld shared cache, since they
Mark Mentovai 2017/02/14 22:18:58 Perhaps just emit it one time, then? Show it as be
erikchen 2017/02/14 22:33:47 Done.
295 // all overlap.
296 if (IsAddressInSharedRegion(seg->vmaddr) &&
297 strcmp(seg->segname, SEG_LINKEDIT) == 0) {
298 continue;
299 }
289 300
290 uint32_t protection_flags = 0; 301 uint32_t protection_flags = 0;
291 if (seg->initprot & VM_PROT_READ) 302 if (seg->initprot & VM_PROT_READ)
292 protection_flags |= VMRegion::kProtectionFlagsRead; 303 protection_flags |= VMRegion::kProtectionFlagsRead;
293 if (seg->initprot & VM_PROT_WRITE) 304 if (seg->initprot & VM_PROT_WRITE)
294 protection_flags |= VMRegion::kProtectionFlagsWrite; 305 protection_flags |= VMRegion::kProtectionFlagsWrite;
295 if (seg->initprot & VM_PROT_EXECUTE) 306 if (seg->initprot & VM_PROT_EXECUTE)
296 protection_flags |= VMRegion::kProtectionFlagsExec; 307 protection_flags |= VMRegion::kProtectionFlagsExec;
297 308
298 VMRegion region; 309 VMRegion region;
299 region.size_in_bytes = seg->vmsize; 310 region.size_in_bytes = seg->vmsize;
300 region.protection_flags = protection_flags; 311 region.protection_flags = protection_flags;
301 region.mapped_file = image_name; 312 region.mapped_file = image_name;
302 region.start_address = 313 region.start_address = slide + seg->vmaddr;
303 reinterpret_cast<uint64_t>(header) + seg->fileoff;
304 314
305 // We intentionally avoid setting any page information, which is not 315 // We intentionally avoid setting any page information, which is not
306 // available from dyld. The fields will be populated later. 316 // available from dyld. The fields will be populated later.
307 regions->push_back(region); 317 regions->push_back(region);
308 } 318 }
309 } 319 }
310 } 320 }
311 return true; 321 return true;
312 } 322 }
313 323
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 std::vector<VMRegion> dyld_regions; 432 std::vector<VMRegion> dyld_regions;
423 if (!GetDyldRegions(&dyld_regions)) 433 if (!GetDyldRegions(&dyld_regions))
424 return false; 434 return false;
425 std::vector<VMRegion> all_regions; 435 std::vector<VMRegion> all_regions;
426 if (!GetAllRegions(&all_regions)) 436 if (!GetAllRegions(&all_regions))
427 return false; 437 return false;
428 438
429 // Cache information from dyld_regions in a data-structure more conducive to 439 // Cache information from dyld_regions in a data-structure more conducive to
430 // fast lookups. 440 // fast lookups.
431 std::unordered_map<uint64_t, VMRegion*> address_to_vm_region; 441 std::unordered_map<uint64_t, VMRegion*> address_to_vm_region;
432 std::vector<uint64_t> addresses_in_shared_region;
433 for (VMRegion& region : dyld_regions) { 442 for (VMRegion& region : dyld_regions) {
434 if (IsAddressInSharedRegion(region.start_address))
435 addresses_in_shared_region.push_back(region.start_address);
436 address_to_vm_region[region.start_address] = &region; 443 address_to_vm_region[region.start_address] = &region;
437 } 444 }
438 445
439 // Merge information from dyld regions and all regions. 446 // Merge information from dyld regions and all regions.
440 for (const VMRegion& region : all_regions) { 447 for (const VMRegion& region : all_regions) {
441 // Check to see if the region already has a VMRegion created from a dyld 448 // Check to see if the region already has a VMRegion created from a dyld
442 // load command. If so, copy the byte stats and move on. 449 // load command. If so, copy the byte stats and move on.
443 auto it = address_to_vm_region.find(region.start_address); 450 auto it = address_to_vm_region.find(region.start_address);
444 if (it != address_to_vm_region.end() && 451 if (it != address_to_vm_region.end() &&
445 it->second->size_in_bytes == region.size_in_bytes) { 452 it->second->size_in_bytes == region.size_in_bytes) {
446 CopyRegionByteStats(it->second, region); 453 CopyRegionByteStats(it->second, region);
447 continue; 454 continue;
448 } 455 }
449 456
450 // Check to see if the region is likely used for the dyld shared cache. 457 // Check to see if the region is likely used for the dyld shared cache.
451 if (IsAddressInSharedRegion(region.start_address)) { 458 if (IsAddressInSharedRegion(region.start_address)) {
452 uint64_t end_address = region.start_address + region.size_in_bytes; 459 uint64_t end_address = region.start_address + region.size_in_bytes;
453 for (uint64_t address : addresses_in_shared_region) { 460 bool skip = false;
461 for (const VMRegion& dyld_region : dyld_regions) {
454 // This region is likely used for the dyld shared cache. Don't record 462 // This region is likely used for the dyld shared cache. Don't record
455 // any byte stats since: 463 // any byte stats since:
456 // 1. It's not possible to figure out which dyld regions the byte 464 // 1. It's not possible to figure out which dyld regions the byte
457 // stats correspond to. 465 // stats correspond to.
458 // 2. The region is likely shared by non-Chrome processes, so there's 466 // 2. The region is likely shared by non-Chrome processes, so there's
459 // no point in charging the pages towards Chrome. 467 // no point in charging the pages towards Chrome.
460 if (address >= region.start_address && address < end_address) { 468 if (dyld_region.start_address >= region.start_address &&
461 continue; 469 dyld_region.start_address < end_address) {
470 skip = true;
471 break;
472 }
473 uint64_t dyld_end_address =
474 dyld_region.start_address + dyld_region.size_in_bytes;
475 if (dyld_end_address >= region.start_address &&
476 dyld_end_address < end_address) {
477 skip = true;
478 break;
462 } 479 }
463 } 480 }
481 if (skip)
482 continue;
464 } 483 }
465 pmd->process_mmaps()->AddVMRegion(region); 484 pmd->process_mmaps()->AddVMRegion(region);
466 } 485 }
467 486
468 for (VMRegion& region : dyld_regions) { 487 for (VMRegion& region : dyld_regions) {
469 pmd->process_mmaps()->AddVMRegion(region); 488 pmd->process_mmaps()->AddVMRegion(region);
470 } 489 }
471 490
472 pmd->set_has_process_mmaps(); 491 pmd->set_has_process_mmaps();
473 return true; 492 return true;
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 #endif 641 #endif
623 } 642 }
624 643
625 void ProcessMetricsMemoryDumpProvider::SuspendFastMemoryPolling() { 644 void ProcessMetricsMemoryDumpProvider::SuspendFastMemoryPolling() {
626 #if defined(OS_LINUX) || defined(OS_ANDROID) 645 #if defined(OS_LINUX) || defined(OS_ANDROID)
627 fast_polling_statm_fd_.reset(); 646 fast_polling_statm_fd_.reset();
628 #endif 647 #endif
629 } 648 }
630 649
631 } // namespace tracing 650 } // namespace tracing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698