1 //===-- LinuxProcMapsTest.cpp ---------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "gmock/gmock.h"
10 #include "gtest/gtest.h"
12 #include "Plugins/Process/Utility/LinuxProcMaps.h"
13 #include "lldb/Target/MemoryRegionInfo.h"
14 #include "lldb/Utility/Status.h"
17 using namespace lldb_private
;
19 typedef std::tuple
<const char *, MemoryRegionInfos
, const char *>
20 LinuxProcMapsTestParams
;
22 // Wrapper for convenience because Range is usually begin, size
23 static MemoryRegionInfo::RangeType
make_range(lldb::addr_t begin
,
25 MemoryRegionInfo::RangeType
range(begin
, 0);
26 range
.SetRangeEnd(end
);
30 class LinuxProcMapsTestFixture
31 : public ::testing::TestWithParam
<LinuxProcMapsTestParams
> {
35 MemoryRegionInfos regions
;
36 LinuxMapCallback callback
;
38 void SetUp() override
{
39 callback
= [this](llvm::Expected
<MemoryRegionInfo
> Info
) {
42 regions
.push_back(*Info
);
46 err_str
= toString(Info
.takeError());
51 void check_regions(LinuxProcMapsTestParams params
) {
52 EXPECT_THAT(std::get
<1>(params
), testing::ContainerEq(regions
));
53 ASSERT_EQ(std::get
<2>(params
), err_str
);
57 TEST_P(LinuxProcMapsTestFixture
, ParseMapRegions
) {
58 auto params
= GetParam();
59 ParseLinuxMapRegions(std::get
<0>(params
), callback
);
60 check_regions(params
);
63 // Note: ConstString("") != ConstString(nullptr)
64 // When a region has no name, it will have the latter in the MemoryRegionInfo
65 INSTANTIATE_TEST_SUITE_P(
66 ProcMapTests
, LinuxProcMapsTestFixture
,
68 // Nothing in nothing out
69 std::make_tuple("", MemoryRegionInfos
{}, ""),
70 // Various formatting error conditions
71 std::make_tuple("55a4512f7000/55a451b68000 rw-p 00000000 00:00 0",
73 "malformed /proc/{pid}/maps entry, missing dash "
74 "between address range"),
75 std::make_tuple("0-0 rw", MemoryRegionInfos
{},
76 "malformed /proc/{pid}/maps entry, missing some "
77 "portion of permissions"),
78 std::make_tuple("0-0 z--p 00000000 00:00 0", MemoryRegionInfos
{},
79 "unexpected /proc/{pid}/maps read permission char"),
80 std::make_tuple("0-0 rz-p 00000000 00:00 0", MemoryRegionInfos
{},
81 "unexpected /proc/{pid}/maps write permission char"),
82 std::make_tuple("0-0 rwzp 00000000 00:00 0", MemoryRegionInfos
{},
83 "unexpected /proc/{pid}/maps exec permission char"),
84 // Stops at first parsing error
86 "0-1 rw-p 00000000 00:00 0 [abc]\n"
87 "0-0 rwzp 00000000 00:00 0\n"
88 "2-3 r-xp 00000000 00:00 0 [def]\n",
90 MemoryRegionInfo(make_range(0, 1), MemoryRegionInfo::eYes
, MemoryRegionInfo::eYes
, MemoryRegionInfo::eNo
,
91 MemoryRegionInfo::eNo
,
92 MemoryRegionInfo::eYes
, ConstString("[abc]"),
93 MemoryRegionInfo::eDontKnow
, 0,
94 MemoryRegionInfo::eDontKnow
,
95 MemoryRegionInfo::eDontKnow
),
97 "unexpected /proc/{pid}/maps exec permission char"),
100 "55a4512f7000-55a451b68000 rw-p 00000000 00:00 0 [heap]",
103 make_range(0x55a4512f7000, 0x55a451b68000),
104 MemoryRegionInfo::eYes
, MemoryRegionInfo::eYes
, MemoryRegionInfo::eNo
,
105 MemoryRegionInfo::eNo
,
106 MemoryRegionInfo::eYes
,
107 ConstString("[heap]"), MemoryRegionInfo::eDontKnow
, 0,
108 MemoryRegionInfo::eDontKnow
, MemoryRegionInfo::eDontKnow
),
113 "7fc090021000-7fc094000000 ---p 00000000 00:00 0\n"
114 "7fc094000000-7fc094a00000 ---s 00000000 00:00 0\n"
115 "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 "
119 make_range(0x7fc090021000, 0x7fc094000000),
120 MemoryRegionInfo::eNo
, MemoryRegionInfo::eNo
, MemoryRegionInfo::eNo
,
121 MemoryRegionInfo::eNo
,
122 MemoryRegionInfo::eYes
,
123 ConstString(nullptr), MemoryRegionInfo::eDontKnow
, 0,
124 MemoryRegionInfo::eDontKnow
, MemoryRegionInfo::eDontKnow
),
126 make_range(0x7fc094000000, 0x7fc094a00000),
127 MemoryRegionInfo::eNo
, MemoryRegionInfo::eNo
, MemoryRegionInfo::eNo
,
128 MemoryRegionInfo::eYes
,
129 MemoryRegionInfo::eYes
,
130 ConstString(nullptr), MemoryRegionInfo::eDontKnow
, 0,
131 MemoryRegionInfo::eDontKnow
, MemoryRegionInfo::eDontKnow
),
133 make_range(0xffffffffff600000, 0xffffffffff601000),
134 MemoryRegionInfo::eYes
, MemoryRegionInfo::eNo
, MemoryRegionInfo::eYes
,
135 MemoryRegionInfo::eNo
,
136 MemoryRegionInfo::eYes
,
137 ConstString("[vsyscall]"), MemoryRegionInfo::eDontKnow
, 0,
138 MemoryRegionInfo::eDontKnow
, MemoryRegionInfo::eDontKnow
),
142 class LinuxProcSMapsTestFixture
: public LinuxProcMapsTestFixture
{};
144 INSTANTIATE_TEST_SUITE_P(
145 ProcSMapTests
, LinuxProcSMapsTestFixture
,
147 // Nothing in nothing out
148 std::make_tuple("", MemoryRegionInfos
{}, ""),
149 // Uses the same parsing for first line, so same errors but referring to
151 std::make_tuple("0/0 rw-p 00000000 00:00 0", MemoryRegionInfos
{},
152 "malformed /proc/{pid}/smaps entry, missing dash "
153 "between address range"),
154 // Stop parsing at first error
156 "1111-2222 rw-p 00000000 00:00 0 [foo]\n"
157 "0/0 rw-p 00000000 00:00 0",
160 make_range(0x1111, 0x2222),
161 MemoryRegionInfo::eYes
, MemoryRegionInfo::eYes
, MemoryRegionInfo::eNo
,
162 MemoryRegionInfo::eNo
,
163 MemoryRegionInfo::eYes
, ConstString("[foo]"),
164 MemoryRegionInfo::eDontKnow
, 0, MemoryRegionInfo::eDontKnow
,
165 MemoryRegionInfo::eDontKnow
),
167 "malformed /proc/{pid}/smaps entry, missing dash between address "
169 // Property line without a region is an error
170 std::make_tuple("Referenced: 2188 kB\n"
171 "1111-2222 rw-p 00000000 00:00 0 [foo]\n"
172 "3333-4444 rw-p 00000000 00:00 0 [bar]\n",
174 "Found a property line without a corresponding mapping "
175 "in /proc/{pid}/smaps"),
176 // Single region parses, has no flags
178 "1111-2222 rw-p 00000000 00:00 0 [foo]",
181 make_range(0x1111, 0x2222),
182 MemoryRegionInfo::eYes
, MemoryRegionInfo::eYes
, MemoryRegionInfo::eNo
,
183 MemoryRegionInfo::eNo
,
184 MemoryRegionInfo::eYes
, ConstString("[foo]"),
185 MemoryRegionInfo::eDontKnow
, 0, MemoryRegionInfo::eDontKnow
,
186 MemoryRegionInfo::eDontKnow
),
189 // Single shared region parses, has no flags
191 "1111-2222 rw-s 00000000 00:00 0 [foo]",
194 make_range(0x1111, 0x2222),
195 MemoryRegionInfo::eYes
, MemoryRegionInfo::eYes
, MemoryRegionInfo::eNo
,
196 MemoryRegionInfo::eYes
,
197 MemoryRegionInfo::eYes
, ConstString("[foo]"),
198 MemoryRegionInfo::eDontKnow
, 0, MemoryRegionInfo::eDontKnow
,
199 MemoryRegionInfo::eDontKnow
),
202 // Single region with flags, other lines ignored
204 "1111-2222 rw-p 00000000 00:00 0 [foo]\n"
205 "Referenced: 2188 kB\n"
206 "AnonHugePages: 0 kB\n"
210 make_range(0x1111, 0x2222),
211 MemoryRegionInfo::eYes
, MemoryRegionInfo::eYes
, MemoryRegionInfo::eNo
,
212 MemoryRegionInfo::eNo
,
213 MemoryRegionInfo::eYes
, ConstString("[foo]"),
214 MemoryRegionInfo::eDontKnow
, 0, MemoryRegionInfo::eYes
,
215 MemoryRegionInfo::eDontKnow
),
218 // Whitespace ignored
220 "0-0 rw-p 00000000 00:00 0\n"
223 MemoryRegionInfo(make_range(0, 0),
224 MemoryRegionInfo::eYes
, MemoryRegionInfo::eYes
, MemoryRegionInfo::eNo
,
225 MemoryRegionInfo::eNo
,
226 MemoryRegionInfo::eYes
, ConstString(nullptr),
227 MemoryRegionInfo::eDontKnow
, 0,
228 MemoryRegionInfo::eYes
,
229 MemoryRegionInfo::eDontKnow
),
232 // VmFlags line means it has flag info, but nothing is set
234 "0-0 rw-p 00000000 00:00 0\n"
237 MemoryRegionInfo(make_range(0, 0),
238 MemoryRegionInfo::eYes
, MemoryRegionInfo::eYes
, MemoryRegionInfo::eNo
,
239 MemoryRegionInfo::eNo
,
240 MemoryRegionInfo::eYes
, ConstString(nullptr),
241 MemoryRegionInfo::eDontKnow
, 0,
242 MemoryRegionInfo::eNo
,
243 MemoryRegionInfo::eDontKnow
),
246 // Handle some pages not having a flags line
248 "1111-2222 rw-p 00000000 00:00 0 [foo]\n"
249 "Referenced: 2188 kB\n"
250 "AnonHugePages: 0 kB\n"
251 "3333-4444 r-xp 00000000 00:00 0 [bar]\n"
255 make_range(0x1111, 0x2222),
256 MemoryRegionInfo::eYes
, MemoryRegionInfo::eYes
, MemoryRegionInfo::eNo
,
257 MemoryRegionInfo::eNo
,
258 MemoryRegionInfo::eYes
, ConstString("[foo]"),
259 MemoryRegionInfo::eDontKnow
, 0, MemoryRegionInfo::eDontKnow
,
260 MemoryRegionInfo::eDontKnow
),
262 make_range(0x3333, 0x4444), MemoryRegionInfo::eYes
, MemoryRegionInfo::eNo
, MemoryRegionInfo::eYes
,
263 MemoryRegionInfo::eNo
,
264 MemoryRegionInfo::eYes
, ConstString("[bar]"),
265 MemoryRegionInfo::eDontKnow
, 0, MemoryRegionInfo::eYes
,
266 MemoryRegionInfo::eDontKnow
),
269 // Handle no pages having a flags line (older kernels)
271 "1111-2222 rw-p 00000000 00:00 0\n"
272 "Referenced: 2188 kB\n"
273 "AnonHugePages: 0 kB\n"
274 "3333-4444 r-xp 00000000 00:00 0\n"
275 "KernelPageSize: 4 kB\n"
276 "MMUPageSize: 4 kB\n",
279 make_range(0x1111, 0x2222),
280 MemoryRegionInfo::eYes
, MemoryRegionInfo::eYes
, MemoryRegionInfo::eNo
,
281 MemoryRegionInfo::eNo
,
282 MemoryRegionInfo::eYes
, ConstString(nullptr),
283 MemoryRegionInfo::eDontKnow
, 0, MemoryRegionInfo::eDontKnow
,
284 MemoryRegionInfo::eDontKnow
),
286 make_range(0x3333, 0x4444),
287 MemoryRegionInfo::eYes
, MemoryRegionInfo::eNo
, MemoryRegionInfo::eYes
,
288 MemoryRegionInfo::eNo
,
289 MemoryRegionInfo::eYes
, ConstString(nullptr),
290 MemoryRegionInfo::eDontKnow
, 0, MemoryRegionInfo::eDontKnow
,
291 MemoryRegionInfo::eDontKnow
),
295 TEST_P(LinuxProcSMapsTestFixture
, ParseSMapRegions
) {
296 auto params
= GetParam();
297 ParseLinuxSMapRegions(std::get
<0>(params
), callback
);
298 check_regions(params
);