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 "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
11 | 12 |
12 namespace base { | 13 namespace base { |
13 namespace debug { | 14 namespace debug { |
14 | 15 |
15 TEST(ProcMapsTest, Empty) { | 16 TEST(ProcMapsTest, Empty) { |
16 std::vector<MappedMemoryRegion> regions; | 17 std::vector<MappedMemoryRegion> regions; |
17 EXPECT_TRUE(ParseProcMaps("", ®ions)); | 18 EXPECT_TRUE(ParseProcMaps("", ®ions)); |
18 EXPECT_EQ(0u, regions.size()); | 19 EXPECT_EQ(0u, regions.size()); |
19 } | 20 } |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 | 191 |
191 // We should be able to find both the current executable as well as the stack | 192 // We should be able to find both the current executable as well as the stack |
192 // mapped into memory. Use the address of |proc_maps| as a way of finding the | 193 // mapped into memory. Use the address of |proc_maps| as a way of finding the |
193 // stack. | 194 // stack. |
194 FilePath exe_path; | 195 FilePath exe_path; |
195 EXPECT_TRUE(PathService::Get(FILE_EXE, &exe_path)); | 196 EXPECT_TRUE(PathService::Get(FILE_EXE, &exe_path)); |
196 uintptr_t address = reinterpret_cast<uintptr_t>(&proc_maps); | 197 uintptr_t address = reinterpret_cast<uintptr_t>(&proc_maps); |
197 bool found_exe = false; | 198 bool found_exe = false; |
198 bool found_stack = false; | 199 bool found_stack = false; |
199 bool found_address = false; | 200 bool found_address = false; |
| 201 |
| 202 // Valgrind uses its own allocated stacks instead of the kernel-provided stack |
| 203 // without letting the kernel know via prctl(PR_SET_MM_START_STACK). This |
| 204 // causes the kernel to use [stack:TID] format. See http://crbug.com/431702 |
| 205 // for details. |
| 206 std::string stack_with_tid = |
| 207 StringPrintf("[stack:%d]", PlatformThread::CurrentId()); |
| 208 |
200 for (size_t i = 0; i < regions.size(); ++i) { | 209 for (size_t i = 0; i < regions.size(); ++i) { |
201 if (regions[i].path == exe_path.value()) { | 210 if (regions[i].path == exe_path.value()) { |
202 // It's OK to find the executable mapped multiple times as there'll be | 211 // It's OK to find the executable mapped multiple times as there'll be |
203 // multiple sections (e.g., text, data). | 212 // multiple sections (e.g., text, data). |
204 found_exe = true; | 213 found_exe = true; |
205 } | 214 } |
206 | 215 |
| 216 bool is_correct_stack = false; |
207 if (regions[i].path == "[stack]") { | 217 if (regions[i].path == "[stack]") { |
208 // Only check if |address| lies within the real stack when not running | 218 is_correct_stack = true; |
209 // Valgrind, otherwise |address| will be on a stack that Valgrind creates. | 219 EXPECT_FALSE(RunningOnValgrind()); |
210 if (!RunningOnValgrind()) { | 220 EXPECT_GE(address, regions[i].start); |
211 EXPECT_GE(address, regions[i].start); | 221 EXPECT_LT(address, regions[i].end); |
212 EXPECT_LT(address, regions[i].end); | 222 } else if (regions[i].path == stack_with_tid) { |
213 } | 223 is_correct_stack = true; |
| 224 EXPECT_TRUE(RunningOnValgrind()); |
| 225 } |
214 | 226 |
| 227 if (is_correct_stack) { |
| 228 // Note that the stack is executable when it is created by Valgrind. |
215 EXPECT_TRUE(regions[i].permissions & MappedMemoryRegion::READ); | 229 EXPECT_TRUE(regions[i].permissions & MappedMemoryRegion::READ); |
216 EXPECT_TRUE(regions[i].permissions & MappedMemoryRegion::WRITE); | 230 EXPECT_TRUE(regions[i].permissions & MappedMemoryRegion::WRITE); |
217 EXPECT_FALSE(regions[i].permissions & MappedMemoryRegion::EXECUTE); | 231 EXPECT_EQ(RunningOnValgrind(), |
| 232 (regions[i].permissions & MappedMemoryRegion::EXECUTE) != 0); |
218 EXPECT_TRUE(regions[i].permissions & MappedMemoryRegion::PRIVATE); | 233 EXPECT_TRUE(regions[i].permissions & MappedMemoryRegion::PRIVATE); |
219 EXPECT_FALSE(found_stack) << "Found duplicate stacks"; | 234 EXPECT_FALSE(found_stack) << "Found duplicate stacks"; |
220 found_stack = true; | 235 found_stack = true; |
221 } | 236 } |
222 | 237 |
223 if (address >= regions[i].start && address < regions[i].end) { | 238 if (address >= regions[i].start && address < regions[i].end) { |
224 EXPECT_FALSE(found_address) << "Found same address in multiple regions"; | 239 EXPECT_FALSE(found_address) << "Found same address in multiple regions"; |
225 found_address = true; | 240 found_address = true; |
226 } | 241 } |
227 } | 242 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 EXPECT_EQ(5ULL, regions.size()); | 319 EXPECT_EQ(5ULL, regions.size()); |
305 EXPECT_EQ("/bin/cat", regions[0].path); | 320 EXPECT_EQ("/bin/cat", regions[0].path); |
306 EXPECT_EQ("/lib/x86_64-linux-gnu/libc-2.15.so", regions[1].path); | 321 EXPECT_EQ("/lib/x86_64-linux-gnu/libc-2.15.so", regions[1].path); |
307 EXPECT_EQ("/lib/x86_64-linux-gnu/ld-2.15.so", regions[2].path); | 322 EXPECT_EQ("/lib/x86_64-linux-gnu/ld-2.15.so", regions[2].path); |
308 EXPECT_EQ("\"vd so\"", regions[3].path); | 323 EXPECT_EQ("\"vd so\"", regions[3].path); |
309 EXPECT_EQ("[vsys call]", regions[4].path); | 324 EXPECT_EQ("[vsys call]", regions[4].path); |
310 } | 325 } |
311 | 326 |
312 } // namespace debug | 327 } // namespace debug |
313 } // namespace base | 328 } // namespace base |
OLD | NEW |