1//===-- LinuxProcMapsTest.cpp ---------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#include "gmock/gmock.h"
10#include "gtest/gtest.h"
11
12#include "Plugins/Process/Utility/LinuxProcMaps.h"
13#include "lldb/Target/MemoryRegionInfo.h"
14#include "lldb/Utility/Status.h"
15#include <tuple>
16
17using namespace lldb_private;
18
19typedef std::tuple<const char *, MemoryRegionInfos, const char *>
20 LinuxProcMapsTestParams;
21
22// Wrapper for convenience because Range is usually begin, size
23static MemoryRegionInfo::RangeType make_range(lldb::addr_t begin,
24 lldb::addr_t end) {
25 MemoryRegionInfo::RangeType range(begin, 0);
26 range.SetRangeEnd(end);
27 return range;
28}
29
30class LinuxProcMapsTestFixture
31 : public ::testing::TestWithParam<LinuxProcMapsTestParams> {
32protected:
33 Status error;
34 std::string err_str;
35 MemoryRegionInfos regions;
36 LinuxMapCallback callback;
37
38 void SetUp() override {
39 callback = [this](llvm::Expected<MemoryRegionInfo> Info) {
40 if (Info) {
41 err_str.clear();
42 regions.push_back(x: *Info);
43 return true;
44 }
45
46 err_str = toString(E: Info.takeError());
47 return false;
48 };
49 }
50
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);
54 }
55};
56
57TEST_P(LinuxProcMapsTestFixture, ParseMapRegions) {
58 auto params = GetParam();
59 ParseLinuxMapRegions(linux_map: std::get<0>(t&: params), callback);
60 check_regions(params);
61}
62
63// Note: ConstString("") != ConstString(nullptr)
64// When a region has no name, it will have the latter in the MemoryRegionInfo
65INSTANTIATE_TEST_SUITE_P(
66 ProcMapTests, LinuxProcMapsTestFixture,
67 ::testing::Values(
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",
72 MemoryRegionInfos{},
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
85 std::make_tuple(
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",
89 MemoryRegionInfos{
90 MemoryRegionInfo(
91 make_range(0, 1), MemoryRegionInfo::eYes,
92 MemoryRegionInfo::eYes, MemoryRegionInfo::eNo,
93 MemoryRegionInfo::eNo, MemoryRegionInfo::eYes,
94 ConstString("[abc]"), MemoryRegionInfo::eDontKnow, 0,
95 MemoryRegionInfo::eDontKnow, MemoryRegionInfo::eDontKnow,
96 MemoryRegionInfo::eDontKnow),
97 },
98 "unexpected /proc/{pid}/maps exec permission char"),
99 // Single entry
100 std::make_tuple(
101 "55a4512f7000-55a451b68000 rw-p 00000000 00:00 0 [heap]",
102 MemoryRegionInfos{
103 MemoryRegionInfo(
104 make_range(0x55a4512f7000, 0x55a451b68000),
105 MemoryRegionInfo::eYes, MemoryRegionInfo::eYes,
106 MemoryRegionInfo::eNo, MemoryRegionInfo::eNo,
107 MemoryRegionInfo::eYes, ConstString("[heap]"),
108 MemoryRegionInfo::eDontKnow, 0, MemoryRegionInfo::eDontKnow,
109 MemoryRegionInfo::eDontKnow, MemoryRegionInfo::eDontKnow),
110 },
111 ""),
112 // Multiple entries
113 std::make_tuple(
114 "7fc090021000-7fc094000000 ---p 00000000 00:00 0\n"
115 "7fc094000000-7fc094a00000 ---s 00000000 00:00 0\n"
116 "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 "
117 "[vsyscall]",
118 MemoryRegionInfos{
119 MemoryRegionInfo(
120 make_range(0x7fc090021000, 0x7fc094000000),
121 MemoryRegionInfo::eNo, MemoryRegionInfo::eNo,
122 MemoryRegionInfo::eNo, MemoryRegionInfo::eNo,
123 MemoryRegionInfo::eYes, ConstString(nullptr),
124 MemoryRegionInfo::eDontKnow, 0, MemoryRegionInfo::eDontKnow,
125 MemoryRegionInfo::eDontKnow, MemoryRegionInfo::eDontKnow),
126 MemoryRegionInfo(
127 make_range(0x7fc094000000, 0x7fc094a00000),
128 MemoryRegionInfo::eNo, MemoryRegionInfo::eNo,
129 MemoryRegionInfo::eNo, MemoryRegionInfo::eYes,
130 MemoryRegionInfo::eYes, ConstString(nullptr),
131 MemoryRegionInfo::eDontKnow, 0, MemoryRegionInfo::eDontKnow,
132 MemoryRegionInfo::eDontKnow, MemoryRegionInfo::eDontKnow),
133 MemoryRegionInfo(
134 make_range(0xffffffffff600000, 0xffffffffff601000),
135 MemoryRegionInfo::eYes, MemoryRegionInfo::eNo,
136 MemoryRegionInfo::eYes, MemoryRegionInfo::eNo,
137 MemoryRegionInfo::eYes, ConstString("[vsyscall]"),
138 MemoryRegionInfo::eDontKnow, 0, MemoryRegionInfo::eDontKnow,
139 MemoryRegionInfo::eDontKnow, MemoryRegionInfo::eDontKnow),
140 },
141 "")));
142
143class LinuxProcSMapsTestFixture : public LinuxProcMapsTestFixture {};
144
145INSTANTIATE_TEST_SUITE_P(
146 ProcSMapTests, LinuxProcSMapsTestFixture,
147 ::testing::Values(
148 // Nothing in nothing out
149 std::make_tuple("", MemoryRegionInfos{}, ""),
150 // Uses the same parsing for first line, so same errors but referring to
151 // smaps
152 std::make_tuple("0/0 rw-p 00000000 00:00 0", MemoryRegionInfos{},
153 "malformed /proc/{pid}/smaps entry, missing dash "
154 "between address range"),
155 // Stop parsing at first error
156 std::make_tuple(
157 "1111-2222 rw-p 00000000 00:00 0 [foo]\n"
158 "0/0 rw-p 00000000 00:00 0",
159 MemoryRegionInfos{
160 MemoryRegionInfo(
161 make_range(0x1111, 0x2222), MemoryRegionInfo::eYes,
162 MemoryRegionInfo::eYes, MemoryRegionInfo::eNo,
163 MemoryRegionInfo::eNo, MemoryRegionInfo::eYes,
164 ConstString("[foo]"), MemoryRegionInfo::eDontKnow, 0,
165 MemoryRegionInfo::eDontKnow, MemoryRegionInfo::eDontKnow,
166 MemoryRegionInfo::eDontKnow),
167 },
168 "malformed /proc/{pid}/smaps entry, missing dash between address "
169 "range"),
170 // Property line without a region is an error
171 std::make_tuple("Referenced: 2188 kB\n"
172 "1111-2222 rw-p 00000000 00:00 0 [foo]\n"
173 "3333-4444 rw-p 00000000 00:00 0 [bar]\n",
174 MemoryRegionInfos{},
175 "Found a property line without a corresponding mapping "
176 "in /proc/{pid}/smaps"),
177 // Single region parses, has no flags
178 std::make_tuple(
179 "1111-2222 rw-p 00000000 00:00 0 [foo]",
180 MemoryRegionInfos{
181 MemoryRegionInfo(
182 make_range(0x1111, 0x2222), MemoryRegionInfo::eYes,
183 MemoryRegionInfo::eYes, MemoryRegionInfo::eNo,
184 MemoryRegionInfo::eNo, MemoryRegionInfo::eYes,
185 ConstString("[foo]"), MemoryRegionInfo::eDontKnow, 0,
186 MemoryRegionInfo::eDontKnow, MemoryRegionInfo::eDontKnow,
187 MemoryRegionInfo::eDontKnow),
188 },
189 ""),
190 // Single shared region parses, has no flags
191 std::make_tuple(
192 "1111-2222 rw-s 00000000 00:00 0 [foo]",
193 MemoryRegionInfos{
194 MemoryRegionInfo(
195 make_range(0x1111, 0x2222), MemoryRegionInfo::eYes,
196 MemoryRegionInfo::eYes, MemoryRegionInfo::eNo,
197 MemoryRegionInfo::eYes, MemoryRegionInfo::eYes,
198 ConstString("[foo]"), MemoryRegionInfo::eDontKnow, 0,
199 MemoryRegionInfo::eDontKnow, MemoryRegionInfo::eDontKnow,
200 MemoryRegionInfo::eDontKnow),
201 },
202 ""),
203 // Single region with flags, other lines ignored
204 std::make_tuple(
205 "1111-2222 rw-p 00000000 00:00 0 [foo]\n"
206 "Referenced: 2188 kB\n"
207 "AnonHugePages: 0 kB\n"
208 "VmFlags: mt",
209 MemoryRegionInfos{
210 MemoryRegionInfo(
211 make_range(0x1111, 0x2222), MemoryRegionInfo::eYes,
212 MemoryRegionInfo::eYes, MemoryRegionInfo::eNo,
213 MemoryRegionInfo::eNo, MemoryRegionInfo::eYes,
214 ConstString("[foo]"), MemoryRegionInfo::eDontKnow, 0,
215 MemoryRegionInfo::eYes, MemoryRegionInfo::eDontKnow,
216 MemoryRegionInfo::eNo),
217 },
218 ""),
219 // Whitespace ignored
220 std::make_tuple(
221 "0-0 rw-p 00000000 00:00 0\n"
222 "VmFlags: mt ",
223 MemoryRegionInfos{
224 MemoryRegionInfo(
225 make_range(0, 0), MemoryRegionInfo::eYes,
226 MemoryRegionInfo::eYes, MemoryRegionInfo::eNo,
227 MemoryRegionInfo::eNo, MemoryRegionInfo::eYes,
228 ConstString(nullptr), MemoryRegionInfo::eDontKnow, 0,
229 MemoryRegionInfo::eYes, MemoryRegionInfo::eDontKnow,
230 MemoryRegionInfo::eNo),
231 },
232 ""),
233 // VmFlags line means it has flag info, but nothing is set
234 std::make_tuple(
235 "0-0 rw-p 00000000 00:00 0\n"
236 "VmFlags: ",
237 MemoryRegionInfos{
238 MemoryRegionInfo(
239 make_range(0, 0), MemoryRegionInfo::eYes,
240 MemoryRegionInfo::eYes, MemoryRegionInfo::eNo,
241 MemoryRegionInfo::eNo, MemoryRegionInfo::eYes,
242 ConstString(nullptr), MemoryRegionInfo::eDontKnow, 0,
243 MemoryRegionInfo::eNo, MemoryRegionInfo::eDontKnow,
244 MemoryRegionInfo::eNo),
245 },
246 ""),
247 // Handle some pages not having a flags line
248 std::make_tuple(
249 "1111-2222 rw-p 00000000 00:00 0 [foo]\n"
250 "Referenced: 2188 kB\n"
251 "AnonHugePages: 0 kB\n"
252 "3333-4444 r-xp 00000000 00:00 0 [bar]\n"
253 "VmFlags: mt",
254 MemoryRegionInfos{
255 MemoryRegionInfo(
256 make_range(0x1111, 0x2222), MemoryRegionInfo::eYes,
257 MemoryRegionInfo::eYes, MemoryRegionInfo::eNo,
258 MemoryRegionInfo::eNo, MemoryRegionInfo::eYes,
259 ConstString("[foo]"), MemoryRegionInfo::eDontKnow, 0,
260 MemoryRegionInfo::eDontKnow, MemoryRegionInfo::eDontKnow,
261 MemoryRegionInfo::eDontKnow),
262 MemoryRegionInfo(
263 make_range(0x3333, 0x4444), MemoryRegionInfo::eYes,
264 MemoryRegionInfo::eNo, MemoryRegionInfo::eYes,
265 MemoryRegionInfo::eNo, MemoryRegionInfo::eYes,
266 ConstString("[bar]"), MemoryRegionInfo::eDontKnow, 0,
267 MemoryRegionInfo::eYes, MemoryRegionInfo::eDontKnow,
268 MemoryRegionInfo::eNo),
269 },
270 ""),
271 // Handle no pages having a flags line (older kernels)
272 std::make_tuple(
273 "1111-2222 rw-p 00000000 00:00 0\n"
274 "Referenced: 2188 kB\n"
275 "AnonHugePages: 0 kB\n"
276 "3333-4444 r-xp 00000000 00:00 0\n"
277 "KernelPageSize: 4 kB\n"
278 "MMUPageSize: 4 kB\n",
279 MemoryRegionInfos{
280 MemoryRegionInfo(
281 make_range(0x1111, 0x2222), MemoryRegionInfo::eYes,
282 MemoryRegionInfo::eYes, MemoryRegionInfo::eNo,
283 MemoryRegionInfo::eNo, MemoryRegionInfo::eYes,
284 ConstString(nullptr), MemoryRegionInfo::eDontKnow, 0,
285 MemoryRegionInfo::eDontKnow, MemoryRegionInfo::eDontKnow,
286 MemoryRegionInfo::eDontKnow),
287 MemoryRegionInfo(
288 make_range(0x3333, 0x4444), MemoryRegionInfo::eYes,
289 MemoryRegionInfo::eNo, MemoryRegionInfo::eYes,
290 MemoryRegionInfo::eNo, MemoryRegionInfo::eYes,
291 ConstString(nullptr), MemoryRegionInfo::eDontKnow, 0,
292 MemoryRegionInfo::eDontKnow, MemoryRegionInfo::eDontKnow,
293 MemoryRegionInfo::eDontKnow),
294 },
295 ""),
296 // We must look for exact flag strings, ignoring substrings of longer
297 // flag names.
298 std::make_tuple(
299 "0-0 rw-p 00000000 00:00 0\n"
300 "VmFlags: amt mtb amtb",
301 MemoryRegionInfos{
302 MemoryRegionInfo(
303 make_range(0, 0), MemoryRegionInfo::eYes,
304 MemoryRegionInfo::eYes, MemoryRegionInfo::eNo,
305 MemoryRegionInfo::eNo, MemoryRegionInfo::eYes,
306 ConstString(nullptr), MemoryRegionInfo::eDontKnow, 0,
307 MemoryRegionInfo::eNo, MemoryRegionInfo::eDontKnow,
308 MemoryRegionInfo::eNo),
309 },
310 "")));
311
312TEST_P(LinuxProcSMapsTestFixture, ParseSMapRegions) {
313 auto params = GetParam();
314 ParseLinuxSMapRegions(linux_smap: std::get<0>(t&: params), callback);
315 check_regions(params);
316}
317

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of lldb/unittests/Process/Utility/LinuxProcMapsTest.cpp