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