| 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 |