📄 memcheck.c
字号:
else { retval = 0; } } else { retval = 0; } return retval;}static void memcheck_place_sentry(struct meminfo *mem){ if(mem->sentry != NULL) { /* Plant sentry. */ /* Use memcpy instead of cast+assignment * * due to possible mis-alignment. */ memcpy(mem->sentry, &memcheck_sentry, sizeof(memcheck_sentry)); }}static size_t memcheck_user_pages(size_t size){ size_t upages; if(memcheck_config.underruns && size % memcheck_pagesize != 0) /* Allow space on beginning(end) for sentry. */ { upages = (size - 1 + sizeof(long)) / memcheck_pagesize + 1; } else /* Sentry can back onto info page, or * * Requested size is _exact_ pagesize, no sentry needed. */ { upages = (size - 1) / memcheck_pagesize + 1; } return upages;}static void memcheck_setup(struct meminfo *mem, size_t pages, size_t size){ size_t upages; mem->pages = pages; mem->size = size; /* Checking for underruns, so set ptr at beginning of data page. */ if(memcheck_config.underruns) { mem->ptr = (char *)mem + memcheck_pagesize; if(size % memcheck_pagesize != 0) { mem->sentry = (((char *)mem->ptr) + size); } else { mem->sentry = NULL; } } else /* Checking for overruns, so set ptr end at end of last page. */ { upages = memcheck_user_pages(size); mem->ptr = (char *)mem + (1 + upages) * memcheck_pagesize - size; if(size % memcheck_pagesize != 0) { mem->sentry = (((char *)mem->ptr) - sizeof(long)); } else { mem->sentry = NULL; } }}static void memcheck_delete(struct meminfo *mem, const struct caller *caller){ if(mem != NULL) { if(memcheck_head == mem) { memcheck_head = mem->next; } if(mem->next != NULL) { mprotect(mem->next, memcheck_pagesize, PROT_READ | PROT_WRITE); mem->next->prev = mem->prev; mprotect(mem->next, memcheck_pagesize, PROT_NONE); } if(mem->prev != NULL) { mprotect(mem->prev, memcheck_pagesize, PROT_READ | PROT_WRITE); mem->prev->next = mem->next; mprotect(mem->prev, memcheck_pagesize, PROT_NONE); } memcpy(&mem->freed, caller, sizeof(mem->freed)); mem->inuse = 0; }}static void memcheck_update(struct meminfo *mem, const struct caller *caller){ if(mem->count < MAX_REALLOC_CALL) { memcpy(&mem->realloc[mem->count], caller, sizeof(mem->realloc[0])); } else { memcpy(&mem->realloc2[mem->count - MAX_REALLOC_CALL], caller, sizeof(mem->realloc2[0])); } ++mem->count;}static void memcheck_insert(struct meminfo *mem, const struct caller *caller){ mem->next = memcheck_head; memcheck_head = mem; if(mem->next != NULL) { mprotect(mem->next, memcheck_pagesize, PROT_READ | PROT_WRITE); mem->next->prev = mem; mprotect(mem->next, memcheck_pagesize, PROT_NONE); } memcpy(&mem->alloc, caller, sizeof(mem->alloc)); mem->inuse = 1;}static void memcheck_log(int level, int flush, const char *fmt, ...){ char buffer[256]; va_list ap; size_t len; if(level <= memcheck_config.level) { va_start(ap, fmt); vsprintf(buffer, fmt, ap); va_end(ap); len = strlen(buffer); if(memcheck_file == -1) { unlink("memcheck.log"); memcheck_file = open("memcheck.log", O_CREAT | O_RDWR, 0666); if(memcheck_file == -1) { memcheck_error("open"); memcheck_file = -2; } } if(memcheck_file >= 0) { if(write(memcheck_file, buffer, len) < 0) { memcheck_error("write"); } if(flush) {#ifdef HAVE_FSYNC if(fsync(memcheck_file) < 0) { memcheck_error("fsync"); }#endif } } }}static void memcheck_log_trace(int level, int flush, const char *message, const struct caller *caller){ if(caller != NULL) { if(caller->file != NULL) { memcheck_log(level, flush, "\t%s by %s at (%s:%d) [%p]\n", message, memcheck_functions[caller->func].name, caller->file, caller->line, caller->addr); } else { memcheck_log(level, flush, "\t%s by %s [%p]\n", message, memcheck_functions[caller->func].name, caller->addr); }#ifdef HAVE_BACKTRACE if(memcheck_config.backtrace) { memcheck_get_symbols(level, flush, &caller->trace); }#endif }}static void memcheck_history(int level, int flush, struct meminfo *mem){ size_t i; if(mem != NULL) { if(mem->alloc.func) { memcheck_log_trace(level, flush, "first allocated", &mem->alloc); } for(i = 0; i < mem->count; ++i) { if(i < MAX_REALLOC_CALL) { if(mem->realloc[i].func) { memcheck_log_trace(level, flush, "reallocated", &mem->realloc[i]); } } else { if(mem->realloc2[i - MAX_REALLOC_CALL].func) { memcheck_log_trace(level, flush, "reallocated", &mem->realloc2[i - MAX_REALLOC_CALL]); } } } if(mem->freed.func) { memcheck_log_trace(level, flush, "first freed", &mem->freed); } }}static void memcheck_log_info(int level, int flush, const char *message, const void *ptr, const struct caller *caller){ if(caller != NULL) { if(caller->file != NULL) { memcheck_log(level, flush, "%s pointer %p in %s at (%s:%d) [%p]\n", message, ptr, memcheck_functions[caller->func].name, caller->file, caller->line, caller->addr); } else { memcheck_log(level, flush, "%s pointer %p in %s at [%p]\n", message, ptr, memcheck_functions[caller->func].name, caller->addr); } }}static int memcheck_protect(struct meminfo *mem, int prot){ size_t upages; size_t pages; size_t size; int retval; if(mem != NULL) { if(mprotect(mem, memcheck_pagesize, PROT_READ | PROT_WRITE)) { memcheck_error("mprotect"); retval = 1; } else { mem->prot = prot; pages = mem->pages; size = mem->size; if(mprotect(mem, memcheck_pagesize * pages, PROT_NONE)) { memcheck_error("mprotect"); retval = 1; } else { if(size > 0 && prot != PROT_NONE) { upages = memcheck_user_pages(size); if(mprotect((char *)mem + memcheck_pagesize, upages * memcheck_pagesize, prot)) { memcheck_error("mprotect"); retval = 1; } else { retval = 0; } } else { retval = 0; } } } } else { retval = 0; } return retval;}static int memcheck_unprotect(struct meminfo *mem){ int retval; if(mem != NULL) { if(mprotect(mem, memcheck_pagesize, PROT_READ | PROT_WRITE)) { memcheck_error("mprotect"); retval = 1; } else { if(mem->pages > 1) { if(mprotect((char *)mem + memcheck_pagesize, (mem->pages - 1) * memcheck_pagesize, PROT_READ | PROT_WRITE)) { memcheck_error("mprotect"); retval = 1; } else { retval = 0; } } else { retval = 0; } } } else { retval = 0; } return retval;}static void memcheck_put(struct meminfo *mem){ if(mem != NULL) { if(memcheck_config.reuse) { if(munmap(mem, mem->pages * memcheck_pagesize)) { memcheck_error("munmap"); } } else { memcheck_protect(mem, PROT_NONE); } }}static struct meminfo *memcheck_get(size_t pages){ struct meminfo *mem; int flags; if(memcheck_config.limit == 0 || memcheck_config.limit - memcheck_pages_in_use >= pages) { memcheck_pages_in_use += pages; flags = MAP_PRIVATE;#ifdef MAP_ANONYMOUS flags |= MAP_ANONYMOUS;#else if(memcheck_devzero == -1) { memcheck_devzero = open("/dev/zero", O_RDWR); } if(memcheck_devzero >= 0)#endif { if((mem = (void *)mmap(NULL, pages * memcheck_pagesize, PROT_READ | PROT_WRITE, flags, memcheck_devzero, 0)) != MAP_FAILED) { memset(mem, 0, memcheck_pagesize); if(pages > 1) { memset((char *)mem + memcheck_pagesize, 0xa5, (pages - 1) * memcheck_pagesize); } } else { errno = ENOMEM; mem = NULL; } }#ifndef MAP_ANONYMOUS else { if(memcheck_devzero == -1) { memcheck_devzero = -2; memcheck_error("open");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -