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 "components/tracing/common/process_metrics_memory_dump_provider.h" | 5 #include "components/tracing/common/process_metrics_memory_dump_provider.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 | 10 |
11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
| 12 #include "base/memory/ptr_util.h" |
| 13 #include "base/process/process_metrics.h" |
12 #include "base/trace_event/process_memory_dump.h" | 14 #include "base/trace_event/process_memory_dump.h" |
13 #include "base/trace_event/process_memory_maps.h" | 15 #include "base/trace_event/process_memory_maps.h" |
14 #include "base/trace_event/process_memory_totals.h" | 16 #include "base/trace_event/process_memory_totals.h" |
15 #include "base/trace_event/trace_event_argument.h" | 17 #include "base/trace_event/trace_event_argument.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
17 | 19 |
18 namespace tracing { | 20 namespace tracing { |
19 | 21 |
20 #if defined(OS_LINUX) || defined(OS_ANDROID) | 22 #if defined(OS_LINUX) || defined(OS_ANDROID) |
21 namespace { | 23 namespace { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 "Private_Dirty: 4 kB\n" | 102 "Private_Dirty: 4 kB\n" |
101 "Referenced: 40 kB\n" | 103 "Referenced: 40 kB\n" |
102 "Anonymous: 16 kB\n" | 104 "Anonymous: 16 kB\n" |
103 "AnonHugePages: 0 kB\n" | 105 "AnonHugePages: 0 kB\n" |
104 "Swap: 0 kB\n" | 106 "Swap: 0 kB\n" |
105 "KernelPageSize: 4 kB\n" | 107 "KernelPageSize: 4 kB\n" |
106 "MMUPageSize: 4 kB\n" | 108 "MMUPageSize: 4 kB\n" |
107 "Locked: 0 kB\n" | 109 "Locked: 0 kB\n" |
108 "VmFlags: rd wr mr mw me ac sd\n"; | 110 "VmFlags: rd wr mr mw me ac sd\n"; |
109 | 111 |
110 void CreateAndSetSmapsFileForTesting(const char* smaps_string, | 112 const char kTestStatm[] = "200 100 20 2 3 4"; |
111 base::ScopedFILE& file) { | 113 |
| 114 void CreateTempFileWithContents(const char* contents, base::ScopedFILE* file) { |
112 base::FilePath temp_path; | 115 base::FilePath temp_path; |
113 FILE* temp_file = CreateAndOpenTemporaryFile(&temp_path); | 116 FILE* temp_file = CreateAndOpenTemporaryFile(&temp_path); |
114 file.reset(temp_file); | 117 file->reset(temp_file); |
115 ASSERT_TRUE(temp_file); | 118 ASSERT_TRUE(temp_file); |
116 | 119 |
117 ASSERT_TRUE(base::WriteFileDescriptor(fileno(temp_file), smaps_string, | 120 ASSERT_TRUE( |
118 strlen(smaps_string))); | 121 base::WriteFileDescriptor(fileno(temp_file), contents, strlen(contents))); |
119 } | 122 } |
120 | 123 |
121 } // namespace | 124 } // namespace |
122 #endif // defined(OS_LINUX) || defined(OS_ANDROID) | 125 #endif // defined(OS_LINUX) || defined(OS_ANDROID) |
123 | 126 |
124 TEST(ProcessMetricsMemoryDumpProviderTest, DumpRSS) { | 127 TEST(ProcessMetricsMemoryDumpProviderTest, DumpRSS) { |
125 const base::trace_event::MemoryDumpArgs high_detail_args = { | 128 const base::trace_event::MemoryDumpArgs high_detail_args = { |
126 base::trace_event::MemoryDumpLevelOfDetail::DETAILED}; | 129 base::trace_event::MemoryDumpLevelOfDetail::DETAILED}; |
127 std::unique_ptr<ProcessMetricsMemoryDumpProvider> pmtdp( | 130 std::unique_ptr<ProcessMetricsMemoryDumpProvider> pmtdp( |
128 new ProcessMetricsMemoryDumpProvider(base::kNullProcessId)); | 131 new ProcessMetricsMemoryDumpProvider(base::kNullProcessId)); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 base::ScopedFILE empty_file(OpenFile(base::FilePath("/dev/null"), "r")); | 178 base::ScopedFILE empty_file(OpenFile(base::FilePath("/dev/null"), "r")); |
176 ASSERT_TRUE(empty_file.get()); | 179 ASSERT_TRUE(empty_file.get()); |
177 ProcessMetricsMemoryDumpProvider::proc_smaps_for_testing = empty_file.get(); | 180 ProcessMetricsMemoryDumpProvider::proc_smaps_for_testing = empty_file.get(); |
178 pmmdp->OnMemoryDump(dump_args, &pmd_invalid); | 181 pmmdp->OnMemoryDump(dump_args, &pmd_invalid); |
179 ASSERT_FALSE(pmd_invalid.has_process_mmaps()); | 182 ASSERT_FALSE(pmd_invalid.has_process_mmaps()); |
180 | 183 |
181 // Parse the 1st smaps file. | 184 // Parse the 1st smaps file. |
182 base::trace_event::ProcessMemoryDump pmd_1(nullptr /* session_state */, | 185 base::trace_event::ProcessMemoryDump pmd_1(nullptr /* session_state */, |
183 dump_args); | 186 dump_args); |
184 base::ScopedFILE temp_file1; | 187 base::ScopedFILE temp_file1; |
185 CreateAndSetSmapsFileForTesting(kTestSmaps1, temp_file1); | 188 CreateTempFileWithContents(kTestSmaps1, &temp_file1); |
186 ProcessMetricsMemoryDumpProvider::proc_smaps_for_testing = temp_file1.get(); | 189 ProcessMetricsMemoryDumpProvider::proc_smaps_for_testing = temp_file1.get(); |
187 pmmdp->OnMemoryDump(dump_args, &pmd_1); | 190 pmmdp->OnMemoryDump(dump_args, &pmd_1); |
188 ASSERT_TRUE(pmd_1.has_process_mmaps()); | 191 ASSERT_TRUE(pmd_1.has_process_mmaps()); |
189 const auto& regions_1 = pmd_1.process_mmaps()->vm_regions(); | 192 const auto& regions_1 = pmd_1.process_mmaps()->vm_regions(); |
190 ASSERT_EQ(2UL, regions_1.size()); | 193 ASSERT_EQ(2UL, regions_1.size()); |
191 | 194 |
192 EXPECT_EQ(0x00400000UL, regions_1[0].start_address); | 195 EXPECT_EQ(0x00400000UL, regions_1[0].start_address); |
193 EXPECT_EQ(0x004be000UL - 0x00400000UL, regions_1[0].size_in_bytes); | 196 EXPECT_EQ(0x004be000UL - 0x00400000UL, regions_1[0].size_in_bytes); |
194 EXPECT_EQ(kProtR | kProtX, regions_1[0].protection_flags); | 197 EXPECT_EQ(kProtR | kProtX, regions_1[0].protection_flags); |
195 EXPECT_EQ("/file/1", regions_1[0].mapped_file); | 198 EXPECT_EQ("/file/1", regions_1[0].mapped_file); |
(...skipping 12 matching lines...) Expand all Loading... |
208 EXPECT_EQ(120 * 1024UL, regions_1[1].byte_stats_shared_clean_resident); | 211 EXPECT_EQ(120 * 1024UL, regions_1[1].byte_stats_shared_clean_resident); |
209 EXPECT_EQ(4 * 1024UL, regions_1[1].byte_stats_shared_dirty_resident); | 212 EXPECT_EQ(4 * 1024UL, regions_1[1].byte_stats_shared_dirty_resident); |
210 EXPECT_EQ(60 * 1024UL, regions_1[1].byte_stats_private_clean_resident); | 213 EXPECT_EQ(60 * 1024UL, regions_1[1].byte_stats_private_clean_resident); |
211 EXPECT_EQ(8 * 1024UL, regions_1[1].byte_stats_private_dirty_resident); | 214 EXPECT_EQ(8 * 1024UL, regions_1[1].byte_stats_private_dirty_resident); |
212 EXPECT_EQ(0 * 1024UL, regions_1[1].byte_stats_swapped); | 215 EXPECT_EQ(0 * 1024UL, regions_1[1].byte_stats_swapped); |
213 | 216 |
214 // Parse the 2nd smaps file. | 217 // Parse the 2nd smaps file. |
215 base::trace_event::ProcessMemoryDump pmd_2(nullptr /* session_state */, | 218 base::trace_event::ProcessMemoryDump pmd_2(nullptr /* session_state */, |
216 dump_args); | 219 dump_args); |
217 base::ScopedFILE temp_file2; | 220 base::ScopedFILE temp_file2; |
218 CreateAndSetSmapsFileForTesting(kTestSmaps2, temp_file2); | 221 CreateTempFileWithContents(kTestSmaps2, &temp_file2); |
219 ProcessMetricsMemoryDumpProvider::proc_smaps_for_testing = temp_file2.get(); | 222 ProcessMetricsMemoryDumpProvider::proc_smaps_for_testing = temp_file2.get(); |
220 pmmdp->OnMemoryDump(dump_args, &pmd_2); | 223 pmmdp->OnMemoryDump(dump_args, &pmd_2); |
221 ASSERT_TRUE(pmd_2.has_process_mmaps()); | 224 ASSERT_TRUE(pmd_2.has_process_mmaps()); |
222 const auto& regions_2 = pmd_2.process_mmaps()->vm_regions(); | 225 const auto& regions_2 = pmd_2.process_mmaps()->vm_regions(); |
223 ASSERT_EQ(1UL, regions_2.size()); | 226 ASSERT_EQ(1UL, regions_2.size()); |
224 EXPECT_EQ(0x7fe7ce79c000UL, regions_2[0].start_address); | 227 EXPECT_EQ(0x7fe7ce79c000UL, regions_2[0].start_address); |
225 EXPECT_EQ(0x7fe7ce7a8000UL - 0x7fe7ce79c000UL, regions_2[0].size_in_bytes); | 228 EXPECT_EQ(0x7fe7ce7a8000UL - 0x7fe7ce79c000UL, regions_2[0].size_in_bytes); |
226 EXPECT_EQ(0U, regions_2[0].protection_flags); | 229 EXPECT_EQ(0U, regions_2[0].protection_flags); |
227 EXPECT_EQ("", regions_2[0].mapped_file); | 230 EXPECT_EQ("", regions_2[0].mapped_file); |
228 EXPECT_EQ(32 * 1024UL, regions_2[0].byte_stats_proportional_resident); | 231 EXPECT_EQ(32 * 1024UL, regions_2[0].byte_stats_proportional_resident); |
229 EXPECT_EQ(16 * 1024UL, regions_2[0].byte_stats_shared_clean_resident); | 232 EXPECT_EQ(16 * 1024UL, regions_2[0].byte_stats_shared_clean_resident); |
230 EXPECT_EQ(12 * 1024UL, regions_2[0].byte_stats_shared_dirty_resident); | 233 EXPECT_EQ(12 * 1024UL, regions_2[0].byte_stats_shared_dirty_resident); |
231 EXPECT_EQ(8 * 1024UL, regions_2[0].byte_stats_private_clean_resident); | 234 EXPECT_EQ(8 * 1024UL, regions_2[0].byte_stats_private_clean_resident); |
232 EXPECT_EQ(4 * 1024UL, regions_2[0].byte_stats_private_dirty_resident); | 235 EXPECT_EQ(4 * 1024UL, regions_2[0].byte_stats_private_dirty_resident); |
233 EXPECT_EQ(0 * 1024UL, regions_2[0].byte_stats_swapped); | 236 EXPECT_EQ(0 * 1024UL, regions_2[0].byte_stats_swapped); |
234 } | 237 } |
235 #endif // defined(OS_LINUX) || defined(OS_ANDROID) | 238 #endif // defined(OS_LINUX) || defined(OS_ANDROID) |
236 | 239 |
| 240 TEST(ProcessMetricsMemoryDumpProviderTest, TestPollFastMemoryTotal) { |
| 241 ProcessMetricsMemoryDumpProvider mdp(base::kNullProcessId); |
| 242 |
| 243 uint64_t total1, total2; |
| 244 mdp.PollFastMemoryTotal(&total1); |
| 245 ASSERT_GT(total1, 0u); |
| 246 size_t kBufSize = 16 * 1024 * 1024; |
| 247 auto buf = base::MakeUnique<char[]>(kBufSize); |
| 248 for (size_t i = 0; i < kBufSize; i++) |
| 249 buf[i] = *((volatile char*)&buf[i]) + 1; |
| 250 mdp.PollFastMemoryTotal(&total2); |
| 251 ASSERT_GT(total2, 0u); |
| 252 EXPECT_GT(total2, total1 + kBufSize / 2); |
| 253 |
| 254 #if defined(OS_LINUX) || defined(OS_ANDROID) |
| 255 EXPECT_GE(mdp.fast_polling_statm_fd_.get(), 0); |
| 256 |
| 257 base::ScopedFILE temp_file; |
| 258 CreateTempFileWithContents(kTestStatm, &temp_file); |
| 259 mdp.fast_polling_statm_fd_for_testing = fileno(temp_file.get()); |
| 260 size_t page_size = base::GetPageSize(); |
| 261 uint64_t value; |
| 262 mdp.PollFastMemoryTotal(&value); |
| 263 EXPECT_EQ(100 * page_size, value); |
| 264 |
| 265 mdp.SuspendFastMemoryPolling(); |
| 266 EXPECT_FALSE(mdp.fast_polling_statm_fd_.is_valid()); |
| 267 #else |
| 268 mdp.SuspendFastMemoryPolling(); |
| 269 #endif |
| 270 } |
| 271 |
237 } // namespace tracing | 272 } // namespace tracing |
OLD | NEW |