OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/debug/proc_maps_linux.h" | 5 #include "base/debug/proc_maps_linux.h" |
6 #include "base/files/file_path.h" | 6 #include "base/files/file_path.h" |
7 #include "base/path_service.h" | 7 #include "base/path_service.h" |
8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
9 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 9 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
10 #include "base/threading/platform_thread.h" | 10 #include "base/threading/platform_thread.h" |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 | 174 |
175 std::vector<MappedMemoryRegion> regions; | 175 std::vector<MappedMemoryRegion> regions; |
176 EXPECT_TRUE(ParseProcMaps(kTestCases[i].input, ®ions)); | 176 EXPECT_TRUE(ParseProcMaps(kTestCases[i].input, ®ions)); |
177 EXPECT_EQ(1u, regions.size()); | 177 EXPECT_EQ(1u, regions.size()); |
178 if (regions.empty()) | 178 if (regions.empty()) |
179 continue; | 179 continue; |
180 EXPECT_EQ(kTestCases[i].permissions, regions[0].permissions); | 180 EXPECT_EQ(kTestCases[i].permissions, regions[0].permissions); |
181 } | 181 } |
182 } | 182 } |
183 | 183 |
184 TEST(ProcMapsTest, ReadProcMaps) { | 184 #if defined(ADDRESS_SANITIZER) |
185 std::string proc_maps; | 185 // AddressSanitizer may move local variables to a dedicated "fake stack" which |
186 ASSERT_TRUE(ReadProcMaps(&proc_maps)); | 186 // is outside the stack region listed in /proc/self/maps. We disable ASan |
187 | 187 // instrumentation for this function to force the variable to be local. |
188 std::vector<MappedMemoryRegion> regions; | 188 __attribute__((no_sanitize_address)) |
189 ASSERT_TRUE(ParseProcMaps(proc_maps, ®ions)); | 189 #endif |
190 ASSERT_FALSE(regions.empty()); | 190 void CheckProcMapsRegions(const std::vector<MappedMemoryRegion> ®ions) { |
191 | |
192 // We should be able to find both the current executable as well as the stack | 191 // We should be able to find both the current executable as well as the stack |
193 // mapped into memory. Use the address of |proc_maps| as a way of finding the | 192 // mapped into memory. Use the address of |exe_path| as a way of finding the |
194 // stack. | 193 // stack. |
195 FilePath exe_path; | 194 FilePath exe_path; |
196 EXPECT_TRUE(PathService::Get(FILE_EXE, &exe_path)); | 195 EXPECT_TRUE(PathService::Get(FILE_EXE, &exe_path)); |
197 uintptr_t address = reinterpret_cast<uintptr_t>(&proc_maps); | 196 uintptr_t address = reinterpret_cast<uintptr_t>(&exe_path); |
198 bool found_exe = false; | 197 bool found_exe = false; |
199 bool found_stack = false; | 198 bool found_stack = false; |
200 bool found_address = false; | 199 bool found_address = false; |
201 | 200 |
202 for (size_t i = 0; i < regions.size(); ++i) { | 201 for (size_t i = 0; i < regions.size(); ++i) { |
203 if (regions[i].path == exe_path.value()) { | 202 if (regions[i].path == exe_path.value()) { |
204 // It's OK to find the executable mapped multiple times as there'll be | 203 // It's OK to find the executable mapped multiple times as there'll be |
205 // multiple sections (e.g., text, data). | 204 // multiple sections (e.g., text, data). |
206 found_exe = true; | 205 found_exe = true; |
207 } | 206 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 } | 238 } |
240 } | 239 } |
241 | 240 |
242 EXPECT_TRUE(found_exe); | 241 EXPECT_TRUE(found_exe); |
243 if (!RunningOnValgrind()) { | 242 if (!RunningOnValgrind()) { |
244 EXPECT_TRUE(found_stack); | 243 EXPECT_TRUE(found_stack); |
245 EXPECT_TRUE(found_address); | 244 EXPECT_TRUE(found_address); |
246 } | 245 } |
247 } | 246 } |
248 | 247 |
| 248 TEST(ProcMapsTest, ReadProcMaps) { |
| 249 std::string proc_maps; |
| 250 ASSERT_TRUE(ReadProcMaps(&proc_maps)); |
| 251 |
| 252 std::vector<MappedMemoryRegion> regions; |
| 253 ASSERT_TRUE(ParseProcMaps(proc_maps, ®ions)); |
| 254 ASSERT_FALSE(regions.empty()); |
| 255 |
| 256 CheckProcMapsRegions(regions); |
| 257 } |
| 258 |
249 TEST(ProcMapsTest, ReadProcMapsNonEmptyString) { | 259 TEST(ProcMapsTest, ReadProcMapsNonEmptyString) { |
250 std::string old_string("I forgot to clear the string"); | 260 std::string old_string("I forgot to clear the string"); |
251 std::string proc_maps(old_string); | 261 std::string proc_maps(old_string); |
252 ASSERT_TRUE(ReadProcMaps(&proc_maps)); | 262 ASSERT_TRUE(ReadProcMaps(&proc_maps)); |
253 EXPECT_EQ(std::string::npos, proc_maps.find(old_string)); | 263 EXPECT_EQ(std::string::npos, proc_maps.find(old_string)); |
254 } | 264 } |
255 | 265 |
256 TEST(ProcMapsTest, MissingFields) { | 266 TEST(ProcMapsTest, MissingFields) { |
257 static const char* const kTestCases[] = { | 267 static const char* const kTestCases[] = { |
258 "00400000\n", // Missing end + beyond. | 268 "00400000\n", // Missing end + beyond. |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 EXPECT_EQ(5ULL, regions.size()); | 329 EXPECT_EQ(5ULL, regions.size()); |
320 EXPECT_EQ("/bin/cat", regions[0].path); | 330 EXPECT_EQ("/bin/cat", regions[0].path); |
321 EXPECT_EQ("/lib/x86_64-linux-gnu/libc-2.15.so", regions[1].path); | 331 EXPECT_EQ("/lib/x86_64-linux-gnu/libc-2.15.so", regions[1].path); |
322 EXPECT_EQ("/lib/x86_64-linux-gnu/ld-2.15.so", regions[2].path); | 332 EXPECT_EQ("/lib/x86_64-linux-gnu/ld-2.15.so", regions[2].path); |
323 EXPECT_EQ("\"vd so\"", regions[3].path); | 333 EXPECT_EQ("\"vd so\"", regions[3].path); |
324 EXPECT_EQ("[vsys call]", regions[4].path); | 334 EXPECT_EQ("[vsys call]", regions[4].path); |
325 } | 335 } |
326 | 336 |
327 } // namespace debug | 337 } // namespace debug |
328 } // namespace base | 338 } // namespace base |
OLD | NEW |