This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch dj/malloc updated. glibc-2.22-719-g1322011


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, dj/malloc has been updated
       via  1322011d96a58f2d7cf9658eaa91f6645ff31b1a (commit)
      from  649255b5d3d24089ecc0024972a875ee83a2be0a (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=1322011d96a58f2d7cf9658eaa91f6645ff31b1a

commit 1322011d96a58f2d7cf9658eaa91f6645ff31b1a
Author: DJ Delorie <dj@delorie.com>
Date:   Thu Feb 11 01:49:48 2016 -0500

    Update malloc tracing utility.
    
    Change head pointer to be total calls; adjust users to modulo after
    incrementing.
    
    Use mmap() instead of sbrk().
    
    Split environment variables so count and file can be specified.
    
    Export trace hooks so mtrace-ctl can be built against libc.so.
    
    Allow NULL to be passed to __mtrace_get_trace_buffer.
    
    Add some error handling to mtrace-ctl.

diff --git a/malloc/Versions b/malloc/Versions
index f3c3d8a..43cb909 100644
--- a/malloc/Versions
+++ b/malloc/Versions
@@ -72,5 +72,9 @@ libc {
     __libc_scratch_buffer_grow;
     __libc_scratch_buffer_grow_preserve;
     __libc_scratch_buffer_set_array_size;
+
+    # malloc trace hooks for mtrace-ctl
+    __malloc_set_trace_buffer;
+    __malloc_get_trace_buffer;
   }
 }
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 6765aba..2fe4ada 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1093,12 +1093,11 @@ static __thread __malloc_trace_buffer_ptr trace_ptr;
 static inline void __attribute__((always_inline))
 __mtb_trace_entry (uint32_t type, int64_t size, void *ptr1)
 {
-  int head1, head2;
-  do {
-    head1 = head2 = __malloc_trace_buffer_head;
-    head2 = (head2 + 1) % __malloc_trace_buffer_size;
-  } while (catomic_compare_and_exchange_bool_acq (&__malloc_trace_buffer_head, head2, head1));
-  trace_ptr = __malloc_trace_buffer + head1;
+  int head1;
+
+  head1 = catomic_exchange_and_add (&__malloc_trace_buffer_head, 1);
+
+  trace_ptr = __malloc_trace_buffer + (head1 % __malloc_trace_buffer_size);
 
   trace_ptr->thread = syscall(__NR_gettid);
   trace_ptr->type = type;
@@ -1128,8 +1127,10 @@ __malloc_set_trace_buffer (void *bufptr, int bufsize)
 void *
 __malloc_get_trace_buffer (int *bufcount, int *bufhead)
 {
-  *bufcount = __malloc_trace_buffer_size;
-  *bufhead = __malloc_trace_buffer_head;
+  if (bufcount)
+    *bufcount = __malloc_trace_buffer_size;
+  if (bufhead)
+    *bufhead = __malloc_trace_buffer_head;
   return __malloc_trace_buffer;
 }
 
diff --git a/malloc/mtrace-ctl.c b/malloc/mtrace-ctl.c
index 2acc897..641a6a2 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;
 }
diff --git a/malloc/mtrace.h b/malloc/mtrace.h
index bcb5b63..e0fdd7b 100644
--- a/malloc/mtrace.h
+++ b/malloc/mtrace.h
@@ -51,14 +51,18 @@ extern volatile int __malloc_trace_buffer_head;
    chunk in BYTES.  Returns the size of __malloc_trace_buffer_s.  The
    buffer should be filled with NUL bytes before passing, such that
    each record's type is UNUSED (below).  The trace buffer may be
-   disabled by passing NULL,0 although it's up to the caller to free
-   the previous buffer first.  */
+   disabled by passing NULL,0 although it's up to the caller to obtain
+   and free/unmap the previous buffer first.  */
 int __malloc_set_trace_buffer (void *bufptr, int bufsize);
 
 /* Returns the location of the buffer (same as passed above, or NULL).
    Also fills in BUFCOUNT which is the number of records (not bytes)
    in the buffer, and BUFHEAD which is the index of the most recently
-   filled entry.  */
+   filled entry.  NOTE that BUFHEAD might be greater than bufcount; if
+   so it reflects the number of records that would have been stored
+   had there been size, and the caller must modulo that by BUFCOUNT to
+   get the ending index.  The last BUFCOUNT records are stored;
+   earlier records are overwritten. */
 void * __malloc_get_trace_buffer (int *bufcount, int *bufhead);
 
 

-----------------------------------------------------------------------

Summary of changes:
 malloc/Versions     |    4 +++
 malloc/malloc.c     |   17 +++++++------
 malloc/mtrace-ctl.c |   62 +++++++++++++++++++++++++++++++++++++++++++-------
 malloc/mtrace.h     |   10 +++++--
 4 files changed, 73 insertions(+), 20 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]