📄 dmalloc.c
字号:
sprintf(b + n, "\\%03o", p[i]); n += 4; } else b[n++] = p[i]; b[n] = '\0'; return b;}/* The callback function that is called by __mp_iterate() for every heap * allocation that has changed since a specified heap event. */staticintcallback(MP_CONST void *p, void *t){ char b[1024]; char s[81]; listinfo *i; __mp_allocinfo d; if (!__mp_info(p, &d)) return 0; i = (listinfo *) t; if ((d.freed && i->freed) || (!d.freed && i->unfreed)) { if (d.file != NULL) { i->kcount++; i->ktotal += d.size; } else { i->ucount++; i->utotal += d.size; } if ((d.file != NULL) || !(malloc_flags & DMALLOC_LOG_KNOWN)) { if (d.file != NULL) { if (i->details) sprintf(b, "%s:%lu", d.file, d.line); __mp_addallocentry(d.file, d.line, d.size); if (d.freed) __mp_addfreeentry(d.file, d.line, d.size); } else if (d.func != NULL) { if (i->details) strcpy(b, d.func); __mp_addallocentry(d.func, 0, d.size); if (d.freed) __mp_addfreeentry(d.func, 0, d.size); } else if (d.stack == NULL) { if (i->details) strcpy(b, "unknown"); __mp_addallocentry(NULL, 0, d.size); if (d.freed) __mp_addfreeentry(NULL, 0, d.size); } else if (d.stack->name != NULL) { if (i->details) strcpy(b, d.stack->name); __mp_addallocentry(d.stack->name, 0, d.size); if (d.freed) __mp_addfreeentry(d.stack->name, 0, d.size); } else { if (i->details) sprintf(b, "ra=%#lx", d.stack->addr); __mp_addallocentry(NULL, (unsigned long) d.stack->addr, d.size); if (d.freed) __mp_addfreeentry(NULL, (unsigned long) d.stack->addr, d.size); } if (i->details) { __mpt_dmallocmessage(" %s: '%#lx' (%lu byte%s) from '%s'\n", d.freed ? "freed" : "not freed", d.block, d.size, (d.size == 1) ? "" : "s", b); if (malloc_flags & DMALLOC_LOG_NONFREE_SPACE) __mpt_dmallocmessage(" dump of '%#lx': '%s'\n", d.block, bytestring(s, 20, (char *) d.block, d.size)); } } return 1; } return 0;}/* Terminate the dmalloc module. */void__mpt_dmallocshutdown(void){ time_t t; unsigned long h, m, s; if (!malloc_initialised) return; __mp_prologue(old_prologue); __mp_epilogue(old_epilogue); if ((t = time(NULL)) != (time_t) -1) { s = (unsigned long) t - (unsigned long) malloc_time; h = s / 3600; m = (s / 60) % 60; s %= 60; } else { t = (time_t) 0; h = m = s = 0; } __mpt_dmallocmessage("ending time = %lu, elapsed since start = " "%lu:%02lu:%02lu\n\n", (unsigned long) t, h, m, s); malloc_initialised = 0;}/* Check the integrity of the memory allocation containing a given pointer, * or the entire heap if the pointer is NULL. */int__mpt_dmallocverify(MP_CONST void *p, MP_CONST char *s, MP_CONST char *t, unsigned long u){ __mp_allocinfo i; int r; if (!malloc_initialised) __mp_init_dmalloc(); if ((p == NULL) || (__mp_info(p, &i) && (p == i.block) && i.allocated && !i.freed)) r = 1; else r = 0; __mp_checkheap(s, t, u); return r;}/* Set the library debug flags and return the previous setting. */unsigned long__mpt_dmallocdebug(unsigned long f){ unsigned long r; if (!malloc_initialised) __mp_init_dmalloc(); r = malloc_flags; malloc_flags = f; setoptions(); return r;}/* Return the current library debug flags. */unsigned long__mpt_dmallocdebugcurrent(void){ if (!malloc_initialised) __mp_init_dmalloc(); return malloc_flags;}/* Examine a pointer in the heap and return information about the memory * allocation it belongs to. */int__mpt_dmallocexamine(MP_CONST void *p, size_t *l, char **t, unsigned long *u, void **a){ __mp_allocinfo i; if (!malloc_initialised) __mp_init_dmalloc(); if (__mp_info(p, &i) && i.allocated) { if (l != NULL) *l = i.size; if (t != NULL) *t = i.file; if (u != NULL) *u = i.line; if (a != NULL) if (i.stack != NULL) *a = i.stack->addr; else *a = NULL; return 1; } return 0;}/* Write a message to the log file. */void__mpt_dmallocmessage(MP_CONST char *s, ...){ va_list v; if (!malloc_initialised) __mp_init_dmalloc(); va_start(v, s); __mpt_dmallocvmessage(s, v); va_end(v);}/* Write a message to the log file. */void__mpt_dmallocvmessage(MP_CONST char *s, va_list v){ char b[1024]; char m[64]; char *c, *p;#if LOG_TIME_NUMBER || LOG_CTIME_STRING time_t t;#endif /* LOG_TIME_NUMBER && LOG_CTIME_STRING */ size_t l; if (!malloc_initialised) __mp_init_dmalloc(); l = 0;#if LOG_TIME_NUMBER || LOG_CTIME_STRING if ((t = time(NULL)) == (time_t) -1) t = (time_t) 0;#endif /* LOG_TIME_NUMBER && LOG_CTIME_STRING */#if LOG_TIME_NUMBER sprintf(m + l, "%lu: ", (unsigned long) t); l += strlen(m + l);#endif /* LOG_TIME_NUMBER */#if LOG_CTIME_STRING sprintf(m + l, "%24.24s: ", ctime(&t)); l += strlen(m + l);#endif /* LOG_CTIME_STRING */#if LOG_ITERATION_COUNT sprintf(m + l, "%lu: ", __mp_snapshot()); l += strlen(m + l);#endif /* LOG_ITERATION_COUNT */ m[l] = '\0'; vsprintf(b, s, v); for (c = b; p = strchr(c, '\n'); c = p + 1) { *p = '\0'; if (*c != '\0') { __mp_printf("%s%s\n", m, c); if (malloc_flags & DMALLOC_PRINT_MESSAGES) fprintf(stderr, "%s%s\n", m, c); } else { __mp_printf("\n"); if (malloc_flags & DMALLOC_PRINT_MESSAGES) fputc('\n', stderr); } } if (*c != '\0') { __mp_printf("%s%s\n", m, c); if (malloc_flags & DMALLOC_PRINT_MESSAGES) fprintf(stderr, "%s%s\n", m, c); }}/* Register a callback function that will be called for each memory * allocation event. */void__mpt_dmalloctrack(dmalloc_track_t h){ if (!malloc_initialised) __mp_init_dmalloc(); malloc_tracker = h;}/* Log the details of any changes to the heap since a certain point. */void__mpt_dmalloclogchanged(unsigned long m, int u, int f, int d){ char *s; listinfo i; int t; if (!malloc_initialised) __mp_init_dmalloc(); if ((u != 0) && (f != 0)) s = "not-freed and freed"; else if (u != 0) s = "not-freed"; else if (f != 0) s = "freed"; else return; __mpt_dmallocmessage("dumping %s pointers changed since %lu:\n", s, m); i.kcount = i.ktotal = 0; i.ucount = i.utotal = 0; i.unfreed = (u != 0) ? 1 : 0; i.freed = (f != 0) ? 1 : 0; i.details = (d != 0) ? 1 : 0; t = __mp_stopleaktable(); __mp_clearleaktable(); __mp_iterate(callback, &i, m); if (i.unfreed) { __mp_printf("\n"); __mp_leaktable(0, MP_LT_UNFREED, 0); } if (i.freed) { __mp_printf("\n"); __mp_leaktable(0, MP_LT_FREED, 0); } __mp_clearleaktable(); if (t != 0) __mp_startleaktable(); if ((i.kcount != 0) || (i.ucount != 0)) { __mpt_dmallocmessage("\n"); if (i.kcount != 0) __mpt_dmallocmessage(" known memory: %lu pointer%s, %lu byte%s\n", i.kcount, (i.kcount == 1) ? "" : "s", i.ktotal, (i.ktotal == 1) ? "" : "s"); if (i.ucount != 0) __mpt_dmallocmessage(" unknown memory: %lu pointer%s, %lu byte%s\n", i.ucount, (i.ucount == 1) ? "" : "s", i.utotal, (i.utotal == 1) ? "" : "s"); } __mpt_dmallocmessage("\n");}/* Return the string associated with a certain error value. */MP_CONST char *__mpt_dmallocstrerror(__mp_errortype e){ MP_CONST char *s; if (!malloc_initialised) __mp_init_dmalloc(); if ((s = __mp_strerror(e)) == NULL) s = "errno value is not valid"; return s;}/* Initialise the dmalloc module. */void__mp_init_dmalloc(void){ char *t; if (malloc_initialised) return; malloc_initialised = 1; if ((malloc_time = time(NULL)) == (time_t) -1) malloc_time = (time_t) 0; malloc_flags = 0; malloc_start = 0; malloc_interval = 1; malloc_tracker = NULL; dmalloc_logpath = NULL; dmalloc_address = NULL; dmalloc_address_count = 0; readoptions(); setoptions(); __mp_atexit(__mpt_dmallocshutdown); if (!__mp_getoption(MP_OPT_LOGFILE, (unsigned long *) &t) || (t == NULL)) t = "stderr"; __mpt_dmallocmessage("Dmalloc version '%lu.%lu.%lu' (mpatrol)\n", DMALLOC_VERSION_MAJOR, DMALLOC_VERSION_MINOR, DMALLOC_VERSION_PATCH); __mpt_dmallocmessage("flags = %#lx, logfile '%s'\n", malloc_flags, t); __mpt_dmallocmessage("interval = %lu, addr = %#lx, seen # = %lu\n", malloc_interval, dmalloc_address, dmalloc_address_count); __mpt_dmallocmessage("starting time = %lu\n\n", (unsigned long) malloc_time); old_prologue = __mp_prologue(prologue); old_epilogue = __mp_epilogue(epilogue);}#ifdef __cplusplus}#endif /* __cplusplus */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -