From cfc89672ed97b62ca1bd8ca37f3690688a0fe256 Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Wed, 13 Jul 2016 22:50:28 -0400 Subject: [PATCH] Add trace_dump tool trace_dump autodetects trace file vs workload, outputs the contents thereof --- malloc/Makefile | 7 +- malloc/trace_dump.c | 198 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 malloc/trace_dump.c diff --git a/malloc/Makefile b/malloc/Makefile index 4146c2a9b49..bbfa2db0c00 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -50,12 +50,15 @@ libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes)) libmtracectl-routines = mtrace-ctl libmtracectl-inhibit-o = $(filter-out .os,$(object-suffixes)) -others: $(objpfx)trace_run $(objpfx)trace2wl -install-bin = trace_run trace2wl +others: $(objpfx)trace_run $(objpfx)trace2wl $(objpfx)trace_dump +install-bin = trace_run trace2wl trace_dump $(objpfx)trace_run: $(objpfx)trace_run.o $(LINK.o) -o $@ $(objpfx)trace_run.o -lpthread +$(objpfx)trace_dump: $(objpfx)trace_dump.o + $(LINK.o) -o $@ $(objpfx)trace_dump.o + ifeq (${CXX},) CXX = g++ endif diff --git a/malloc/trace_dump.c b/malloc/trace_dump.c new file mode 100644 index 00000000000..d3a72f248cf --- /dev/null +++ b/malloc/trace_dump.c @@ -0,0 +1,198 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// The trace file looks like an array of struct __malloc_trace_buffer_s +#include "mtrace.h" + +static size_t +get_int (unsigned char **ptr) +{ + size_t rv = 0; + while (1) + { + unsigned char c = *(*ptr)++; + rv |= (c & 0x7f); + if (c & 0x80) + rv <<= 7; + else + return rv; + } +} + + +int +data_looks_like_raw_trace (unsigned char *data, long n_data) +{ + long lim = n_data > 1024 ? 1020 : (n_data - 4); + long i; + + // free and malloc calls will have a NULL we can look for + for (i=0; itype) + { + case __MTB_TYPE_UNUSED: + break; + default: + printf ("%08x %s %c%c%c%c%c%c%c%c %016llx %016llx %016llx\n", + t->thread, + t->type == __MTB_TYPE_MAGIC ? "magic " : typenames[t->type], + t->path_thread_cache ? 'T' : '-', + t->path_cpu_cache ? 'c' : '-', + t->path_cpu_cache2 ? 'C' : '-', + t->path_sbrk ? 's' : '-', + t->path_mmap ? 'M' : '-', + t->path_munmap ? 'U' : '-', + t->path_m_f_realloc ? 'R' : '-', + t->path_hook ? 'H' : '-', + (long long unsigned int) (size_t) t->ptr1, + (long long unsigned int) t->size, + (long long unsigned int) (size_t) t->ptr2); + break; + } + + data += sizeof (struct __malloc_trace_buffer_s); + } +} + +void +dump_workload (unsigned char *data, long n_data) +{ + unsigned char *orig_data = data; + unsigned char *edata = data + n_data; + int thread_idx = 0; + int n_ptrs, n_syncs, n_threads, idx, p1, p2, sz; + + while (data < edata) + { + printf("%016lx: %4d: ", data - orig_data, thread_idx); + switch (*data++) + { + case C_NOP: + break; + case C_ALLOC_PTRS: + n_ptrs = get_int(&data); + printf("AllocPtrs: %d\n", n_ptrs); + break; + case C_ALLOC_SYNCS: + n_syncs = get_int(&data); + printf("AllocSyncs: %d\n", n_syncs); + break; + case C_NTHREADS: + n_threads = get_int (&data); + printf("NThreads: %d\n", n_threads); + break; + case C_START_THREAD: + idx = get_int (&data); + printf("StartThread: 0x%x\n", idx); + break; + case C_DONE: + printf("Done\n"); + thread_idx ++; + break; + + case C_MALLOC: + p2 = get_int (&data); + sz = get_int (&data); + printf("Malloc (%d) -> %d\n", sz, p2); + break; + + case C_CALLOC: + p2 = get_int (&data); + sz = get_int (&data); + printf("Calloc (%d) -> %d\n", sz, p2); + break; + + case C_REALLOC: + p2 = get_int (&data); + p1 = get_int (&data); + sz = get_int (&data); + printf("Realloc (%d, %d) -> %d\n", p1, sz, p2); + break; + + case C_FREE: + p1 = get_int (&data); + printf("Free (%d)\n", p1); + break; + + case C_SYNC_W: + p1 = get_int(&data); + printf("SyncW (%d)\n", p1); + break; + + case C_SYNC_R: + p1 = get_int(&data); + printf("SyncR (%d)\n", p1); + break; + + default: + printf("(unknown:%d)\n", *--data); + exit(1); + } + } +} + +int +main (int argc, char **argv) +{ + int fd; + struct stat statb; + unsigned char *data; + + fd = open(argv[1], O_RDONLY); + if (fd < 0) + { + fprintf(stderr, "Unable to open %s for reading\n", argv[1]); + perror("The error was"); + exit(1); + } + fstat (fd, &statb); + + data = (unsigned char *) mmap (NULL, statb.st_size, PROT_READ, MAP_SHARED, fd, 0); + + if (data_looks_like_raw_trace (data, statb.st_size)) + dump_raw_trace (data, statb.st_size); + else + dump_workload (data, statb.st_size); + + return 0; +} -- 2.47.2