OLD | NEW |
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 "base/trace_event/process_memory_maps_dump_provider.h" | 5 #include "base/trace_event/process_memory_maps_dump_provider.h" |
6 | 6 |
7 #include <cctype> | 7 #include <cctype> |
8 #include <fstream> | 8 #include <fstream> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/process/process_metrics.h" | 11 #include "base/process/process_metrics.h" |
12 #include "base/trace_event/process_memory_dump.h" | 12 #include "base/trace_event/process_memory_dump.h" |
13 #include "base/trace_event/process_memory_maps.h" | 13 #include "base/trace_event/process_memory_maps.h" |
14 | 14 |
15 namespace base { | 15 namespace base { |
16 namespace trace_event { | 16 namespace trace_event { |
17 | 17 |
| 18 namespace { |
| 19 const char kDumperFriendlyName[] = "ProcessMemoryMaps"; |
| 20 } |
| 21 |
18 #if defined(OS_LINUX) || defined(OS_ANDROID) | 22 #if defined(OS_LINUX) || defined(OS_ANDROID) |
19 // static | 23 // static |
20 std::istream* ProcessMemoryMapsDumpProvider::proc_smaps_for_testing = nullptr; | 24 std::istream* ProcessMemoryMapsDumpProvider::proc_smaps_for_testing = nullptr; |
21 | 25 |
22 namespace { | 26 namespace { |
23 | 27 |
24 const uint32 kMaxLineSize = 4096; | 28 const uint32 kMaxLineSize = 4096; |
25 | 29 |
26 bool ParseSmapsHeader(std::istream* smaps, | 30 bool ParseSmapsHeader(std::istream* smaps, |
27 ProcessMemoryMaps::VMRegion* region) { | 31 ProcessMemoryMaps::VMRegion* region) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 DCHECK_EQ("kB", unit); | 101 DCHECK_EQ("kB", unit); |
98 } | 102 } |
99 #endif | 103 #endif |
100 | 104 |
101 smaps->ignore(kMaxLineSize, '\n'); | 105 smaps->ignore(kMaxLineSize, '\n'); |
102 | 106 |
103 return res; | 107 return res; |
104 } | 108 } |
105 | 109 |
106 uint32 ReadLinuxProcSmapsFile(std::istream* smaps, ProcessMemoryMaps* pmm) { | 110 uint32 ReadLinuxProcSmapsFile(std::istream* smaps, ProcessMemoryMaps* pmm) { |
107 if (!smaps->good()) { | 111 if (!smaps->good()) |
108 LOG(ERROR) << "Could not read smaps file."; | |
109 return 0; | 112 return 0; |
110 } | 113 |
111 const uint32 kNumExpectedCountersPerRegion = 2; | 114 const uint32 kNumExpectedCountersPerRegion = 2; |
112 uint32 counters_parsed_for_current_region = 0; | 115 uint32 counters_parsed_for_current_region = 0; |
113 uint32 num_valid_regions = 0; | 116 uint32 num_valid_regions = 0; |
114 ProcessMemoryMaps::VMRegion region; | 117 ProcessMemoryMaps::VMRegion region; |
115 bool should_add_current_region = false; | 118 bool should_add_current_region = false; |
116 for (;;) { | 119 for (;;) { |
117 int next = smaps->peek(); | 120 int next = smaps->peek(); |
118 if (next == std::ifstream::traits_type::eof() || next == '\n') | 121 if (next == std::ifstream::traits_type::eof() || next == '\n') |
119 break; | 122 break; |
120 if (isxdigit(next) && !isupper(next)) { | 123 if (isxdigit(next) && !isupper(next)) { |
(...skipping 26 matching lines...) Expand all Loading... |
147 } | 150 } |
148 | 151 |
149 ProcessMemoryMapsDumpProvider::ProcessMemoryMapsDumpProvider() { | 152 ProcessMemoryMapsDumpProvider::ProcessMemoryMapsDumpProvider() { |
150 } | 153 } |
151 | 154 |
152 ProcessMemoryMapsDumpProvider::~ProcessMemoryMapsDumpProvider() { | 155 ProcessMemoryMapsDumpProvider::~ProcessMemoryMapsDumpProvider() { |
153 } | 156 } |
154 | 157 |
155 // Called at trace dump point time. Creates a snapshot the memory maps for the | 158 // Called at trace dump point time. Creates a snapshot the memory maps for the |
156 // current process. | 159 // current process. |
157 void ProcessMemoryMapsDumpProvider::DumpInto(ProcessMemoryDump* pmd) { | 160 bool ProcessMemoryMapsDumpProvider::DumpInto(ProcessMemoryDump* pmd) { |
158 uint32 res = 0; | 161 uint32 res = 0; |
159 | 162 |
160 #if defined(OS_LINUX) || defined(OS_ANDROID) | 163 #if defined(OS_LINUX) || defined(OS_ANDROID) |
161 if (UNLIKELY(proc_smaps_for_testing)) { | 164 if (UNLIKELY(proc_smaps_for_testing)) { |
162 res = ReadLinuxProcSmapsFile(proc_smaps_for_testing, pmd->process_mmaps()); | 165 res = ReadLinuxProcSmapsFile(proc_smaps_for_testing, pmd->process_mmaps()); |
163 } else { | 166 } else { |
164 std::ifstream proc_self_smaps("/proc/self/smaps"); | 167 std::ifstream proc_self_smaps("/proc/self/smaps"); |
165 res = ReadLinuxProcSmapsFile(&proc_self_smaps, pmd->process_mmaps()); | 168 res = ReadLinuxProcSmapsFile(&proc_self_smaps, pmd->process_mmaps()); |
166 } | 169 } |
167 #else | 170 #else |
168 LOG(ERROR) << "ProcessMemoryMaps dump provider is supported only on Linux"; | 171 LOG(ERROR) << "ProcessMemoryMaps dump provider is supported only on Linux"; |
169 #endif | 172 #endif |
170 | 173 |
171 if (res > 0) | 174 if (res > 0) { |
172 pmd->set_has_process_mmaps(); | 175 pmd->set_has_process_mmaps(); |
| 176 return true; |
| 177 } |
| 178 |
| 179 return false; |
| 180 } |
| 181 |
| 182 const char* ProcessMemoryMapsDumpProvider::GetFriendlyName() const { |
| 183 return kDumperFriendlyName; |
173 } | 184 } |
174 | 185 |
175 } // namespace trace_event | 186 } // namespace trace_event |
176 } // namespace base | 187 } // namespace base |
OLD | NEW |