1 #include "huge_page_deducer.h" 2 3 #include "base/logging.h" 4 #include "compat/string.h" 5 #include "compat/test.h" 6 7 8 namespace quipper { 9 namespace { 10 using PerfEvent = PerfDataProto::PerfEvent; 11 using MMapEvent = PerfDataProto::MMapEvent; 12 using ::testing::EqualsProto; 13 using ::testing::Pointwise; 14 using ::testing::proto::Partially; 15 16 // AddMmap is a helper function to create simple MMapEvents, with which 17 // testcases can encode "maps" entries similar to /proc/self/maps in a tabular 18 // one-line-per-entry. 19 void AddMmap(uint32_t pid, uint64_t mmap_start, uint64_t length, uint64_t pgoff, 20 const string& file, RepeatedPtrField<PerfEvent>* events) { 21 MMapEvent* ev = events->Add()->mutable_mmap_event(); 22 ev->set_pid(pid); 23 ev->set_start(mmap_start); 24 ev->set_len(length); 25 ev->set_pgoff(pgoff); 26 ev->set_filename(file); 27 } 28 29 TEST(HugePageDeducer, HugePagesMappings) { 30 RepeatedPtrField<PerfEvent> events; 31 { 32 MMapEvent* ev = events.Add()->mutable_mmap_event(); 33 ev->set_pid(1234); 34 ev->set_start(0x40000000); 35 ev->set_len(0x18000); 36 ev->set_pgoff(0); 37 ev->set_filename("/usr/lib/libfoo.so"); 38 } 39 { 40 MMapEvent* ev = events.Add()->mutable_mmap_event(); 41 ev->set_pid(1234); 42 ev->set_start(0x40018000); 43 ev->set_len(0x1e8000); 44 ev->set_pgoff(0); 45 ev->set_filename("/opt/google/chrome/chrome"); 46 } 47 { 48 MMapEvent* ev = events.Add()->mutable_mmap_event(); 49 ev->set_pid(1234); 50 ev->set_start(0x40200000); 51 ev->set_len(0x1c00000); 52 ev->set_pgoff(0); 53 ev->set_filename("//anon"); 54 } 55 { 56 MMapEvent* ev = events.Add()->mutable_mmap_event(); 57 ev->set_pid(1234); 58 ev->set_start(0x41e00000); 59 ev->set_len(0x4000000); 60 ev->set_pgoff(0x1de8000); 61 ev->set_filename("/opt/google/chrome/chrome"); 62 } 63 { 64 MMapEvent* ev = events.Add()->mutable_mmap_event(); 65 ev->set_pid(2345); 66 ev->set_start(0x45e00000); 67 ev->set_len(0x1e00000); 68 ev->set_pgoff(0); 69 ev->set_filename("//anon"); 70 } 71 { 72 MMapEvent* ev = events.Add()->mutable_mmap_event(); 73 ev->set_pid(2345); 74 ev->set_start(0x47c00000); 75 ev->set_len(0x4000000); 76 ev->set_pgoff(0x1e00000); 77 ev->set_filename("/opt/google/chrome/chrome"); 78 } 79 80 DeduceHugePages(&events); 81 CombineMappings(&events); 82 83 ASSERT_GE(events.size(), 3); 84 EXPECT_EQ(events.size(), 3); 85 86 EXPECT_THAT(events, 87 Pointwise(Partially(EqualsProto()), 88 { 89 "mmap_event: { start: 0x40000000 len:0x18000 " 90 "pgoff: 0 filename: '/usr/lib/libfoo.so'}", 91 "mmap_event: { start: 0x40018000 len:0x5de8000 " 92 "pgoff: 0 filename: '/opt/google/chrome/chrome'}", 93 "mmap_event: { start: 0x45e00000 len:0x5e00000 " 94 "pgoff: 0 filename: '/opt/google/chrome/chrome'}", 95 })); 96 97 EXPECT_EQ("/usr/lib/libfoo.so", events[0].mmap_event().filename()); 98 EXPECT_EQ(0x40000000, events[0].mmap_event().start()); 99 EXPECT_EQ(0x18000, events[0].mmap_event().len()); 100 EXPECT_EQ(0x0, events[0].mmap_event().pgoff()); 101 102 // The split Chrome mappings should have been combined. 103 EXPECT_EQ("/opt/google/chrome/chrome", events[2].mmap_event().filename()); 104 EXPECT_EQ(0x40018000, events[1].mmap_event().start()); 105 EXPECT_EQ(0x5de8000, events[1].mmap_event().len()); 106 EXPECT_EQ(0x0, events[1].mmap_event().pgoff()); 107 108 EXPECT_EQ("/opt/google/chrome/chrome", events[2].mmap_event().filename()); 109 EXPECT_EQ(0x45e00000, events[2].mmap_event().start()); 110 EXPECT_EQ(0x5e00000, events[2].mmap_event().len()); 111 EXPECT_EQ(0x0, events[2].mmap_event().pgoff()); 112 } 113 114 enum HugepageTextStyle { 115 kAnonHugepageText, 116 kNoHugepageText, 117 }; 118 119 class HugepageTextStyleDependent 120 : public ::testing::TestWithParam<HugepageTextStyle> { 121 protected: 122 void AddHugepageTextMmap(uint32_t pid, uint64_t mmap_start, uint64_t length, 123 uint64_t pgoff, string file, 124 RepeatedPtrField<PerfEvent>* events) { 125 // Various hugepage implementations and perf versions result in various 126 // quirks in how hugepages are reported. 127 128 switch (GetParam()) { 129 case kNoHugepageText: 130 // Do nothing; the maps are complete and file-backed 131 break; 132 case kAnonHugepageText: 133 // exec is remapped into anonymous memory, which perf reports as 134 // '//anon'. Anonymous sections have no pgoff. 135 file = "//anon"; 136 pgoff = 0; 137 break; 138 default: 139 CHECK(false) << "Unimplemented"; 140 } 141 AddMmap(pid, mmap_start, length, pgoff, file, events); 142 } 143 }; 144 145 TEST_P(HugepageTextStyleDependent, OnlyOneMappingThatIsHuge) { 146 RepeatedPtrField<PerfEvent> events; 147 AddHugepageTextMmap(1, 0x100200000, 0x200000, 0, "file", &events); 148 149 DeduceHugePages(&events); 150 CombineMappings(&events); 151 152 // Don't check filename='file'; if it's backed by anonymous memory, it isn't 153 // possible for quipper to deduce the filename without other mmaps immediately 154 // adjacent. 155 EXPECT_THAT( 156 events, 157 Pointwise(Partially(EqualsProto()), 158 {"mmap_event: { start: 0x100200000 len: 0x200000 pgoff: 0}"})); 159 } 160 161 TEST_P(HugepageTextStyleDependent, OnlyOneMappingUnaligned) { 162 RepeatedPtrField<PerfEvent> events; 163 AddMmap(2, 0x200201000, 0x200000, 0, "file", &events); 164 165 DeduceHugePages(&events); 166 CombineMappings(&events); 167 168 EXPECT_THAT(events, Pointwise(Partially(EqualsProto()), 169 {"mmap_event: { start: 0x200201000 " 170 "len:0x200000 pgoff: 0 filename: 'file'}"})); 171 } 172 173 TEST_P(HugepageTextStyleDependent, FirstPageIsHugeWithSmallTail) { 174 RepeatedPtrField<PerfEvent> events; 175 AddHugepageTextMmap(3, 0x300400000, 0x400000, 0, "file", &events); 176 AddMmap(3, 0x300800000, 0x001000, 0x400000, "file", &events); 177 178 DeduceHugePages(&events); 179 CombineMappings(&events); 180 181 EXPECT_THAT(events, Pointwise(Partially(EqualsProto()), 182 {"mmap_event: { start: 0x300400000 " 183 "len:0x401000 pgoff: 0 filename: 'file'}"})); 184 } 185 186 TEST_P(HugepageTextStyleDependent, DISABLED_FirstPageIsSmallWithHugeTail) { 187 // This test is disabled because DeduceHugePage requires a non-zero pgoff 188 // *after* a hugepage_text section in order to correctly deduce it, so it 189 // is unable to deduce these cases. 190 RepeatedPtrField<PerfEvent> events; 191 AddMmap(4, 0x4003ff000, 0x001000, 0, "file", &events); 192 AddHugepageTextMmap(4, 0x400400000, 0x200000, 0x001000, "file", &events); 193 194 DeduceHugePages(&events); 195 CombineMappings(&events); 196 197 EXPECT_THAT(events, Pointwise(Partially(EqualsProto()), 198 {"mmap_event: { start: 0x4003ff000 " 199 "len:0x201000 pgoff: 0 filename: 'file'}"})); 200 } 201 202 TEST_P(HugepageTextStyleDependent, HugePageBetweenTwoSmallSections) { 203 RepeatedPtrField<PerfEvent> events; 204 AddMmap(5, 0x5003ff000, 0x001000, 0, "file", &events); 205 AddHugepageTextMmap(5, 0x500400000, 0x200000, 0x001000, "file", &events); 206 AddMmap(5, 0x500600000, 0x001000, 0x201000, "file", &events); 207 208 DeduceHugePages(&events); 209 CombineMappings(&events); 210 211 EXPECT_THAT(events, Pointwise(Partially(EqualsProto()), 212 {"mmap_event: { start: 0x5003ff000 " 213 "len:0x202000 pgoff: 0 filename: 'file'}"})); 214 } 215 216 TEST_P(HugepageTextStyleDependent, HugePageSplitByEarlyMlockBetweenTwoSmall) { 217 RepeatedPtrField<PerfEvent> events; 218 AddMmap(6, 0x6003ff000, 0x001000, 0, "file", &events); 219 AddHugepageTextMmap(6, 0x600400000, 0x3f8000, 0x001000, "file", &events); 220 AddHugepageTextMmap(6, 0x6007f8000, 0x008000, 0x3f9000, "file", &events); 221 AddMmap(6, 0x600800000, 0x001000, 0x401000, "file", &events); 222 223 DeduceHugePages(&events); 224 CombineMappings(&events); 225 226 EXPECT_THAT(events, Pointwise(Partially(EqualsProto()), 227 {"mmap_event: { start: 0x6003ff000 " 228 "len:0x402000 pgoff: 0 filename: 'file'}"})); 229 } 230 231 TEST_P(HugepageTextStyleDependent, HugePageSplitByLateMlockBetweenTwoSmall) { 232 RepeatedPtrField<PerfEvent> events; 233 AddMmap(7, 0x7003ff000, 0x001000, 0, "file", &events); 234 AddHugepageTextMmap(7, 0x700400000, 0x008000, 0x001000, "file", &events); 235 AddHugepageTextMmap(7, 0x700408000, 0x3f8000, 0x009000, "file", &events); 236 AddMmap(7, 0x700800000, 0x001000, 0x401000, "file", &events); 237 238 DeduceHugePages(&events); 239 CombineMappings(&events); 240 241 EXPECT_THAT(events, Pointwise(Partially(EqualsProto()), 242 {"mmap_event: { start: 0x7003ff000 " 243 "len:0x402000 pgoff: 0 filename: 'file'}"})); 244 } 245 246 TEST_P(HugepageTextStyleDependent, HugePageSplitEvenlyByMlockBetweenTwoSmall) { 247 RepeatedPtrField<PerfEvent> events; 248 AddMmap(8, 0x8003ff000, 0x001000, 0, "file", &events); 249 AddHugepageTextMmap(8, 0x800400000, 0x0f8000, 0x001000, "file", &events); 250 AddHugepageTextMmap(8, 0x8004f8000, 0x008000, 0x0f9000, "file", &events); 251 AddHugepageTextMmap(8, 0x800500000, 0x100000, 0x101000, "file", &events); 252 AddMmap(8, 0x800600000, 0x001000, 0x201000, "file", &events); 253 254 DeduceHugePages(&events); 255 CombineMappings(&events); 256 257 EXPECT_THAT(events, Pointwise(Partially(EqualsProto()), 258 {"mmap_event: { start: 0x8003ff000 " 259 "len:0x202000 pgoff: 0 filename: 'file'}"})); 260 } 261 262 TEST_P(HugepageTextStyleDependent, MultipleContiguousHugepages) { 263 RepeatedPtrField<PerfEvent> events; 264 AddMmap(9, 0x9003ff000, 0x001000, 0, "file", &events); 265 AddHugepageTextMmap(9, 0x900400000, 0x200000, 0x001000, "file", &events); 266 AddHugepageTextMmap(9, 0x900600000, 0x200000, 0x201000, "file", &events); 267 AddMmap(9, 0x900800000, 0x001000, 0x401000, "file", &events); 268 269 DeduceHugePages(&events); 270 CombineMappings(&events); 271 272 EXPECT_THAT(events, Pointwise(Partially(EqualsProto()), 273 {"mmap_event: { start: 0x9003ff000 " 274 "len:0x402000 pgoff: 0 filename: 'file'}"})); 275 } 276 277 TEST_P(HugepageTextStyleDependent, MultipleContiguousMlockSplitHugepages) { 278 // Think: 279 // - hugepage_text 4MiB range 280 // - mlock alternating 512-KiB chunks 281 RepeatedPtrField<PerfEvent> events; 282 AddMmap(10, 0xa003ff000, 0x001000, 0, "file", &events); 283 AddHugepageTextMmap(10, 0xa00400000, 0x080000, 0x001000, "file", &events); 284 AddHugepageTextMmap(10, 0xa00480000, 0x080000, 0x081000, "file", &events); 285 AddHugepageTextMmap(10, 0xa00500000, 0x080000, 0x101000, "file", &events); 286 AddHugepageTextMmap(10, 0xa00580000, 0x080000, 0x181000, "file", &events); 287 AddHugepageTextMmap(10, 0xa00600000, 0x080000, 0x201000, "file", &events); 288 AddHugepageTextMmap(10, 0xa00680000, 0x080000, 0x281000, "file", &events); 289 AddHugepageTextMmap(10, 0xa00700000, 0x080000, 0x301000, "file", &events); 290 AddHugepageTextMmap(10, 0xa00780000, 0x080000, 0x381000, "file", &events); 291 AddMmap(10, 0xa00800000, 0x001000, 0x401000, "file", &events); 292 293 DeduceHugePages(&events); 294 CombineMappings(&events); 295 296 EXPECT_THAT(events, Pointwise(Partially(EqualsProto()), 297 {"mmap_event: { start: 0xa003ff000 " 298 "len:0x402000 pgoff: 0 filename: 'file'}"})); 299 } 300 301 TEST_P(HugepageTextStyleDependent, MultipleWithUnalignedInitialHugePage) { 302 // Base on real program 303 RepeatedPtrField<PerfEvent> events; 304 305 AddHugepageTextMmap(11, 0x85d32e000, 0x6d2000, 0x0, "file", &events); 306 AddHugepageTextMmap(11, 0x85da00000, 0x6a00000, 0x6d2000, "file", &events); 307 AddMmap(11, 0x864400000, 0x200000, 0x70d2000, "file", &events); 308 AddHugepageTextMmap(11, 0x864600000, 0x200000, 0x72d2000, "file", &events); 309 AddMmap(11, 0x864800000, 0x600000, 0x74d2000, "file", &events); 310 AddHugepageTextMmap(11, 0x864e00000, 0x200000, 0x7ad2000, "file", &events); 311 AddMmap(11, 0x865000000, 0x4a000, 0x7cd2000, "file", &events); 312 AddMmap(11, 0x86504a000, 0x1000, 0x7d1c000, "file", &events); 313 AddMmap(11, 0xa3d368000, 0x3a96000, 0x0, "file2", &events); 314 AddMmap(11, 0xa467cc000, 0x2000, 0x0, "file3", &events); 315 316 DeduceHugePages(&events); 317 CombineMappings(&events); 318 319 EXPECT_THAT(events, Pointwise(Partially(EqualsProto()), 320 { 321 "mmap_event: { start: 0x85d32e000 " 322 "len:0x7d1d000 pgoff: 0 filename: 'file'}", 323 "mmap_event: { start: 0xa3d368000 " 324 "len:0x3a96000 pgoff: 0 filename: 'file2'}", 325 "mmap_event: { start: 0xa467cc000 " 326 "len:0x2000, pgoff: 0 filename: 'file3'}", 327 })); 328 } 329 330 TEST_P(HugepageTextStyleDependent, MultipleWithUnalignedInitialHugePage2) { 331 // Base on real program 332 RepeatedPtrField<PerfEvent> events; 333 AddHugepageTextMmap(12, 0xbcff6000, 0x200000, 0x00000000, "file", &events); 334 AddMmap(12, 0xbd1f6000, 0x300a000, 0x200000, "file", &events); 335 AddHugepageTextMmap(12, 0xc0200000, 0x2b374000, 0x320a000, "file", &events); 336 AddHugepageTextMmap(12, 0xeb574000, 0x514000, 0x2e57e000, "file", &events); 337 AddHugepageTextMmap(12, 0xeba88000, 0x1d78000, 0x2ea92000, "file", &events); 338 AddMmap(12, 0xed800000, 0x1200000, 0x3080a000, "file", &events); 339 AddHugepageTextMmap(12, 0xeea00000, 0x200000, 0x31a0a000, "file", &events); 340 AddMmap(12, 0xeec00000, 0x2800000, 0x31c0a000, "file", &events); 341 AddHugepageTextMmap(12, 0xf1400000, 0x200000, 0x3440a000, "file", &events); 342 AddMmap(12, 0xf1600000, 0x89f000, 0x3460a000, "file", &events); 343 AddMmap(12, 0xf1e9f000, 0x1000, 0x34ea9000, "file", &events); 344 345 DeduceHugePages(&events); 346 CombineMappings(&events); 347 348 EXPECT_THAT(events, Pointwise(Partially(EqualsProto()), 349 {"mmap_event: { start: 0xbcff6000 " 350 "len:0x34eaa000 pgoff: 0 filename: 'file'}"})); 351 } 352 353 TEST_P(HugepageTextStyleDependent, NoMmaps) { 354 RepeatedPtrField<PerfEvent> events; 355 events.Add(); 356 357 DeduceHugePages(&events); 358 CombineMappings(&events); 359 360 EXPECT_THAT(events, Pointwise(EqualsProto(), std::vector<PerfEvent>(1))); 361 } 362 TEST_P(HugepageTextStyleDependent, MultipleNonMmaps) { 363 RepeatedPtrField<PerfEvent> events; 364 events.Add(); 365 events.Add(); 366 367 DeduceHugePages(&events); 368 CombineMappings(&events); 369 370 EXPECT_THAT(events, Pointwise(EqualsProto(), std::vector<PerfEvent>(2))); 371 } 372 TEST_P(HugepageTextStyleDependent, NonMmapFirstMmap) { 373 RepeatedPtrField<PerfEvent> events; 374 events.Add(); 375 AddHugepageTextMmap(12, 0, 0x200000, 0, "file", &events); 376 377 DeduceHugePages(&events); 378 CombineMappings(&events); 379 380 EXPECT_THAT(events, Pointwise(Partially(EqualsProto()), 381 {"", "mmap_event: { pgoff: 0 }"})); 382 } 383 TEST_P(HugepageTextStyleDependent, NonMmapAfterLastMmap) { 384 RepeatedPtrField<PerfEvent> events; 385 AddHugepageTextMmap(12, 0, 0x200000, 0, "file", &events); 386 events.Add(); 387 388 DeduceHugePages(&events); 389 CombineMappings(&events); 390 391 EXPECT_THAT(events, Pointwise(Partially(EqualsProto()), 392 {"mmap_event: { pgoff: 0 }", ""})); 393 } 394 395 INSTANTIATE_TEST_CASE_P(NoHugepageText, HugepageTextStyleDependent, 396 ::testing::Values(kNoHugepageText)); 397 INSTANTIATE_TEST_CASE_P(AnonHugepageText, HugepageTextStyleDependent, 398 ::testing::Values(kAnonHugepageText)); 399 400 TEST(HugePageDeducer, DoesNotChangeVirtuallyContiguousPgoffNonContiguous) { 401 // We've seen programs with strange memory layouts having virtually contiguous 402 // memory backed by non-contiguous bits of a file. 403 RepeatedPtrField<PerfEvent> events; 404 AddMmap(758463, 0x2f278000, 0x20000, 0, "lib0.so", &events); 405 AddMmap(758463, 0x2f29d000, 0x2000, 0, "shm", &events); 406 AddMmap(758463, 0x2f2a2000, 0xa000, 0, "lib1.so", &events); 407 AddMmap(758463, 0x3d400000, 0x9ee000, 0, "lib2.so", &events); 408 AddMmap(758463, 0x3e000000, 0x16000, 0, "lib3.so", &events); 409 AddMmap(758463, 0x3e400000, 0x270000, 0x1a00000, "shm", &events); 410 AddMmap(758463, 0x3e670000, 0x10000, 0x1aaac000, "shm", &events); 411 AddMmap(758463, 0x3e680000, 0x10000, 0x1b410000, "shm", &events); 412 413 DeduceHugePages(&events); 414 CombineMappings(&events); 415 416 EXPECT_THAT(events, 417 Pointwise(Partially(EqualsProto()), 418 { 419 "mmap_event: { pgoff: 0 filename: 'lib0.so' }", 420 "mmap_event: { pgoff: 0 filename: 'shm' }", 421 "mmap_event: { pgoff: 0 filename: 'lib1.so' }", 422 "mmap_event: { pgoff: 0 filename: 'lib2.so' }", 423 "mmap_event: { pgoff: 0 filename: 'lib3.so' }", 424 "mmap_event: { pgoff: 0x1a00000 filename: 'shm' }", 425 "mmap_event: { pgoff: 0x1aaac000 filename: 'shm' }", 426 "mmap_event: { pgoff: 0x1b410000 filename: 'shm' }", 427 })); 428 } 429 430 TEST(HugePageDeducer, IgnoresDynamicMmaps) { 431 // Now, let's watch a binary hugepage_text itself. 432 RepeatedPtrField<PerfEvent> events; 433 AddMmap(6531, 0x560d76b25000, 0x24ce000, 0, "main", &events); 434 events.rbegin()->set_timestamp(700413232676401); 435 AddMmap(6531, 0x7f686a1ec000, 0x24000, 0, "ld.so", &events); 436 events.rbegin()->set_timestamp(700413232691935); 437 AddMmap(6531, 0x7ffea5dc8000, 0x2000, 0, "[vdso]", &events); 438 events.rbegin()->set_timestamp(700413232701418); 439 AddMmap(6531, 0x7f686a1e3000, 0x5000, 0, "lib1.so", &events); 440 events.rbegin()->set_timestamp(700413232824216); 441 AddMmap(6531, 0x7f686a1a8000, 0x3a000, 0, "lib2.so", &events); 442 events.rbegin()->set_timestamp(700413232854520); 443 AddMmap(6531, 0x7f6869ea7000, 0x5000, 0, "lib3.so", &events); 444 events.rbegin()->set_timestamp(700413248827794); 445 AddMmap(6531, 0x7f6867e00000, 0x200000, 0, "/anon_hugepage (deleted)", 446 &events); 447 events.rbegin()->set_timestamp(700413295816043); 448 AddMmap(6531, 0x7f6867c00000, 0x200000, 0, "/anon_hugepage (deleted)", 449 &events); 450 events.rbegin()->set_timestamp(700413305947499); 451 AddMmap(6531, 0x7f68663f8000, 0x1e00000, 0x7f68663f8000, "//anon", &events); 452 events.rbegin()->set_timestamp(700413306012797); 453 AddMmap(6531, 0x7f6866525000, 0x1a00000, 0x7f6866525000, "//anon", &events); 454 events.rbegin()->set_timestamp(700413312132909); 455 456 DeduceHugePages(&events); 457 CombineMappings(&events); 458 459 EXPECT_THAT( 460 events, 461 Pointwise( 462 Partially(EqualsProto()), 463 { 464 "mmap_event: { pgoff: 0 filename: 'main' }", 465 "mmap_event: { pgoff: 0 filename: 'ld.so' }", 466 "mmap_event: { pgoff: 0 filename: '[vdso]' }", 467 "mmap_event: { pgoff: 0 filename: 'lib1.so' }", 468 "mmap_event: { pgoff: 0 filename: 'lib2.so' }", 469 "mmap_event: { pgoff: 0 filename: 'lib3.so' }", 470 "mmap_event: { pgoff: 0 filename: '/anon_hugepage (deleted)' }", 471 "mmap_event: { pgoff: 0 filename: '/anon_hugepage (deleted)' }", 472 "mmap_event: { pgoff: 0x7f68663f8000 filename: '//anon' }", 473 "mmap_event: { pgoff: 0x7f6866525000 filename: '//anon' }", 474 })); 475 } 476 477 TEST(HugePageDeducer, Regression62446346) { 478 RepeatedPtrField<PerfEvent> events; 479 480 // Perf infers the filename is "file", but at offset 0 for 481 // hugepage-backed, anonymous mappings. 482 // 483 // vaddr start - vaddr end vaddr-size elf-offset 484 // [0x55a685bfb000-55a685dfb000) (0x200000) @ 0]: file 485 // [0x55a685dfb000-55a687c00000) (0x1e05000) @ 0x200000]: file 486 // [0x55a687c00000-55a6a5200000) (0x1d600000) @ 0]: file 487 // [0x55a6a5200000-55a6a6400000) (0x1200000) @ 0x1f605000]: file 488 // [0x55a6a6400000-55a6a6600000) (0x200000) @ 0]: file 489 // [0x55a6a6600000-55a6a8800000) (0x2200000) @ 0x20a05000]: file 490 // [0x55a6a8800000-55a6a8a00000) (0x200000) @ 0]: file 491 // [0x55a6a8a00000-55a6a90ca000) (0x6ca000) @ 0x22e05000]: file 492 // [0x55a6a90ca000-55a6a90cb000) (0x1000) @ 0x234cf000]: file 493 { 494 MMapEvent* ev = events.Add()->mutable_mmap_event(); 495 ev->set_pid(1234); 496 ev->set_start(0x55a685bfb000); 497 ev->set_len(0x200000); 498 ev->set_pgoff(0); 499 ev->set_filename("file"); 500 } 501 { 502 MMapEvent* ev = events.Add()->mutable_mmap_event(); 503 ev->set_pid(1234); 504 ev->set_start(0x55a685dfb000); 505 ev->set_len(0x1e05000); 506 ev->set_pgoff(0x200000); 507 ev->set_filename("file"); 508 } 509 { 510 MMapEvent* ev = events.Add()->mutable_mmap_event(); 511 ev->set_pid(1234); 512 ev->set_start(0x55a687c00000); 513 ev->set_len(0x1d600000); 514 ev->set_pgoff(0); 515 ev->set_filename("file"); 516 } 517 { 518 MMapEvent* ev = events.Add()->mutable_mmap_event(); 519 ev->set_pid(1234); 520 ev->set_start(0x55a6a5200000); 521 ev->set_len(0x1200000); 522 ev->set_pgoff(0x1f605000); 523 ev->set_filename("file"); 524 } 525 { 526 MMapEvent* ev = events.Add()->mutable_mmap_event(); 527 ev->set_pid(1234); 528 ev->set_start(0x55a6a6400000); 529 ev->set_len(0x200000); 530 ev->set_pgoff(0); 531 ev->set_filename("file"); 532 } 533 { 534 MMapEvent* ev = events.Add()->mutable_mmap_event(); 535 ev->set_pid(1234); 536 ev->set_start(0x55a6a6600000); 537 ev->set_len(0x2200000); 538 ev->set_pgoff(0x20a05000); 539 ev->set_filename("file"); 540 } 541 { 542 MMapEvent* ev = events.Add()->mutable_mmap_event(); 543 ev->set_pid(1234); 544 ev->set_start(0x55a6a8800000); 545 ev->set_len(0x200000); 546 ev->set_pgoff(0); 547 ev->set_filename("file"); 548 } 549 { 550 MMapEvent* ev = events.Add()->mutable_mmap_event(); 551 ev->set_pid(1234); 552 ev->set_start(0x55a6a8a00000); 553 ev->set_len(0x6ca000); 554 ev->set_pgoff(0x22e05000); 555 ev->set_filename("file"); 556 } 557 { 558 MMapEvent* ev = events.Add()->mutable_mmap_event(); 559 ev->set_pid(1234); 560 ev->set_start(0x55a6a90ca000); 561 ev->set_len(0x1000); 562 ev->set_pgoff(0x234cf000); 563 ev->set_filename("file"); 564 } 565 566 DeduceHugePages(&events); 567 CombineMappings(&events); 568 569 ASSERT_EQ(1, events.size()); 570 571 EXPECT_EQ("file", events[0].mmap_event().filename()); 572 EXPECT_EQ(0x55a685bfb000, events[0].mmap_event().start()); 573 EXPECT_EQ(0x55a6a90cb000 - 0x55a685bfb000, events[0].mmap_event().len()); 574 EXPECT_EQ(0, events[0].mmap_event().pgoff()); 575 } 576 577 } // namespace 578 } // namespace quipper 579