Chromium Code Reviews| 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 ccac246654069fb66a624e55b5816d28de403ec9..1406689fcac30de729d6407381b459228fa72b6a 100644 |
| --- a/components/tracing/common/process_metrics_memory_dump_provider.cc |
| +++ b/components/tracing/common/process_metrics_memory_dump_provider.cc |
| @@ -271,7 +271,8 @@ bool GetDyldRegions(std::vector<VMRegion>* regions) { |
| uint64_t next_command = reinterpret_cast<uint64_t>(header + 1); |
| uint64_t command_end = next_command + header->sizeofcmds; |
| - for (unsigned int i = 0; i < header->ncmds; ++i) { |
| + uint64_t slide = 0; |
| + for (unsigned int j = 0; j < header->ncmds; ++j) { |
| // Ensure that next_command doesn't run past header->sizeofcmds. |
| if (next_command + sizeof(struct load_command) > command_end) |
| return false; |
| @@ -286,6 +287,16 @@ bool GetDyldRegions(std::vector<VMRegion>* regions) { |
| reinterpret_cast<const segment_command_64*>(load_cmd); |
| if (strcmp(seg->segname, SEG_PAGEZERO) == 0) |
| continue; |
| + if (strcmp(seg->segname, SEG_TEXT) == 0) { |
| + slide = reinterpret_cast<uint64_t>(header) - seg->vmaddr; |
| + } |
| + |
| + // 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.
|
| + // all overlap. |
| + if (IsAddressInSharedRegion(seg->vmaddr) && |
| + strcmp(seg->segname, SEG_LINKEDIT) == 0) { |
| + continue; |
| + } |
| uint32_t protection_flags = 0; |
| if (seg->initprot & VM_PROT_READ) |
| @@ -299,8 +310,7 @@ bool GetDyldRegions(std::vector<VMRegion>* regions) { |
| region.size_in_bytes = seg->vmsize; |
| region.protection_flags = protection_flags; |
| region.mapped_file = image_name; |
| - region.start_address = |
| - reinterpret_cast<uint64_t>(header) + seg->fileoff; |
| + region.start_address = slide + seg->vmaddr; |
| // We intentionally avoid setting any page information, which is not |
| // available from dyld. The fields will be populated later. |
| @@ -429,10 +439,7 @@ bool ProcessMetricsMemoryDumpProvider::DumpProcessMemoryMaps( |
| // Cache information from dyld_regions in a data-structure more conducive to |
| // fast lookups. |
| std::unordered_map<uint64_t, VMRegion*> address_to_vm_region; |
| - std::vector<uint64_t> addresses_in_shared_region; |
| for (VMRegion& region : dyld_regions) { |
| - if (IsAddressInSharedRegion(region.start_address)) |
| - addresses_in_shared_region.push_back(region.start_address); |
| address_to_vm_region[region.start_address] = ®ion; |
| } |
| @@ -450,17 +457,29 @@ bool ProcessMetricsMemoryDumpProvider::DumpProcessMemoryMaps( |
| // Check to see if the region is likely used for the dyld shared cache. |
| if (IsAddressInSharedRegion(region.start_address)) { |
| uint64_t end_address = region.start_address + region.size_in_bytes; |
| - for (uint64_t address : addresses_in_shared_region) { |
| + bool skip = false; |
| + for (const VMRegion& dyld_region : dyld_regions) { |
| // This region is likely used for the dyld shared cache. Don't record |
| // any byte stats since: |
| // 1. It's not possible to figure out which dyld regions the byte |
| // stats correspond to. |
| // 2. The region is likely shared by non-Chrome processes, so there's |
| // no point in charging the pages towards Chrome. |
| - if (address >= region.start_address && address < end_address) { |
| - continue; |
| + if (dyld_region.start_address >= region.start_address && |
| + dyld_region.start_address < end_address) { |
| + skip = true; |
| + break; |
| + } |
| + uint64_t dyld_end_address = |
| + dyld_region.start_address + dyld_region.size_in_bytes; |
| + if (dyld_end_address >= region.start_address && |
| + dyld_end_address < end_address) { |
| + skip = true; |
| + break; |
| } |
| } |
| + if (skip) |
| + continue; |
| } |
| pmd->process_mmaps()->AddVMRegion(region); |
| } |