1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file. 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/debug/proc_maps_linux.h" 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/files/file_path.h" 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/path_service.h" 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/stringprintf.h" 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/third_party/dynamic_annotations/dynamic_annotations.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "testing/gtest/include/gtest/gtest.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace base { 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace debug { 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST(ProcMapsTest, Empty) { 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MappedMemoryRegion> regions; 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(ParseProcMaps("", ®ions)); 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, regions.size()); 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST(ProcMapsTest, NoSpaces) { 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const char kNoSpaces[] = 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 r-xp 00002200 fc:00 794418 /bin/cat\n"; 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MappedMemoryRegion> regions; 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(ParseProcMaps(kNoSpaces, ®ions)); 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(1u, regions.size()); 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x00400000u, regions[0].start); 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x0040b000u, regions[0].end); 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x00002200u, regions[0].offset); 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("/bin/cat", regions[0].path); 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST(ProcMapsTest, Spaces) { 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const char kSpaces[] = 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 r-xp 00002200 fc:00 794418 /bin/space cat\n"; 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MappedMemoryRegion> regions; 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(ParseProcMaps(kSpaces, ®ions)); 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(1u, regions.size()); 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x00400000u, regions[0].start); 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x0040b000u, regions[0].end); 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x00002200u, regions[0].offset); 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("/bin/space cat", regions[0].path); 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST(ProcMapsTest, NoNewline) { 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const char kNoSpaces[] = 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 r-xp 00002200 fc:00 794418 /bin/cat"; 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MappedMemoryRegion> regions; 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_FALSE(ParseProcMaps(kNoSpaces, ®ions)); 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST(ProcMapsTest, NoPath) { 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const char kNoPath[] = 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 rw-p 00000000 00:00 0 \n"; 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MappedMemoryRegion> regions; 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(ParseProcMaps(kNoPath, ®ions)); 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(1u, regions.size()); 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x00400000u, regions[0].start); 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x0040b000u, regions[0].end); 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x00000000u, regions[0].offset); 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("", regions[0].path); 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST(ProcMapsTest, Heap) { 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const char kHeap[] = 73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "022ac000-022cd000 rw-p 00000000 00:00 0 [heap]\n"; 74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MappedMemoryRegion> regions; 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(ParseProcMaps(kHeap, ®ions)); 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(1u, regions.size()); 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x022ac000u, regions[0].start); 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x022cd000u, regions[0].end); 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x00000000u, regions[0].offset); 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("[heap]", regions[0].path); 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(ARCH_CPU_32_BITS) 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST(ProcMapsTest, Stack32) { 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const char kStack[] = 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "beb04000-beb25000 rw-p 00000000 00:00 0 [stack]\n"; 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MappedMemoryRegion> regions; 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(ParseProcMaps(kStack, ®ions)); 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(1u, regions.size()); 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0xbeb04000u, regions[0].start); 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0xbeb25000u, regions[0].end); 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x00000000u, regions[0].offset); 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("[stack]", regions[0].path); 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#elif defined(ARCH_CPU_64_BITS) 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST(ProcMapsTest, Stack64) { 101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const char kStack[] = 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "7fff69c5b000-7fff69c7d000 rw-p 00000000 00:00 0 [stack]\n"; 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MappedMemoryRegion> regions; 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(ParseProcMaps(kStack, ®ions)); 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(1u, regions.size()); 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x7fff69c5b000u, regions[0].start); 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x7fff69c7d000u, regions[0].end); 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x00000000u, regions[0].offset); 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("[stack]", regions[0].path); 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST(ProcMapsTest, Multiple) { 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const char kMultiple[] = 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 r-xp 00000000 fc:00 794418 /bin/cat\n" 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "0060a000-0060b000 r--p 0000a000 fc:00 794418 /bin/cat\n" 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "0060b000-0060c000 rw-p 0000b000 fc:00 794418 /bin/cat\n"; 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MappedMemoryRegion> regions; 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(ParseProcMaps(kMultiple, ®ions)); 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(3u, regions.size()); 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x00400000u, regions[0].start); 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x0040b000u, regions[0].end); 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x00000000u, regions[0].offset); 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("/bin/cat", regions[0].path); 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x0060a000u, regions[1].start); 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x0060b000u, regions[1].end); 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x0000a000u, regions[1].offset); 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("/bin/cat", regions[1].path); 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x0060b000u, regions[2].start); 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x0060c000u, regions[2].end); 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0x0000b000u, regions[2].offset); 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("/bin/cat", regions[2].path); 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST(ProcMapsTest, Permissions) { 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static struct { 143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char* input; 144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint8 permissions; 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } kTestCases[] = { 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch {"00400000-0040b000 ---s 00000000 fc:00 794418 /bin/cat\n", 0}, 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch {"00400000-0040b000 ---S 00000000 fc:00 794418 /bin/cat\n", 0}, 148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch {"00400000-0040b000 r--s 00000000 fc:00 794418 /bin/cat\n", 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MappedMemoryRegion::READ}, 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch {"00400000-0040b000 -w-s 00000000 fc:00 794418 /bin/cat\n", 151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MappedMemoryRegion::WRITE}, 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch {"00400000-0040b000 --xs 00000000 fc:00 794418 /bin/cat\n", 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MappedMemoryRegion::EXECUTE}, 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch {"00400000-0040b000 rwxs 00000000 fc:00 794418 /bin/cat\n", 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MappedMemoryRegion::READ | MappedMemoryRegion::WRITE | 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MappedMemoryRegion::EXECUTE}, 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch {"00400000-0040b000 ---p 00000000 fc:00 794418 /bin/cat\n", 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MappedMemoryRegion::PRIVATE}, 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch {"00400000-0040b000 r--p 00000000 fc:00 794418 /bin/cat\n", 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MappedMemoryRegion::READ | MappedMemoryRegion::PRIVATE}, 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch {"00400000-0040b000 -w-p 00000000 fc:00 794418 /bin/cat\n", 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MappedMemoryRegion::WRITE | MappedMemoryRegion::PRIVATE}, 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch {"00400000-0040b000 --xp 00000000 fc:00 794418 /bin/cat\n", 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MappedMemoryRegion::EXECUTE | MappedMemoryRegion::PRIVATE}, 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch {"00400000-0040b000 rwxp 00000000 fc:00 794418 /bin/cat\n", 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MappedMemoryRegion::READ | MappedMemoryRegion::WRITE | 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MappedMemoryRegion::EXECUTE | MappedMemoryRegion::PRIVATE}, 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SCOPED_TRACE( 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::StringPrintf("kTestCases[%zu] = %s", i, kTestCases[i].input)); 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MappedMemoryRegion> regions; 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(ParseProcMaps(kTestCases[i].input, ®ions)); 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1u, regions.size()); 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (regions.empty()) 178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch continue; 179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kTestCases[i].permissions, regions[0].permissions); 180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST(ProcMapsTest, ReadProcMaps) { 184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string proc_maps; 185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(ReadProcMaps(&proc_maps)); 186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MappedMemoryRegion> regions; 188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(ParseProcMaps(proc_maps, ®ions)); 189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_FALSE(regions.empty()); 190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // We should be able to find both the current executable as well as the stack 192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // mapped into memory. Use the address of |proc_maps| as a way of finding the 193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // stack. 194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FilePath exe_path; 195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(PathService::Get(FILE_EXE, &exe_path)); 196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uintptr_t address = reinterpret_cast<uintptr_t>(&proc_maps); 197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool found_exe = false; 198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool found_stack = false; 1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool found_address = false; 200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < regions.size(); ++i) { 201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (regions[i].path == exe_path.value()) { 2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // It's OK to find the executable mapped multiple times as there'll be 2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // multiple sections (e.g., text, data). 204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch found_exe = true; 205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (regions[i].path == "[stack]") { 2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Only check if |address| lies within the real stack when not running 2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Valgrind, otherwise |address| will be on a stack that Valgrind creates. 2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!RunningOnValgrind()) { 2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_GE(address, regions[i].start); 2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_LT(address, regions[i].end); 2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(regions[i].permissions & MappedMemoryRegion::READ); 216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(regions[i].permissions & MappedMemoryRegion::WRITE); 217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(regions[i].permissions & MappedMemoryRegion::EXECUTE); 218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(regions[i].permissions & MappedMemoryRegion::PRIVATE); 219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(found_stack) << "Found duplicate stacks"; 220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch found_stack = true; 221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (address >= regions[i].start && address < regions[i].end) { 2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(found_address) << "Found same address in multiple regions"; 2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch found_address = true; 2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(found_exe); 230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(found_stack); 2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(found_address); 232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST(ProcMapsTest, ReadProcMapsNonEmptyString) { 23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string old_string("I forgot to clear the string"); 23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string proc_maps(old_string); 23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(ReadProcMaps(&proc_maps)); 23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(std::string::npos, proc_maps.find(old_string)); 23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 24058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST(ProcMapsTest, MissingFields) { 242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const char* kTestCases[] = { 243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000\n", // Missing end + beyond. 244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000\n", // Missing perms + beyond. 245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 r-xp\n", // Missing offset + beyond. 246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 r-xp 00000000\n", // Missing device + beyond. 247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 r-xp 00000000 fc:00\n", // Missing inode + beyond. 248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 00000000 fc:00 794418 /bin/cat\n", // Missing perms. 249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 r-xp fc:00 794418 /bin/cat\n", // Missing offset. 250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 r-xp 00000000 fc:00 /bin/cat\n", // Missing inode. 251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000 r-xp 00000000 fc:00 794418 /bin/cat\n", // Missing end. 252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "-0040b000 r-xp 00000000 fc:00 794418 /bin/cat\n", // Missing start. 253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 r-xp 00000000 794418 /bin/cat\n", // Missing device. 254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < arraysize(kTestCases); ++i) { 257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SCOPED_TRACE(base::StringPrintf("kTestCases[%zu] = %s", i, kTestCases[i])); 258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MappedMemoryRegion> regions; 259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(ParseProcMaps(kTestCases[i], ®ions)); 260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST(ProcMapsTest, InvalidInput) { 264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const char* kTestCases[] = { 265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "thisisal-0040b000 rwxp 00000000 fc:00 794418 /bin/cat\n", 266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "0040000d-linvalid rwxp 00000000 fc:00 794418 /bin/cat\n", 267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 inpu 00000000 fc:00 794418 /bin/cat\n", 268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 rwxp tforproc fc:00 794418 /bin/cat\n", 269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 rwxp 00000000 ma:ps 794418 /bin/cat\n", 270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "00400000-0040b000 rwxp 00000000 fc:00 parse! /bin/cat\n", 271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < arraysize(kTestCases); ++i) { 274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SCOPED_TRACE(base::StringPrintf("kTestCases[%zu] = %s", i, kTestCases[i])); 275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MappedMemoryRegion> regions; 276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(ParseProcMaps(kTestCases[i], ®ions)); 277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 280effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST(ProcMapsTest, ParseProcMapsEmptyString) { 281effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::vector<MappedMemoryRegion> regions; 282effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_TRUE(ParseProcMaps("", ®ions)); 283effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(0ULL, regions.size()); 284effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 285effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 286effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Testing a couple of remotely possible weird things in the input: 287effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// - Line ending with \r\n or \n\r. 288effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// - File name contains quotes. 289effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// - File name has whitespaces. 290effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST(ProcMapsTest, ParseProcMapsWeirdCorrectInput) { 291effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::vector<MappedMemoryRegion> regions; 292effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const std::string kContents = 293effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "00400000-0040b000 r-xp 00000000 fc:00 2106562 " 294effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " /bin/cat\r\n" 295effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "7f53b7dad000-7f53b7f62000 r-xp 00000000 fc:00 263011 " 296effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " /lib/x86_64-linux-gnu/libc-2.15.so\n\r" 297effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "7f53b816d000-7f53b818f000 r-xp 00000000 fc:00 264284 " 298effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " /lib/x86_64-linux-gnu/ld-2.15.so\n" 299effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "7fff9c7ff000-7fff9c800000 r-xp 00000000 00:00 0 " 300effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " \"vd so\"\n" 301effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 " 302effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " [vsys call]\n"; 303effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_TRUE(ParseProcMaps(kContents, ®ions)); 304effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(5ULL, regions.size()); 305effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ("/bin/cat", regions[0].path); 306effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ("/lib/x86_64-linux-gnu/libc-2.15.so", regions[1].path); 307effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ("/lib/x86_64-linux-gnu/ld-2.15.so", regions[2].path); 308effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ("\"vd so\"", regions[3].path); 309effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ("[vsys call]", regions[4].path); 310effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 311effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace debug 313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace base 314