📄 mptrace.c
字号:
{ fprintf(stderr, "%s: Error reading file\n", progname); exit(EXIT_FAILURE); } bufferlen += n; /* If the buffer has not been completely filled then we zero the remaining * bytes. This is done simply to prevent running off the end of the buffer * if we are reading an LEB128 number from an unterminated file. */ if (l = MP_BUFFER_SIZE - bufferlen) memset(buffer + bufferlen, 0, l); return bufferlen;}/* Read an entry from the tracing output file. */staticvoidgetentry(void *d, size_t l, size_t n, int b){ size_t i, s; s = l * n; if (refill(s) < s) { fprintf(stderr, "%s: Error reading file\n", progname); exit(EXIT_FAILURE); } memcpy(d, bufferpos, s); bufferpos += s; bufferlen -= s; /* Byte-swap all of the elements if necessary. */ if (b != 0) for (i = 0; i < n; i++) { byteswap(d, l); d = (char *) d + l; }}/* Read a signed LEB128 number from the tracing output file. */staticlonggetsleb128(void){ size_t s; long n; /* Since the tracing output file must end with a magic sequence of 4 bytes, * it is not unreasonable to request at least 5 bytes from the input file * since an LEB128 number must be at least 1 byte. */ if (refill(5) < 5) { fprintf(stderr, "%s: Error reading file\n", progname); exit(EXIT_FAILURE); } n = __mp_decodesleb128(bufferpos, &s); bufferpos += s; bufferlen -= s; return n;}/* Read an unsigned LEB128 number from the tracing output file. */staticunsigned longgetuleb128(void){ size_t s; unsigned long n; /* Since the tracing output file must end with a magic sequence of 4 bytes, * it is not unreasonable to request at least 5 bytes from the input file * since an LEB128 number must be at least 1 byte. */ if (refill(5) < 5) { fprintf(stderr, "%s: Error reading file\n", progname); exit(EXIT_FAILURE); } n = __mp_decodeuleb128(bufferpos, &s); bufferpos += s; bufferlen -= s; return n;}/* Read a null-terminated string from the tracing output file. */staticchar *getstring(void){ static char b[1024]; size_t i; for (i = 0; i < sizeof(b); i++) { if (!refill(1)) { fprintf(stderr, "%s: Error reading file\n", progname); exit(EXIT_FAILURE); } b[i] = *bufferpos; bufferpos++; bufferlen--; if (b[i] == '\0') return b; } fprintf(stderr, "%s: Buffer overflow\n", progname); exit(EXIT_FAILURE); return NULL;}/* Read a (possibly cached) function name from the tracing output file. */staticchar *getfuncname(void){ char *s; int d; unsigned char i; if (!refill(1)) { fprintf(stderr, "%s: Error reading file\n", progname); exit(EXIT_FAILURE); } i = (unsigned char) *bufferpos; bufferpos++; bufferlen--; if (i == 0) return NULL; d = ((i & 0x80) != 0); i = (i & 0x7F) - 1; if (d != 0) { s = getstring(); if (funcnames[i] != NULL) free(funcnames[i]); if ((funcnames[i] = (char *) malloc(strlen(s) + 1)) == NULL) { fprintf(stderr, "%s: Out of memory\n", progname); exit(EXIT_FAILURE); } strcpy(funcnames[i], s); } return funcnames[i];}/* Read a (possibly cached) file name from the tracing output file. */staticchar *getfilename(void){ char *s; int d; unsigned char i; if (!refill(1)) { fprintf(stderr, "%s: Error reading file\n", progname); exit(EXIT_FAILURE); } i = (unsigned char) *bufferpos; bufferpos++; bufferlen--; if (i == 0) return NULL; d = ((i & 0x80) != 0); i = (i & 0x7F) - 1; if (d != 0) { s = getstring(); if (filenames[i] != NULL) free(filenames[i]); if ((filenames[i] = (char *) malloc(strlen(s) + 1)) == NULL) { fprintf(stderr, "%s: Out of memory\n", progname); exit(EXIT_FAILURE); } strcpy(filenames[i], s); } return filenames[i];}/* Read the current event's thread id, source function name, file name and line * number from the tracing output file. */staticvoidgetsource(unsigned long *i, char **s, char **t, unsigned long *u){ char *a; *s = *t = NULL; *i = *u = 0; /* From mpatrol release 1.4.5, the thread id, source function name, file * name and line number for each allocation, reallocation and deallocation * is also written to the tracing output file. */ if (version >= 10405) { *i = getuleb128(); *s = getfuncname(); *t = getfilename(); *u = getuleb128(); }}#if MP_GUI_SUPPORT/* Refresh the memory display window. */staticvoidredrawmemory(Widget w, XtPointer d, XmDrawingAreaCallbackStruct *s){ XCopyArea(appdisplay, pixmap, s->window, ungc, 0, 0, width - 1, height - 1, 0, 0);}#endif /* MP_GUI_SUPPORT */#if MP_GUI_SUPPORT/* Update the memory display window. */staticvoiddrawmemory(void *a, size_t s, GC g){ unsigned long i, j, l, u, x1, x2, y1, y2; if (a < addrbase) return; l = (unsigned long) a - (unsigned long) addrbase; u = l + s - 1; l /= addrscale; u /= addrscale; x1 = l % width; y1 = l / width; x2 = u % width; y2 = u / width; if (y2 >= height) return; if (y1 == y2) { XDrawLine(appdisplay, XtWindow(drawwidget), g, x1, y1, x2, y1); XDrawLine(appdisplay, pixmap, g, x1, y1, x2, y1); } else { for (i = x1, j = y1; j < y2; i = 0, j++) { XDrawLine(appdisplay, XtWindow(drawwidget), g, i, j, width - 1, j); XDrawLine(appdisplay, pixmap, g, i, j, width - 1, j); } XDrawLine(appdisplay, XtWindow(drawwidget), g, 0, y2, x2, y2); XDrawLine(appdisplay, pixmap, g, 0, y2, x2, y2); } /* We just do a busy loop here since sleep() does not have enough accuracy * and usleep() is only available on a small number of platforms. We need * to modify the global variable "delay" in case some clever compilers * optimise away the pointless modification of a local variable. */ if (delay > 0) { i = delay; for (delay *= 100000; delay > 0; delay--); delay = i; }}#endif /* MP_GUI_SUPPORT *//* Divide two integers, rounding to the nearest integer. */staticunsigned longrounddivide(unsigned long n, unsigned long d){ unsigned long q; double r; if (d == 0) return 0; q = n / d; r = (double) (n - (q * d)) / (double) d; if ((r < 0.5) || ((0.5 <= r) && (r <= 0.5) && !(q & 1))) return q; return q + 1;}/* Display a size in bytes. */staticvoidprintsize(size_t l){ fprintf(stdout, "%lu byte", l); if (l != 1) fputc('s', stdout);}/* Display source-level information for a given event. */staticvoidprintsource(unsigned long i, char *s, char *t, unsigned long u){ if ((i != 0) || (s != NULL) || ((t != NULL) && (u != 0))) { fputs(" ", stdout); if (i != 0) fprintf(stdout, " thread %lu", i); if (s != NULL) fprintf(stdout, " in %s", s); if ((t != NULL) && (u != 0)) fprintf(stdout, " at %s line %lu", t, u); fputc('\n', stdout); }}/* Display the statistics gathered from the tracing output file. */staticvoidshowstats(void){ fputs("memory allocation tracing statistics\n", stdout); fputs("------------------------------------\n", stdout); fprintf(stdout, "allocated: %lu (", stats.acount); printsize(stats.atotal); fprintf(stdout, ")\nfreed: %lu (", stats.fcount); printsize(stats.ftotal); fprintf(stdout, ")\nunfreed: %lu (", stats.acount - stats.fcount); printsize(stats.atotal - stats.ftotal); fprintf(stdout, ")\npeak: %lu (", stats.pcount); printsize(stats.ptotal); fprintf(stdout, ")\nreserved: %lu (", stats.rcount); printsize(stats.rtotal); fprintf(stdout, ")\ninternal: %lu (", stats.icount); printsize(stats.itotal); fprintf(stdout, ")\ntotal: %lu (", stats.rcount + stats.icount); printsize(stats.rtotal + stats.itotal); fputs(")\n\n", stdout); fputs("smallest size: ", stdout); printsize(stats.lsize); fputs("\nlargest size: ", stdout); printsize(stats.usize); fputs("\naverage size: ", stdout); printsize(rounddivide(stats.atotal, stats.acount)); fputc('\n', stdout);}/* Read an event from the tracing output file. */#if MP_GUI_SUPPORTstaticintreadevent(XtPointer p)#else /* MP_GUI_SUPPORT */staticintreadevent(void)#endif /* MP_GUI_SUPPORT */{ char s[4]; allocation *f; char *g, *h; void *a; size_t i, l, m; unsigned long n, t, u; if (refill(1)) switch (*bufferpos) { case 'A': bufferpos++; bufferlen--; currentevent++; n = getuleb128(); a = (void *) getuleb128(); l = getuleb128(); getsource(&t, &g, &h, &u); f = newalloc(n, currentevent, a, l); stats.acount++; stats.atotal += l; if (stats.pcount < stats.acount - stats.fcount) stats.pcount = stats.acount - stats.fcount; if (stats.ptotal < stats.atotal - stats.ftotal) stats.ptotal = stats.atotal - stats.ftotal; if ((stats.lsize == 0) || (stats.lsize > l)) stats.lsize = l; if (stats.usize < l) stats.usize = l; if (verbose) { fprintf(stdout, "%6lu alloc %6lu " MP_POINTER " %8lu" " %6lu %8lu\n", currentevent, n, a, l, stats.acount - stats.fcount, stats.atotal - stats.ftotal); if (displaysource) printsource(t, g, h, u); } if (hatffile != NULL) fprintf(hatffile, "1 %lu 0x%lx\n", l, a); if (f->entry != NULL) { if ((m = slotentry(f)) > maxslots) maxslots = m; fprintf(simfile, " {%lu, %lu, 0},\n", m, l); }#if MP_GUI_SUPPORT if (usegui) { if (addrbase == NULL) addrbase = (void *) __mp_rounddown((unsigned long) a, 1024); drawmemory(a, l, algc); return 0; }#endif /* MP_GUI_SUPPORT */ return 1; case 'R': bufferpos++; bufferlen--; currentevent++; n = getuleb128(); a = (void *) getuleb128(); l = getuleb128(); getsource(&t, &g, &h, &u); if (f = (allocation *) __mp_search(alloctree.root, n)) { if (f->time != 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -