1 #include <algorithm> 2 #include <cstdint> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <iostream> 7 8 constexpr size_t num_pages = 7; 9 constexpr size_t accessible_pages[] = {0, 2, 4, 6}; 10 11 bool 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 use 18 // this to test lldb's ability to skip over inaccessible blocks. 19 #ifdef _WIN32 20 #include "Windows.h" 21 22 int getpagesize() { 23 SYSTEM_INFO system_info; 24 GetSystemInfo(&system_info); 25 return system_info.dwPageSize; 26 } 27 28 char *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 #else 49 #include "sys/mman.h" 50 #include "unistd.h" 51 52 char *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 #endif 72 73 int 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 memory 78 mem_with_holes + 2 * pagesize, // After a hole 79 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 block 82 mem_with_holes + 7 * pagesize - 7, // End of memory 83 }; 84 for (char *p : positions) 85 strcpy(p, "needle"); 86 87 return 0; // break here 88 } 89