/* Credits to author Filip Strömbäck * * Additional comment by klaar36: * The three programs debug1, debug2 and debug3 contain common bugs * triggering "undefined behaviour". * "Undefined behaviour" is normally just that: you can not in advance * determine the outcome. * - sometimes the program may appear to work despite the bug * - sometimes the program produce invalid "random" output (junk) * - sometimes the program crash with "segmentation fault" or the like * * The code in this file implement custom version of malloc and free * that make sure each bug will generate a segmentation fault, so that * we may investigate and debug them. * * This is not general purpose code, but tailored to the limited needs * of those three specific programs. * * Read The Fantastic Manual (RTFM) to get a grasp of what is really * done, and you may learn one or two things about system calls and * operating system memory management in the process. */ #include #include #include struct alloc_info { void *page_base; size_t alloc_size; }; size_t align(size_t sz, size_t alignment) { return (sz + alignment - 1) & ~(alignment - 1); } void *malloc(size_t size) { // Minimum alignment for data structures. size = align(size, 32); size_t pagesize = sysconf(_SC_PAGE_SIZE); size_t round_size = align(size + sizeof(struct alloc_info), pagesize) + pagesize; void *mem = mmap(NULL, round_size + pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); // Add a "guard page" that will fault. mprotect((char *)mem + round_size, pagesize, PROT_NONE); memset(mem, 0xCC, round_size); struct alloc_info *info = (void *)((char *)mem + round_size - size - sizeof(struct alloc_info)); info->page_base = mem; info->alloc_size = round_size; return (char *)info + sizeof(struct alloc_info); } void free(void *mem) { struct alloc_info *info = (void *)((char *)mem - sizeof(struct alloc_info)); munmap(info->page_base, info->alloc_size); }