aboutsummaryrefslogtreecommitdiff
path: root/malloc/mtrace-ctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'malloc/mtrace-ctl.c')
-rw-r--r--malloc/mtrace-ctl.c62
1 files changed, 53 insertions, 9 deletions
diff --git a/malloc/mtrace-ctl.c b/malloc/mtrace-ctl.c
index 2acc8976ce..641a6a2aff 100644
--- a/malloc/mtrace-ctl.c
+++ b/malloc/mtrace-ctl.c
@@ -1,19 +1,49 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
+#include <string.h>
#include <unistd.h>
+#include <sys/mman.h>
+
+/* Build like this:
+
+ gcc -shared -fpic mtrace-ctl.c -o /tmp/mtrace-ctl.so ../../glibc.build/libc.so
+
+ Invoke like this:
+
+ LD_PRELOAD=/tmp/mtrace-ctl.so ./myprog
+
+*/
#include "mtrace.h"
+static void
+err(const char *str)
+{
+ write (2, str, strlen(str));
+ write (2, "\n", 1);
+ exit(1);
+}
+
void __attribute__((constructor))
djmain()
{
- char *e = getenv("MTRACE_CTL");
- if (!e) e = "1000";
- int sz = atoi(e) * sizeof(struct __malloc_trace_buffer_s);
- char *buf = sbrk (sz+15);
- while ((intptr_t)buf & 15)
- buf ++;
+ char *e;
+ int sz;
+
+ e = getenv("MTRACE_CTL_COUNT");
+ if (!e)
+ e = "1000";
+ sz = atoi(e) * sizeof(struct __malloc_trace_buffer_s);
+
+ char *buf = mmap (NULL, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (!buf)
+ err("Cannot mmap");
+
+ buf[0] = 1;
+ buf[sz-1] = 1;
+
+ /* This must be the last thing we do. */
__malloc_set_trace_buffer ((void *)buf, sz);
return;
}
@@ -31,17 +61,29 @@ const char * const typenames[] = {
void __attribute__((destructor))
djend()
{
+ char *e;
FILE *outf;
int head, size, i;
+
+ /* Prevent problems with recursion etc by shutting off trace right away. */
__malloc_trace_buffer_ptr buf = __malloc_get_trace_buffer (&size, &head);
- outf = fopen("/tmp/mtrace.out", "w");
+ __malloc_set_trace_buffer (NULL, 0);
+
+ e = getenv("MTRACE_CTL_FILE");
+ if (!e)
+ e = "/tmp/mtrace.out";
+
+ outf = fopen(e, "w");
if (!outf)
- return;
+ err("cannot open output file");
+ setbuf (outf, NULL);
+
+ fprintf (outf, "%d out of %d events captured\n", head, size);
fprintf (outf, "threadid type path ptr1 size ptr2\n");
for (i=0; i<size; i++)
{
- __malloc_trace_buffer_ptr t = buf + i % size;
+ __malloc_trace_buffer_ptr t = buf + (i+head) % size;
switch (t->type)
{
@@ -65,5 +107,7 @@ djend()
}
}
fclose (outf);
+
+ munmap (buf, size * sizeof(struct __malloc_trace_buffer_s));
return;
}