#include #include #include #include #include #include constexpr size_t num_pages = 7; constexpr size_t accessible_pages[] = {0, 2, 4, 6}; bool is_accessible(size_t page) { return std::find(std::begin(accessible_pages), std::end(accessible_pages), page) != std::end(accessible_pages); } // allocate_memory_with_holes returns a pointer to `num_pages` pages of memory, // where some of the pages are inaccessible (even to debugging APIs). We use // this to test lldb's ability to skip over inaccessible blocks. #ifdef _WIN32 #include "Windows.h" int getpagesize() { SYSTEM_INFO system_info; GetSystemInfo(&system_info); return system_info.dwPageSize; } char *allocate_memory_with_holes() { int pagesize = getpagesize(); void *mem = VirtualAlloc(nullptr, num_pages * pagesize, MEM_RESERVE, PAGE_NOACCESS); if (!mem) { std::cerr << std::system_category().message(GetLastError()) << std::endl; exit(1); } char *bytes = static_cast(mem); for (size_t page = 0; page < num_pages; ++page) { if (!is_accessible(page)) continue; if (!VirtualAlloc(bytes + page * pagesize, pagesize, MEM_COMMIT, PAGE_READWRITE)) { std::cerr << std::system_category().message(GetLastError()) << std::endl; exit(1); } } return bytes; } #else #include "sys/mman.h" #include "unistd.h" char *allocate_memory_with_holes() { int pagesize = getpagesize(); void *mem = mmap(nullptr, num_pages * pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (mem == MAP_FAILED) { perror("mmap"); exit(1); } char *bytes = static_cast(mem); for (size_t page = 0; page < num_pages; ++page) { if (is_accessible(page)) continue; if (munmap(bytes + page * pagesize, pagesize) != 0) { perror("munmap"); exit(1); } } return bytes; } #endif int main(int argc, char const *argv[]) { char *mem_with_holes = allocate_memory_with_holes(); int pagesize = getpagesize(); char *positions[] = { mem_with_holes, // Beginning of memory mem_with_holes + 2 * pagesize, // After a hole mem_with_holes + 2 * pagesize + pagesize / 2, // Middle of a block, after an existing match. mem_with_holes + 5 * pagesize - 7, // End of a block mem_with_holes + 7 * pagesize - 7, // End of memory }; for (char *p : positions) strcpy(p, "needle"); return 0; // break here }