📄 mptrace.c
字号:
/* * mpatrol * A library for controlling and tracing dynamic memory allocations. * Copyright (C) 1997-2002 Graeme S. Roy <graeme.roy@analog.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307, USA. *//* * A tool designed to read a tracing output file produced by the mpatrol * library and display the tracing information that was obtained. It can * also produce a C source file containing a trace-driven memory allocation * simulation of the program which produced the corresponding tracing output * file. */#include "tree.h"#include "slots.h"#include "getopt.h"#include "utils.h"#include "version.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#if MP_GUI_SUPPORT#include <Xm/DrawingA.h>#include <Xm/ScrolledW.h>#endif /* MP_GUI_SUPPORT */#if MP_IDENT_SUPPORT#ident "$Id: mptrace.c,v 1.28 2002/01/08 20:13:59 graeme Exp $"#else /* MP_IDENT_SUPPORT */static MP_CONST MP_VOLATILE char *mptrace_id = "$Id: mptrace.c,v 1.28 2002/01/08 20:13:59 graeme Exp $";#endif /* MP_IDENT_SUPPORT */#define PROGVERSION "1.4" /* the current version of this program *//* The flags used to parse the command line options. */typedef enum options_flags{ OF_HATFFILE = 'H', OF_HELP = 'h', OF_SIMFILE = 'S', OF_SOURCE = 's', OF_VERSION = 'V', OF_VERBOSE = 'v', OF_GUI = 'w'}options_flags;/* Structure containing the allocation details for a single memory allocation. */typedef struct allocation{ treenode node; /* tree node */ unsigned long event; /* event number */ void *entry; /* pointer array entry */ void *addr; /* allocation address */ size_t size; /* allocation size */ unsigned long time; /* allocation lifetime */}allocation;/* Structure containing the statistics for a tracing output file. */typedef struct statistics{ size_t acount; /* total number of allocated blocks */ size_t atotal; /* total size of allocated blocks */ size_t fcount; /* total number of freed blocks */ size_t ftotal; /* total size of freed blocks */ size_t rcount; /* total number of reserved blocks */ size_t rtotal; /* total size of reserved blocks */ size_t icount; /* total number of internal blocks */ size_t itotal; /* total size of internal blocks */ size_t pcount; /* peak number of allocated blocks */ size_t ptotal; /* peak size of allocated blocks */ size_t lsize; /* smallest size of an allocation */ size_t usize; /* largest size of an allocation */}statistics;/* The version of the mpatrol library which produced the tracing output file. */static unsigned long version;/* The tree containing information about each memory allocation. */static treeroot alloctree;/* The number of the current event in the tracing output file. */static unsigned long currentevent;/* The input buffer used to read from the tracing output file, and also the * current buffer position and length. */static char buffer[MP_BUFFER_SIZE];static char *bufferpos;static size_t bufferlen;/* The slot table allows us to reuse entries in the pointer array when we are * writing a simulation file. The size of the tableslots array sets a limit * on the maximum number of allocations that can be in use at any one time. */static slottable table;static void *tableslots[4096];static size_t maxslots;/* The name caches for the function names and the file names. */static char *funcnames[MP_NAMECACHE_SIZE];static char *filenames[MP_NAMECACHE_SIZE];/* The statistics gathered from the tracing output file. */static statistics stats;/* The tracing output file produced by mpatrol. */static FILE *tracefile;/* The HATF file produced from the tracing output file. */static FILE *hatffile;/* The simulation file produced from the tracing output file. */static FILE *simfile;/* The filename used to invoke this tool. */static char *progname;/* Indicates if the tracing table should be displayed. */static int verbose;/* Indicates if source-level information should be displayed in the tracing * table if it is available. */static int displaysource;#if MP_GUI_SUPPORT/* Indicates if the GUI should be used or not. */static int usegui;/* The X toolkit context for this application. */static XtAppContext appcontext;/* The X display and screen pointers for this application. */static Display *appdisplay;static Screen *appscreen;/* The X widgets for the application shell, main application and drawing area. */static Widget appwidget, mainwidget, drawwidget;/* The X pixmap for the backup drawing area. */static Pixmap pixmap;/* The X graphics contexts for unallocated, internal, free and allocated memory. */static GC ungc, ingc, frgc, algc;/* The colours for unallocated, internal, free and allocated memory. */static Pixel uncol, incol, frcol, alcol;/* The width and height (in pixels) of the window and the drawing area. */static Dimension vwidth, vheight, width, height;/* The delay between drawing each event. */static unsigned long delay;/* The base address and the size (in megabytes) of the address space covered by * the drawing area. */static void *addrbase;static unsigned long addrspace;/* The scaling factor of the drawing area. */static unsigned long addrscale;/* The X resources for this application. */static XtResource resources[] ={ {"alloc", XmCColor, XmRPixel, sizeof(Pixel), (Cardinal) &alcol, XmRString, (XtPointer) "black"}, {"base", "Base", XmRInt, sizeof(void *), (Cardinal) &addrbase, XmRImmediate, (XtPointer) NULL}, {"delay", "Delay", XmRInt, sizeof(unsigned long), (Cardinal) &delay, XmRImmediate, (XtPointer) 0}, {"free", XmCColor, XmRPixel, sizeof(Pixel), (Cardinal) &frcol, XmRString, (XtPointer) "white"}, {"height", XmCHeight, XmRShort, sizeof(Dimension), (Cardinal) &height, XmRImmediate, (XtPointer) 512}, {"internal", XmCColor, XmRPixel, sizeof(Pixel), (Cardinal) &incol, XmRString, (XtPointer) "red"}, {"space", "Space", XmRInt, sizeof(unsigned long), (Cardinal) &addrspace, XmRImmediate, (XtPointer) 4}, {"unalloc", XmCColor, XmRPixel, sizeof(Pixel), (Cardinal) &uncol, XmRString, (XtPointer) "blue"}, {"view-height", XmCHeight, XmRShort, sizeof(Dimension), (Cardinal) &vheight, XmRImmediate, (XtPointer) 256}, {"view-width", XmCWidth, XmRShort, sizeof(Dimension), (Cardinal) &vwidth, XmRImmediate, (XtPointer) 256}, {"width", XmCWidth, XmRShort, sizeof(Dimension), (Cardinal) &width, XmRImmediate, (XtPointer) 512}};/* The X options for this application. */static XrmOptionDescRec options[] ={ {"--alloc", "alloc", XrmoptionSepArg, NULL}, {"--base", "base", XrmoptionSepArg, NULL}, {"--delay", "delay", XrmoptionSepArg, NULL}, {"--free", "free", XrmoptionSepArg, NULL}, {"--height", "height", XrmoptionSepArg, NULL}, {"--internal", "internal", XrmoptionSepArg, NULL}, {"--space", "space", XrmoptionSepArg, NULL}, {"--unalloc", "unalloc", XrmoptionSepArg, NULL}, {"--view-height", "view-height", XrmoptionSepArg, NULL}, {"--view-width", "view-width", XrmoptionSepArg, NULL}, {"--width", "width", XrmoptionSepArg, NULL}};#endif /* MP_GUI_SUPPORT *//* The table describing all recognised options. */static option options_table[] ={ {"gui", OF_GUI, NULL, "\tDisplays the GUI (if supported).\n"}, {"hatf-file", OF_HATFFILE, "file", "\tSpecifies that the trace should also be written to a file in Heap\n" "\tAllocation Trace Format (HATF).\n"}, {"help", OF_HELP, NULL, "\tDisplays this quick-reference option summary.\n"}, {"sim-file", OF_SIMFILE, "file", "\tSpecifies that a trace-driven memory allocation simulation program\n" "\twritten in C should be written to a file.\n"}, {"source", OF_SOURCE, NULL, "\tDisplays source-level information for each event in the tracing\n" "\ttable, if available.\n"}, {"verbose", OF_VERBOSE, NULL, "\tSpecifies that the tracing table should be displayed.\n"}, {"version", OF_VERSION, NULL, "\tDisplays the version number of this program.\n"}, NULL};#define slotentry(n) \ (unsigned long) ((sizeof(tableslots) - ((char *) (n)->entry - \ (char *) tableslots)) / sizeof(void *))/* Create a new memory allocation. */staticallocation *newalloc(unsigned long i, unsigned long e, void *a, size_t l){ allocation *n; if (n = (allocation *) __mp_search(alloctree.root, i)) { if (n->time == 0) fprintf(stderr, "%s: Allocation index `%lu' has been allocated " "twice without being freed\n", progname, i); } else { if ((n = (allocation *) malloc(sizeof(allocation))) == NULL) { fprintf(stderr, "%s: Out of memory\n", progname); exit(EXIT_FAILURE); } __mp_treeinsert(&alloctree, &n->node, i); n->event = e; } if (simfile != NULL) { if ((n->entry = __mp_getslot(&table)) == NULL) { fprintf(stderr, "%s: Too many allocations in use\n", progname); exit(EXIT_FAILURE); } } else n->entry = NULL; n->addr = a; n->size = l; n->time = 0; return n;}/* Free all existing memory allocations. */staticvoidfreeallocs(void){ allocation *n, *p; for (n = (allocation *) __mp_minimum(alloctree.root); n != NULL; n = p) { p = (allocation *) __mp_successor(&n->node); __mp_treeremove(&alloctree, &n->node); free(n); }}/* Byte-swap a block of memory. */staticvoidbyteswap(void *b, size_t n){ char *s, *t; char c; s = (char *) b; t = (char *) b + n - 1; while (s < t) { c = *s; *s++ = *t; *t-- = c; }}/* Refill the input buffer. The input buffer is necessary since we need to * have a minimum number of bytes to read an LEB128 number from the input * file. */staticsize_trefill(size_t s){ static int e; size_t l, n; /* We only need to refill the input buffer if there are not enough bytes * in the buffer and we have not reached the end of the file. */ if ((e == 1) || (bufferlen >= s)) return bufferlen; /* Check that the requested number of bytes will fit into the buffer. */ if (s > MP_BUFFER_SIZE) { fprintf(stderr, "%s: Buffer overflow\n", progname); exit(EXIT_FAILURE); } /* If there are any remaining bytes in the buffer then move them to the * start of the buffer so that we can fill up the rest of the buffer. */ if ((bufferpos != buffer) && (bufferlen > 0)) memmove(buffer, bufferpos, bufferlen); bufferpos = buffer; /* Attempt to fill up the buffer with bytes from the input file. */ l = MP_BUFFER_SIZE - bufferlen; if ((n = fread(buffer + bufferlen, sizeof(char), l, tracefile)) != l) if (feof(tracefile)) e = 1; else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -