📄 mptrace.c
字号:
fprintf(stderr, "%s: Allocation index `%lu' has already " "been freed\n", progname, n); stats.acount++; stats.atotal += l; stats.fcount++; stats.ftotal += f->size; 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 realloc %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, "4 %lu 0x%lx 0x%lx\n", l, f->addr, a); if (f->entry != NULL) { m = slotentry(f); fprintf(simfile, " {%lu, %lu, 1},\n", m, l); }#if MP_GUI_SUPPORT if (usegui) { drawmemory(f->addr, f->size, frgc); drawmemory(a, l, algc); }#endif /* MP_GUI_SUPPORT */ f->addr = a; f->size = l; } else fprintf(stderr, "%s: Unknown allocation index `%lu'\n", progname, n);#if MP_GUI_SUPPORT if (usegui) return 0;#endif /* MP_GUI_SUPPORT */ return 1; case 'F': bufferpos++; bufferlen--; currentevent++; n = getuleb128(); getsource(&t, &g, &h, &u); if (f = (allocation *) __mp_search(alloctree.root, n)) { if (f->time != 0) fprintf(stderr, "%s: Allocation index `%lu' has already " "been freed\n", progname, n); f->time = currentevent - f->event; stats.fcount++; stats.ftotal += f->size; if (verbose) { fprintf(stdout, "%6lu free %6lu " MP_POINTER " %8lu " "%6lu %6lu %8lu\n", currentevent, n, f->addr, f->size, f->time, stats.acount - stats.fcount, stats.atotal - stats.ftotal); if (displaysource) printsource(t, g, h, u); } if (hatffile != NULL) fprintf(hatffile, "2 0x%lx\n", f->addr); if (f->entry != NULL) { fprintf(simfile, " {%lu, 0, 0},\n", slotentry(f)); __mp_freeslot(&table, f->entry); f->entry = NULL; }#if MP_GUI_SUPPORT if (usegui) drawmemory(f->addr, f->size, frgc);#endif /* MP_GUI_SUPPORT */ } else fprintf(stderr, "%s: Unknown allocation index `%lu'\n", progname, n);#if MP_GUI_SUPPORT if (usegui) return 0;#endif /* MP_GUI_SUPPORT */ return 1; case 'H': bufferpos++; bufferlen--; a = (void *) getuleb128(); l = getuleb128(); if (verbose) fprintf(stdout, " reserve " MP_POINTER " %8lu\n", a, l); stats.rcount++; stats.rtotal += l;#if MP_GUI_SUPPORT if (usegui) { if (addrbase == NULL) addrbase = (void *) __mp_rounddown((unsigned long) a, 1024); drawmemory(a, l, frgc); return 0; }#endif /* MP_GUI_SUPPORT */ return 1; case 'I': bufferpos++; bufferlen--; a = (void *) getuleb128(); l = getuleb128(); if (verbose) fprintf(stdout, " internal " MP_POINTER " %8lu\n", a, l); stats.icount++; stats.itotal += l;#if MP_GUI_SUPPORT if (usegui) { drawmemory(a, l, ingc); return 0; }#endif /* MP_GUI_SUPPORT */ return 1; default: break; } if ((hatffile != NULL) && (hatffile != stdout) && (hatffile != stderr)) fclose(hatffile); if (simfile != NULL) { fputs(" {0, 0, 0}\n};\n\n\n", simfile); fputs("int main(void)\n{\n", simfile); fprintf(simfile, " void *p[%lu];\n", maxslots); fputs(" event *e;\n\n", simfile); fputs(" for (e = events; e->index != 0; e++)\n", simfile); fputs(" if (e->resize)\n", simfile); fputs(" {\n", simfile); fputs(" if ((p[e->index - 1] = realloc(p[e->index - 1], " "e->size)) == NULL)\n", simfile); fputs(" {\n", simfile); fputs(" fputs(\"out of memory\\n\", stderr);\n", simfile); fputs(" exit(EXIT_FAILURE);\n", simfile); fputs(" }\n", simfile); fputs(" }\n", simfile); fputs(" else if (e->size == 0)\n", simfile); fputs(" free(p[e->index - 1]);\n", simfile); fputs(" else if ((p[e->index - 1] = malloc(e->size)) == NULL)\n", simfile); fputs(" {\n", simfile); fputs(" fputs(\"out of memory\\n\", stderr);\n", simfile); fputs(" exit(EXIT_FAILURE);\n", simfile); fputs(" }\n", simfile); fputs(" return EXIT_SUCCESS;\n}\n", simfile); if ((simfile != stdout) && (simfile != stderr)) fclose(simfile); } getentry(s, sizeof(char), 4, 0); if (memcmp(s, MP_TRACEMAGIC, 4) != 0) { fprintf(stderr, "%s: Invalid file format\n", progname); exit(EXIT_FAILURE); } if (verbose) fputc('\n', stdout); showstats(); for (i = 0; i < MP_NAMECACHE_SIZE; i++) { if (funcnames[i] != NULL) free(funcnames[i]); if (filenames[i] != NULL) free(filenames[i]); } freeallocs(); fclose(tracefile);#if MP_GUI_SUPPORT if (usegui) return 1;#endif /* MP_GUI_SUPPORT */ return 0;}/* Log the allocations and deallocations from the tracing output file. */staticvoidreadfile(void){ char s[4]; size_t i; int b; /* When reading the tracing output file, we assume that if it begins and * ends with the magic sequence of characters then it is a valid tracing * output file from the mpatrol library. There are probably an infinite * number of checks we could do to ensure that the rest of the data in the * file is valid, but that would be overcomplicated and probably slow this * program down. However, if the file is only partially written then the * getentry() function will catch the error before we do something silly. */ getentry(s, sizeof(char), 4, 0); if (memcmp(s, MP_TRACEMAGIC, 4) != 0) { fprintf(stderr, "%s: Invalid file format\n", progname); exit(EXIT_FAILURE); } /* The following test allows us to read tracing output files that were * produced on a different processor architecture. If the next word in the * file does not contain the value 1 then we have to byte-swap any further * data that we read from the file. Note that this test only works if the * word size is the same on both machines. */ getentry(&i, sizeof(size_t), 1, 0); b = (i != 1); /* Get the version number of the mpatrol library which produced the * tracing output file. We assume that we can't read files produced by * later versions of mpatrol. */ getentry(&version, sizeof(unsigned long), 1, b); if (version / 100 > MP_VERNUM / 100) { fprintf(stderr, "%s: Tracing file version too new\n", progname); exit(EXIT_FAILURE); } /* Display the tracing table headings. */ if (verbose) { fputs(" event type index ", stdout);#if ENVIRON == ENVIRON_64 fputs(" allocation ", stdout);#else /* ENVIRON */ fputs("allocation", stdout);#endif /* ENVIRON */ fputs(" size life", stdout); fputs(" count bytes\n", stdout); fputs("------ ------ ------ ", stdout);#if ENVIRON == ENVIRON_64 fputs("------------------", stdout);#else /* ENVIRON */ fputs("----------", stdout);#endif /* ENVIRON */ fputs(" -------- ------", stdout); fputs(" ------ --------\n", stdout); } /* Read each allocation or deallocation entry. */#if MP_GUI_SUPPORT if (!usegui) while (readevent(NULL));#else /* MP_GUI_SUPPORT */ while (readevent());#endif /* MP_GUI_SUPPORT */}/* Read the tracing output file and display all specified information. */intmain(int argc, char **argv){ struct { char x; void *y; } z; char b[256]; char *f, *s, *t;#if MP_GUI_SUPPORT XGCValues g;#endif /* MP_GUI_SUPPORT */ long n; int c, e, h, v;#if MP_GUI_SUPPORT appwidget = XtVaAppInitialize(&appcontext, "MPTrace", options, XtNumber(options), &argc, argv, NULL, NULL); XtVaGetApplicationResources(appwidget, NULL, resources, XtNumber(resources), NULL);#endif /* MP_GUI_SUPPORT */ s = t = NULL; e = h = v = 0; progname = __mp_basename(argv[0]); while ((c = __mp_getopt(argc, argv, __mp_shortopts(b, options_table), options_table)) != EOF) switch (c) { case OF_GUI:#if MP_GUI_SUPPORT usegui = 1;#endif /* MP_GUI_SUPPORT */ break; case OF_HATFFILE: t = __mp_optarg; break; case OF_HELP: h = 1; break; case OF_SIMFILE: s = __mp_optarg; break; case OF_SOURCE: displaysource = 1; break; case OF_VERBOSE: verbose = 1; break; case OF_VERSION: v = 1; break; default: e = 1; break; } argc -= __mp_optindex; argv += __mp_optindex; if (v == 1) { fprintf(stdout, "%s %s\n%s %s\n\n", progname, PROGVERSION, __mp_copyright, __mp_author); fputs("This is free software, and you are welcome to redistribute it " "under certain\n", stdout); fputs("conditions; see the GNU Library General Public License for " "details.\n\n", stdout); fputs("For the latest mpatrol release and documentation,\n", stdout); fprintf(stdout, "visit %s.\n\n", __mp_homepage); } if (argc > 1) e = 1; if ((e == 1) || (h == 1)) { fprintf(stdout, "Usage: %s [options] [file]\n\n", progname); if (h == 0) fprintf(stdout, "Type `%s --help' for a complete list of " "options.\n", progname); else __mp_showopts(options_table); if (e == 1) exit(EXIT_FAILURE); exit(EXIT_SUCCESS); } if (argc == 1) f = argv[0]; else f = MP_TRACEFILE; __mp_newtree(&alloctree); if (strcmp(f, "-") == 0) tracefile = stdin; else if ((tracefile = fopen(f, "rb")) == NULL) { fprintf(stderr, "%s: Cannot open file `%s'\n", progname, f); exit(EXIT_FAILURE); } currentevent = 0; bufferpos = buffer; bufferlen = 0; n = (char *) &z.y - &z.x; __mp_newslots(&table, sizeof(void *), __mp_poweroftwo(n)); __mp_initslots(&table, tableslots, sizeof(tableslots)); maxslots = 1; if (s != NULL) { if (strcmp(s, "stdout") == 0) simfile = stdout; else if (strcmp(s, "stderr") == 0) simfile = stderr; else if ((simfile = fopen(s, "w")) == NULL) { fprintf(stderr, "%s: Cannot open file `%s'\n", progname, s); exit(EXIT_FAILURE); } fprintf(simfile, "/* produced by %s %s from %s */\n\n\n", progname, PROGVERSION, f); fputs("#include <stdio.h>\n", simfile); fputs("#include <stdlib.h>\n\n\n", simfile); fputs("typedef struct event\n{\n", simfile); fputs(" unsigned long index;\n", simfile); fputs(" unsigned long size;\n", simfile); fputs(" char resize;\n", simfile); fputs("}\nevent;\n\n\n", simfile); fputs("static event events[] =\n{\n", simfile); } if (t != NULL) { if (strcmp(t, "stdout") == 0) hatffile = stdout; else if (strcmp(t, "stderr") == 0) hatffile = stderr; else if ((hatffile = fopen(t, "w")) == NULL) { fprintf(stderr, "%s: Cannot open file `%s'\n", progname, t); exit(EXIT_FAILURE); } fprintf(hatffile, "## Tracename: %s\n", t); fputs("## Author: Unknown\n", hatffile); fputs("## Date: Unknown\n", hatffile); fputs("## DTDURL: hatf.dtd\n", hatffile); fprintf(hatffile, "## Description: Converted to HATF by %s %s.\n\n", progname, PROGVERSION); } readfile();#if MP_GUI_SUPPORT if (usegui) { appdisplay = XtDisplay(appwidget); appscreen = XtScreen(appwidget); addrscale = (((addrspace * 1048576) - 1) / (width * height)) + 1; /* Set up the main application window and scrollable drawing area. * Also set up a pixmap to backup the drawing area. */ mainwidget = XtVaCreateManagedWidget("main", xmScrolledWindowWidgetClass, appwidget, XmNwidth, vwidth, XmNheight, vheight, XmNscrollingPolicy, XmAUTOMATIC, XmNscrollBarDisplayPolicy, XmAS_NEEDED, NULL); drawwidget = XtVaCreateManagedWidget("draw", xmDrawingAreaWidgetClass, mainwidget, XmNwidth, width, XmNheight, height, NULL); pixmap = XCreatePixmap(appdisplay, RootWindowOfScreen(appscreen), width, height, DefaultDepthOfScreen(appscreen)); /* Set up the graphics contexts that are used for drawing in different * colours. */ g.foreground = uncol; ungc = XCreateGC(appdisplay, RootWindowOfScreen(appscreen), GCForeground, &g); g.foreground = incol; ingc = XCreateGC(appdisplay, RootWindowOfScreen(appscreen), GCForeground, &g); g.foreground = frcol; frgc = XCreateGC(appdisplay, RootWindowOfScreen(appscreen), GCForeground, &g); g.foreground = alcol; algc = XCreateGC(appdisplay, RootWindowOfScreen(appscreen), GCForeground, &g); /* Add a callback procedure to handle the refreshing of the drawing * area and also a work procedure to read events from the tracing * output file. Then initialise the drawing area and enter the main X * application loop. */ XtAddCallback(drawwidget, XmNexposeCallback, (XtCallbackProc) redrawmemory, NULL); XtAppAddWorkProc(appcontext, (XtWorkProc) readevent, NULL); XtRealizeWidget(appwidget); XFillRectangle(appdisplay, XtWindow(drawwidget), ungc, 0, 0, width - 1, height - 1); XFillRectangle(appdisplay, pixmap, ungc, 0, 0, width - 1, height - 1); XtAppMainLoop(appcontext); }#endif /* MP_GUI_SUPPORT */ return EXIT_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -