89 lines · cpp
1#include <algorithm>2#include <cstdint>3#include <cstdio>4#include <cstdlib>5#include <cstring>6#include <iostream>7 8constexpr size_t num_pages = 7;9constexpr size_t accessible_pages[] = {0, 2, 4, 6};10 11bool is_accessible(size_t page) {12 return std::find(std::begin(accessible_pages), std::end(accessible_pages),13 page) != std::end(accessible_pages);14}15 16// allocate_memory_with_holes returns a pointer to `num_pages` pages of memory,17// where some of the pages are inaccessible (even to debugging APIs). We use18// this to test lldb's ability to skip over inaccessible blocks.19#ifdef _WIN3220#include "Windows.h"21 22int getpagesize() {23 SYSTEM_INFO system_info;24 GetSystemInfo(&system_info);25 return system_info.dwPageSize;26}27 28char *allocate_memory_with_holes() {29 int pagesize = getpagesize();30 void *mem =31 VirtualAlloc(nullptr, num_pages * pagesize, MEM_RESERVE, PAGE_NOACCESS);32 if (!mem) {33 std::cerr << std::system_category().message(GetLastError()) << std::endl;34 exit(1);35 }36 char *bytes = static_cast<char *>(mem);37 for (size_t page = 0; page < num_pages; ++page) {38 if (!is_accessible(page))39 continue;40 if (!VirtualAlloc(bytes + page * pagesize, pagesize, MEM_COMMIT,41 PAGE_READWRITE)) {42 std::cerr << std::system_category().message(GetLastError()) << std::endl;43 exit(1);44 }45 }46 return bytes;47}48#else49#include "sys/mman.h"50#include "unistd.h"51 52char *allocate_memory_with_holes() {53 int pagesize = getpagesize();54 void *mem = mmap(nullptr, num_pages * pagesize, PROT_READ | PROT_WRITE,55 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);56 if (mem == MAP_FAILED) {57 perror("mmap");58 exit(1);59 }60 char *bytes = static_cast<char *>(mem);61 for (size_t page = 0; page < num_pages; ++page) {62 if (is_accessible(page))63 continue;64 if (munmap(bytes + page * pagesize, pagesize) != 0) {65 perror("munmap");66 exit(1);67 }68 }69 return bytes;70}71#endif72 73int main(int argc, char const *argv[]) {74 char *mem_with_holes = allocate_memory_with_holes();75 int pagesize = getpagesize();76 char *positions[] = {77 mem_with_holes, // Beginning of memory78 mem_with_holes + 2 * pagesize, // After a hole79 mem_with_holes + 2 * pagesize +80 pagesize / 2, // Middle of a block, after an existing match.81 mem_with_holes + 5 * pagesize - 7, // End of a block82 mem_with_holes + 7 * pagesize - 7, // End of memory83 };84 for (char *p : positions)85 strcpy(p, "needle");86 87 return 0; // break here88}89