This is the mail archive of the libc-alpha@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]

malloc probes for Systemtap


I was asked to introduce probes in malloc to aid in debugging cases in
which our memory allocation code performs poorly.

I've grouped the probes in separate patches, in which the probes are
logically connected.  I'd appreciate feedback on the soundness of the
probe set: did I miss anything in these groups that is worth probing?
is any of the probes uselessly redundant?  are they desirable at all?

Are they ok for master?  Do the docs look reasonable, description and
formatting-wise?  (The only other probe docs I found in glibc were in
elf/rtld-debugger-interface.txt)

The version of the patchset I pushed to lxoliva/malloc-probes-bz742038
depends on Siddhesh's patch that introduces get_another_arena.  Although
I've just suggested changes to it, I decided to post the patchset as it
is, since most of it applies cleanly anyway, and regardless of
adjustments needed for Siddhesh's patch, I suspect we might go through
more than one round of review before my patchset can go in anyway.


Add first set of malloc probes.

From: Alexandre Oliva <aoliva@redhat.com>

for ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* malloc/malloc.c: Include stap-probe.h.
	(__libc_mallopt): Add mallopt probe.
	* malloc/arena.c (_int_new_arena): Add malloc_arena_new probe.
	* manual/malloc.texi: Document them.
---

 malloc/arena.c     |    1 +
 malloc/malloc.c    |    4 ++++
 manual/memory.texi |   27 +++++++++++++++++++++++++++
 3 files changed, 32 insertions(+), 0 deletions(-)


diff --git a/malloc/arena.c b/malloc/arena.c
index 9e5e332..e319b59 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -735,6 +735,7 @@ _int_new_arena(size_t size)
   top(a) = (mchunkptr)ptr;
   set_head(top(a), (((char*)h + h->size) - ptr) | PREV_INUSE);
 
+  LIBC_PROBE (malloc_arena_new, 2, a, size);
   tsd_setspecific(arena_key, (void *)a);
   mutex_init(&a->mutex);
   (void)mutex_lock(&a->mutex);
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 2a32d49..57a6f23 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1882,6 +1882,8 @@ static int perturb_byte;
 #define free_perturb(p, n) memset (p, perturb_byte & 0xff, n)
 
 
+#include <stap-probe.h>
+
 /* ------------------- Support for multiple arenas -------------------- */
 #include "arena.c"
 
@@ -4699,6 +4701,8 @@ int __libc_mallopt(int param_number, int value)
   /* Ensure initialization/consolidation */
   malloc_consolidate(av);
 
+  LIBC_PROBE (mallopt, 2, param_number, value);
+
   switch(param_number) {
   case M_MXFAST:
     if (value >= 0 && value <= MAX_FAST_SIZE) {
diff --git a/manual/memory.texi b/manual/memory.texi
index 35fed23..de58a5d 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -286,6 +286,8 @@ any time (or never).
 * Heap Consistency Checking::   Automatic checking for errors.
 * Hooks for Malloc::            You can use these hooks for debugging
 				 programs that use @code{malloc}.
+* Probes for Malloc::           You can use these probes to monitor some
+				 internal behavior of @code{malloc}.
 * Statistics of Malloc::        Getting information about how much
 				 memory your program is using.
 * Summary of Malloc::           Summary of @code{malloc} and related functions.
@@ -1019,6 +1021,31 @@ installing such hooks.
 @c __morecore, __after_morecore_hook are undocumented
 @c It's not clear whether to document them.
 
+@node Probes for Malloc
+@subsubsection Memory Allocation Probes
+@cindex allocation probes, for @code{malloc}
+
+These are nearly-zero-overhead probes available for monitoring internal
+@code{malloc} behavior, using Systemtap process marks with the
+@code{libc} provider.  The probes assume a reasonable knowledge of the
+@code{malloc} implementation.
+
+@deftp Probe malloc_arena_new (void *@var{$arg1}, size_t @var{$arg2})
+This probe is hit when @code{malloc} allocated and initialized an
+additional allocation arena (not the main arena), but before it is
+assigned to the running thread and inserted in the internal linked list
+of arenas.  The arena's @code{malloc_state} internal data structure is
+located at @var{$arg1}, within a newly-allocated heap big enough to hold
+at least @var{$arg2} bytes.
+@end deftp
+
+@deftp Probe mallopt (int @var{$arg1}, int @var{$arg2})
+This probe is hit when function @code{mallopt} is called to change
+@code{malloc} internal configuration parameters, before any change to
+the parameters is made.  The arguments @var{$arg1} and @var{$arg2} are
+the ones passed to the @code{mallopt} function.
+@end deftp
+
 @node Statistics of Malloc
 @subsubsection Statistics for Memory Allocation with @code{malloc}
 
Add probes for all changes to malloc options.

From: Alexandre Oliva <aoliva@redhat.com>

for ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* malloc/malloc.c (__libc_free): Add
	mallopt_free_dyn_thresholds probe.
	(__libc_mallopt): Add multiple mallopt probes.
	* manual/malloc.texi: Document them.
---

 malloc/malloc.c    |   30 +++++++++++++++++---
 manual/memory.texi |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 103 insertions(+), 5 deletions(-)


diff --git a/malloc/malloc.c b/malloc/malloc.c
index 57a6f23..bb9f984 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2921,6 +2921,8 @@ __libc_free(void* mem)
       {
 	mp_.mmap_threshold = chunksize (p);
 	mp_.trim_threshold = 2 * mp_.mmap_threshold;
+	LIBC_PROBE (mallopt_free_dyn_thresholds, 2,
+		    mp_.mmap_threshold, mp_.trim_threshold);
       }
     munmap_chunk(p);
     return;
@@ -4705,19 +4707,25 @@ int __libc_mallopt(int param_number, int value)
 
   switch(param_number) {
   case M_MXFAST:
-    if (value >= 0 && value <= MAX_FAST_SIZE) {
-      set_max_fast(value);
-    }
+    if (value >= 0 && value <= MAX_FAST_SIZE)
+      {
+	LIBC_PROBE (mallopt_mxfast, 2, value, get_max_fast ());
+	set_max_fast(value);
+      }
     else
       res = 0;
     break;
 
   case M_TRIM_THRESHOLD:
+    LIBC_PROBE (mallopt_trim_threshold, 3, value,
+		mp_.trim_threshold, mp_.no_dyn_threshold);
     mp_.trim_threshold = value;
     mp_.no_dyn_threshold = 1;
     break;
 
   case M_TOP_PAD:
+    LIBC_PROBE (mallopt_top_pad, 3, value,
+		mp_.top_pad, mp_.no_dyn_threshold);
     mp_.top_pad = value;
     mp_.no_dyn_threshold = 1;
     break;
@@ -4728,33 +4736,45 @@ int __libc_mallopt(int param_number, int value)
       res = 0;
     else
       {
+	LIBC_PROBE (mallopt_mmap_threshold, 3, value,
+		    mp_.mmap_threshold, mp_.no_dyn_threshold);
 	mp_.mmap_threshold = value;
 	mp_.no_dyn_threshold = 1;
       }
     break;
 
   case M_MMAP_MAX:
+      LIBC_PROBE (mallopt_mmap_max, 3, value,
+		  mp_.mmap_threshold, mp_.no_dyn_threshold);
       mp_.n_mmaps_max = value;
       mp_.no_dyn_threshold = 1;
     break;
 
   case M_CHECK_ACTION:
+    LIBC_PROBE (mallopt_check_action, 2, value, check_action);
     check_action = value;
     break;
 
   case M_PERTURB:
+    LIBC_PROBE (mallopt_perturb, 2, value, perturb_byte);
     perturb_byte = value;
     break;
 
 #ifdef PER_THREAD
   case M_ARENA_TEST:
     if (value > 0)
-      mp_.arena_test = value;
+      {
+	LIBC_PROBE (mallopt_arena_test, 2, value, mp_.arena_test);
+	mp_.arena_test = value;
+      }
     break;
 
   case M_ARENA_MAX:
     if (value > 0)
-      mp_.arena_max = value;
+      {
+	LIBC_PROBE (mallopt_arena_max, 2, value, mp_.arena_max);
+	mp_.arena_max = value;
+      }
     break;
 #endif
   }
diff --git a/manual/memory.texi b/manual/memory.texi
index de58a5d..c074fc6 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -1046,6 +1046,84 @@ the parameters is made.  The arguments @var{$arg1} and @var{$arg2} are
 the ones passed to the @code{mallopt} function.
 @end deftp
 
+@deftp Probe mallopt_mxfast (int @var{$arg1}, int @var{$arg2})
+This probe is hit shortly after the @code{mallopt} probe, when the
+parameter to be changed is @code{M_MXFAST}, and the requested value is
+in an acceptable range.  Argument @var{$arg1} is the requested value,
+and @var{$arg2} is the previous value of this @code{malloc} parameter.
+@end deftp
+
+@deftp Probe mallopt_trim_threshold (int @var{$arg1}, int @var{$arg2}, int @var{$arg3})
+This probe is hit shortly after the @code{mallopt} probe, when the
+parameter to be changed is @code{M_TRIM_THRESHOLD}.  Argument
+@var{$arg1} is the requested value, @var{$arg2} is the previous value of
+this @code{malloc} parameter, and @var{$arg3} is nonzero if dynamic
+threshold adjustments was already disabled.
+@end deftp
+
+@deftp Probe mallopt_top_pad (int @var{$arg1}, int @var{$arg2}, int @var{$arg3})
+This probe is hit shortly after the @code{mallopt} probe, when the
+parameter to be changed is @code{M_TOP_PAD}.  Argument @var{$arg1} is
+the requested value, @var{$arg2} is the previous value of this
+@code{malloc} parameter, and @var{$arg3} is nonzero if dynamic threshold
+adjustments was already disabled.
+@end deftp
+
+@deftp Probe mallopt_mmap_threshold (int @var{$arg1}, int @var{$arg2}, int @var{$arg3})
+This probe is hit shortly after the @code{mallopt} probe, when the
+parameter to be changed is @code{M_MMAP_THRESHOLD}, and the requested
+value is in an acceptable range.  Argument @var{$arg1} is the requested
+value, @var{$arg2} is the previous value of this @code{malloc}
+parameter, and @var{$arg3} is nonzero if dynamic threshold adjustments
+was already disabled.
+@end deftp
+
+@deftp Probe mallopt_mmap_max (int @var{$arg1}, int @var{$arg2}, int @var{$arg3})
+This probe is hit shortly after the @code{mallopt} probe, when the
+parameter to be changed is @code{M_MMAP_MAX}.  Argument @var{$arg1} is
+the requested value, @var{$arg2} is the previous value of this
+@code{malloc} parameter, and @var{$arg3} is nonzero if dynamic threshold
+adjustments was already disabled.
+@end deftp
+
+@deftp Probe mallopt_check_action (int @var{$arg1}, int @var{$arg2})
+This probe is hit shortly after the @code{mallopt} probe, when the
+parameter to be changed is @code{M_CHECK_ACTION}.  Argument @var{$arg1}
+is the requested value, and @var{$arg2} is the previous value of this
+@code{malloc} parameter.
+@end deftp
+
+@deftp Probe mallopt_perturb (int @var{$arg1}, int @var{$arg2})
+This probe is hit shortly after the @code{mallopt} probe, when the
+parameter to be changed is @code{M_PERTURB}.  Argument @var{$arg1} is
+the requested value, and @var{$arg2} is the previous value of this
+@code{malloc} parameter.
+@end deftp
+
+@deftp Probe mallopt_arena_test (int @var{$arg1}, int @var{$arg2})
+This probe is hit shortly after the @code{mallopt} probe, when the
+parameter to be changed is @code{M_ARENA_TEST}, and the requested value
+is in an acceptable range.  Argument @var{$arg1} is the requested value,
+and @var{$arg2} is the previous value of this @code{malloc} parameter.
+This probe is not available if @code{malloc} is compiled without
+per-thread arenas (@samp{-DPER_THREAD}).
+@end deftp
+
+@deftp Probe mallopt_arena_max (int @var{$arg1}, int @var{$arg2})
+This probe is hit shortly after the @code{mallopt} probe, when the
+parameter to be changed is @code{M_ARENA_MAX}, and the requested value
+is in an acceptable range.  Argument @var{$arg1} is the requested value,
+and @var{$arg2} is the previous value of this @code{malloc} parameter.
+This probe is not available if @code{malloc} is compiled without
+per-thread arenas (@samp{-DPER_THREAD}).
+@end deftp
+
+@deftp Probe mallopt_free_dyn_thresholds (int @var{$arg1}, int @var{$arg2})
+This probe is hit when function @code{free} decides to adjust the
+dynamic brk/mmap thresholds.  Argument @var{$arg1} and @var{$arg2} are
+the adjusted mmap and trim thresholds, respectively.
+@end deftp
+
 @node Statistics of Malloc
 @subsubsection Statistics for Memory Allocation with @code{malloc}
 
Add probes for malloc arena changes.

From: Alexandre Oliva <aoliva@redhat.com>

for ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* malloc/arena.c (get_free_list): Add probe
	malloc_arena_reuse_free_list.
	(reused_arena) [PER_THREAD]: Add probes malloc_arena_reuse_wait
	and malloc_arena_reuse.
	(arena_get2) [!PER_THREAD]: Likewise.
	* malloc/malloc.c (__libc_realloc) [!PER_THREAD]: Add probe
	malloc_arena_reuse_realloc.
	* manual/malloc.texi: Document them.
---

 malloc/arena.c     |    5 ++++
 malloc/malloc.c    |    1 +
 manual/memory.texi |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+), 0 deletions(-)


diff --git a/malloc/arena.c b/malloc/arena.c
index e319b59..0828456 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -774,6 +774,7 @@ get_free_list (void)
 
       if (result != NULL)
 	{
+	  LIBC_PROBE (malloc_arena_reuse_free_list, 1, result);
 	  (void)mutex_lock(&result->mutex);
 	  tsd_setspecific(arena_key, (void *)result);
 	  THREAD_STAT(++(result->stat_lock_loop));
@@ -810,9 +811,11 @@ reused_arena (mstate avoid_arena)
     result = result->next;
 
   /* No arena available.  Wait for the next in line.  */
+  LIBC_PROBE (malloc_arena_reuse_wait, 3, &result->mutex, result, avoid_arena);
   (void)mutex_lock(&result->mutex);
 
  out:
+  LIBC_PROBE (malloc_arena_reuse, 2, result, avoid_arena);
   tsd_setspecific(arena_key, (void *)result);
   THREAD_STAT(++(result->stat_lock_loop));
   next_to_use = result->next;
@@ -891,6 +894,7 @@ arena_get2(mstate a_tsd, size_t size, mstate avoid_arena)
       if (retried)
 	(void)mutex_unlock(&list_lock);
       THREAD_STAT(++(a->stat_lock_loop));
+      LIBC_PROBE (malloc_arena_reuse, 2, a, a_tsd);
       tsd_setspecific(arena_key, (void *)a);
       return a;
     }
@@ -903,6 +907,7 @@ arena_get2(mstate a_tsd, size_t size, mstate avoid_arena)
      locks. */
   if(!retried && mutex_trylock(&list_lock)) {
     /* We will block to not run in a busy loop.  */
+    LIBC_PROBE (malloc_arena_reuse_wait, 3, &list_lock, NULL, a_tsd);
     (void)mutex_lock(&list_lock);
 
     /* Since we blocked there might be an arena available now.  */
diff --git a/malloc/malloc.c b/malloc/malloc.c
index bb9f984..00e968a 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -3002,6 +3002,7 @@ __libc_realloc(void* oldmem, size_t bytes)
 #endif
 
 #if !defined PER_THREAD
+  LIBC_PROBE (malloc_arena_reuse_realloc, 1, ar_ptr);
   /* As in malloc(), remember this arena for the next allocation. */
   tsd_setspecific(arena_key, (void *)ar_ptr);
 #endif
diff --git a/manual/memory.texi b/manual/memory.texi
index c074fc6..c995dfb 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -1039,6 +1039,66 @@ located at @var{$arg1}, within a newly-allocated heap big enough to hold
 at least @var{$arg2} bytes.
 @end deftp
 
+@deftp Probe malloc_arena_reuse (void *@var{$arg1}, void *@var{$arg2})
+This probe is hit when @code{malloc} has just selected an existing arena
+to reuse, and (temporarily) reserved it for exclusive use.  Argument
+@var{$arg1} is a pointer to the newly-selected arena, and @var{$arg2} is
+a pointer to the arena previously used by that thread.  
+
+When per-thread arenas are enabled, this occurs within
+@code{reused_arena}, right after the mutex mentioned in probe
+@code{malloc_arena_reuse_wait} is acquired; argument @var{$arg1} will
+point to the same arena.  In this configuration, this will usually only
+occur once per thread.  The exception is when a thread first selected
+the main arena, but a subsequent allocation from it fails: then, and
+only then, may we switch to another arena to retry that allocations, and
+for further allocations within that thread.
+
+When per-thread arenas are disabled, this occurs within
+@code{arena_get2}, whenever the mutex for the previously-selected arena
+cannot be immediately acquired.
+@end deftp
+
+@deftp Probe malloc_arena_reuse_wait (void *@var{$arg1}, void *@var{$arg2}, void *@var{$arg3})
+This probe is hit when @code{malloc} is about to wait for an arena to
+become available for reuse.  Argument @var{$arg1} holds a pointer to the
+mutex the thread is going to wait on, @var{$arg2} is a pointer to a
+newly-chosen arena to be reused, and @var{$arg3} is a pointer to the
+arena previously used by that thread.
+
+When per-thread arenas are enabled, this occurs within
+@code{reused_arena}, when a thread first tries to allocate memory or
+needs a retry after a failure to allocate from the main arena, there
+isn't any free arena, the maximum number of arenas has been reached, and
+an existing arena was chosen for reuse, but its mutex could not be
+immediately acquired.  The mutex in @var{$arg1} is the mutex of the
+selected arena.
+
+When per-thread arenas are disabled, this occurs within
+@code{arena_get2}, when a thread first tries to allocate memory or the
+mutex of the arena it previously used could not be immediately acquired,
+and none of the existing arenas could be immediately reserved for
+exclusive use.  The mutex in @var{$arg1} is that of the list of arenas,
+and since the arena won't have been selected yet, @var{$arg2} will be
+@code{NULL}.
+@end deftp
+
+@deftp Probe malloc_arena_reuse_free_list (void *@var{$arg1})
+This probe is hit when @code{malloc} has chosen an arena that is in the
+free list for use by a thread, within the @code{get_free_list} function.
+This probe is only available when @code{malloc} is configured to use
+per-thread arenas.  The argument @var{$arg1} holds a pointer to the
+selected arena.
+@end deftp
+
+@deftp Probe malloc_arena_reuse_realloc (void *@var{$arg1})
+This probe is hit within @code{realloc}, as the arena of the current
+thread is changed to match that in which the given address was
+allocated.  This probe is not available when @code{malloc} is configured
+to use per-thread arenas.  The argument @var{$arg1} holds a pointer to
+the newly-selected arena.
+@end deftp
+
 @deftp Probe mallopt (int @var{$arg1}, int @var{$arg2})
 This probe is hit when function @code{mallopt} is called to change
 @code{malloc} internal configuration parameters, before any change to
Add probes for malloc retries.

From: Alexandre Oliva <aoliva@redhat.com>

for ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* malloc/malloc.c (__libc_malloc): Add malloc_retry probe.
	(__libc_realloc): Add realloc_retry probe.
	(__libc_memalign): Add memalign_retry probe.
	(__libc_valloc): Add valloc_retry probe.
	(__libc_pvalloc): Add pvalloc_retry probe.
	(__libc_calloc): Add calloc_retry probe.
	* manual/malloc.texi: Document them.
---

 malloc/malloc.c    |    6 ++++++
 manual/memory.texi |   20 ++++++++++++++++++++
 2 files changed, 26 insertions(+), 0 deletions(-)


diff --git a/malloc/malloc.c b/malloc/malloc.c
index 00e968a..3af5d3c 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2881,6 +2881,7 @@ __libc_malloc(size_t bytes)
     return 0;
   victim = _int_malloc(ar_ptr, bytes);
   if(!victim) {
+    LIBC_PROBE (malloc_retry, 1, bytes);
     ar_ptr = get_another_arena(ar_ptr, bytes);
     if (__builtin_expect(ar_ptr != NULL, 1)) {
       victim = _int_malloc(ar_ptr, bytes);
@@ -3016,6 +3017,7 @@ __libc_realloc(void* oldmem, size_t bytes)
   if (newp == NULL)
     {
       /* Try harder to allocate memory in other arenas.  */
+      LIBC_PROBE (realloc_retry, 2, bytes, oldmem);
       newp = __libc_malloc(bytes);
       if (newp != NULL)
 	{
@@ -3051,6 +3053,7 @@ __libc_memalign(size_t alignment, size_t bytes)
     return 0;
   p = _int_memalign(ar_ptr, alignment, bytes);
   if(!p) {
+    LIBC_PROBE (memalign_retry, 2, bytes, alignment);
     ar_ptr = get_another_arena (ar_ptr, bytes);
     if (__builtin_expect(ar_ptr != NULL, 1)) {
       p = _int_memalign(ar_ptr, alignment, bytes);
@@ -3088,6 +3091,7 @@ __libc_valloc(size_t bytes)
     return 0;
   p = _int_valloc(ar_ptr, bytes);
   if(!p) {
+    LIBC_PROBE (valloc_retry, 1, bytes);
     ar_ptr = get_another_arena (ar_ptr, bytes);
     if (__builtin_expect(ar_ptr != NULL, 1)) {
       p = _int_memalign(ar_ptr, pagesz, bytes);
@@ -3123,6 +3127,7 @@ __libc_pvalloc(size_t bytes)
   arena_get(ar_ptr, bytes + 2*pagesz + MINSIZE);
   p = _int_pvalloc(ar_ptr, bytes);
   if(!p) {
+    LIBC_PROBE (pvalloc_retry, 1, bytes);
     ar_ptr = get_another_arena (ar_ptr, bytes + 2*pagesz + MINSIZE);
     if (__builtin_expect(ar_ptr != NULL, 1)) {
       p = _int_memalign(ar_ptr, pagesz, rounded_bytes);
@@ -3199,6 +3204,7 @@ __libc_calloc(size_t n, size_t elem_size)
 	 av == arena_for_chunk(mem2chunk(mem)));
 
   if (mem == 0) {
+    LIBC_PROBE (calloc_retry, 1, sz);
     av = get_another_arena (av, sz);
     if (__builtin_expect(av != NULL, 1)) {
       mem = _int_malloc(av, sz);
diff --git a/manual/memory.texi b/manual/memory.texi
index c995dfb..c2abdad 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -1030,6 +1030,26 @@ These are nearly-zero-overhead probes available for monitoring internal
 @code{libc} provider.  The probes assume a reasonable knowledge of the
 @code{malloc} implementation.
 
+@deftp Probe malloc_retry (size_t @var{$arg1})
+@deftpx Probe realloc_retry (size_t @var{$arg1}, void *@var{$arg2})
+@deftpx Probe memalign_retry (size_t @var{$arg1}, size_t @var{$arg2})
+@deftpx Probe valloc_retry (size_t @var{$arg1})
+@deftpx Probe pvalloc_retry (size_t @var{$arg1})
+@deftpx Probe calloc_retry (size_t @var{$arg1})
+These probes are hit when the corresponding functions fail to obtain the
+requested amount of memory from the arena in use, before it retries on
+another arena.  Argument @var{$arg1} is the amount of memory requested
+by the user; in the @code{calloc} case, that is the total size computed
+from both function arguments.  In the @code{realloc} case, @var{$arg2}
+is the pointer to the memory area being resized.  In the @code{memalign}
+case, @var{$arg2} is the alignment to be used for the request, which may
+be stricter than the value passed to the @code{memalign} function.
+
+Note that the argument order does NOT match that of the corresponding
+two-argument functions, so that in all of these probes the
+user-requested allocation size is in @var{$arg1}.
+@end deftp
+
 @deftp Probe malloc_arena_new (void *@var{$arg1}, size_t @var{$arg2})
 This probe is hit when @code{malloc} allocated and initialized an
 additional allocation arena (not the main arena), but before it is
Add catch-all alloc retry probe.

From: Alexandre Oliva <aoliva@redhat.com>

for ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* malloc/malloc.c (get_another_arena): Add malloc_all_retry
	probe.
	* manual/malloc.texi: Document it.
---

 malloc/malloc.c    |    1 +
 manual/memory.texi |   12 ++++++++++++
 2 files changed, 13 insertions(+), 0 deletions(-)


diff --git a/malloc/malloc.c b/malloc/malloc.c
index 3af5d3c..1a56a34 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2847,6 +2847,7 @@ mremap_chunk(mchunkptr p, size_t new_size)
 static mstate
 get_another_arena(mstate ar_ptr, size_t bytes)
 {
+  LIBC_PROBE (malloc_all_retry, 2, bytes, ar_ptr);
   if(ar_ptr != &main_arena) {
     (void)mutex_unlock(&ar_ptr->mutex);
     ar_ptr = &main_arena;
diff --git a/manual/memory.texi b/manual/memory.texi
index c2abdad..4414e1e 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -1050,6 +1050,18 @@ two-argument functions, so that in all of these probes the
 user-requested allocation size is in @var{$arg1}.
 @end deftp
 
+@deftp Probe malloc_all_retry (size_t @var{$arg1}, void *@var{$arg2})
+This probe is hit within @code{get_another_arena}, the function used by
+all of the corresponding functions above to select the alternate arena
+in which to retry the allocation, before the selection takes place.
+This probe is redundant, but much easier to use when it's not important
+to determine which memory allocation functions are failing to allocate
+in the first try.  Argument @var{$arg1} is the same as in the
+function-specific probes, except for extra room for padding introduced
+by functions that have to ensure stricter alignment.  Argument
+@var{$arg2} is the arena in which allocation failed.
+@end deftp
+
 @deftp Probe malloc_arena_new (void *@var{$arg1}, size_t @var{$arg2})
 This probe is hit when @code{malloc} allocated and initialized an
 additional allocation arena (not the main arena), but before it is
Add malloc probes for sbrk and heap resizing.

From: Alexandre Oliva <aoliva@redhat.com>

for ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* malloc/arena.c (new_heap): New heap_new probe.
	(grow_heap): New heap_more probe.
	(shrink_heap): New heap_less probe.
	(heap_trim): New heap_free probe.
	* malloc/malloc.c (sysmalloc): New sbrk_more probe.
	(systrim): New sbrk_less probe.
	* manual/malloc.texi: Document them.
---

 malloc/arena.c     |    4 ++++
 malloc/malloc.c    |    6 +++++-
 manual/memory.texi |   40 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 1 deletions(-)


diff --git a/malloc/arena.c b/malloc/arena.c
index 0828456..9ef0b7c 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -584,6 +584,7 @@ new_heap(size_t size, size_t top_pad)
   h->size = size;
   h->mprotect_size = size;
   THREAD_STAT(stat_n_heaps++);
+  LIBC_PROBE (heap_new, 2, h, h->size);
   return h;
 }
 
@@ -609,6 +610,7 @@ grow_heap(heap_info *h, long diff)
   }
 
   h->size = new_size;
+  LIBC_PROBE (heap_more, 2, h, h->size);
   return 0;
 }
 
@@ -636,6 +638,7 @@ shrink_heap(heap_info *h, long diff)
   /*fprintf(stderr, "shrink %p %08lx\n", h, new_size);*/
 
   h->size = new_size;
+  LIBC_PROBE (heap_less, 2, h, h->size);
   return 0;
 }
 
@@ -673,6 +676,7 @@ heap_trim(heap_info *heap, size_t pad)
       break;
     ar_ptr->system_mem -= heap->size;
     arena_mem -= heap->size;
+    LIBC_PROBE (heap_free, 2, heap, heap->size);
     delete_heap(heap);
     heap = prev_heap;
     if(!prev_inuse(p)) { /* consolidate backward */
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 1a56a34..c229048 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2452,8 +2452,10 @@ static void* sysmalloc(INTERNAL_SIZE_T nb, mstate av)
     below even if we cannot call MORECORE.
   */
 
-  if (size > 0)
+  if (size > 0) {
     brk = (char*)(MORECORE(size));
+    LIBC_PROBE (sbrk_more, 2, brk, size);
+  }
 
   if (brk != (char*)(MORECORE_FAILURE)) {
     /* Call the `morecore' hook if necessary.  */
@@ -2751,6 +2753,8 @@ static int systrim(size_t pad, mstate av)
 	(*hook) ();
       new_brk = (char*)(MORECORE(0));
 
+      LIBC_PROBE (sbrk_less, 2, new_brk, extra);
+
       if (new_brk != (char*)MORECORE_FAILURE) {
 	released = (long)(current_brk - new_brk);
 
diff --git a/manual/memory.texi b/manual/memory.texi
index 4414e1e..decef95 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -1030,6 +1030,46 @@ These are nearly-zero-overhead probes available for monitoring internal
 @code{libc} provider.  The probes assume a reasonable knowledge of the
 @code{malloc} implementation.
 
+@deftp Probe sbrk_more (void *@var{$arg1}, size_t @var{$arg2})
+This probe is hit after the main arena is extended by calling
+@code{sbrk}.  Argument @var{$arg1} is the additional size requested to
+@code{sbrk}, and @var{$arg2} is the pointer that marks the end of the
+@code{sbrk} area, returned in response to the request.
+@end deftp
+
+@deftp Probe sbrk_less (void *@var{$arg1}, size_t @var{$arg2})
+This probe is hit after the main arena is shortened by calling
+@code{sbrk}.  Argument @var{$arg1} is the size released by @code{sbrk}
+(the positive value, rather than the negated number passed to
+@code{sbrk}), and @var{$arg2} is the pointer that marks the end of the
+@code{sbrk} area, returned in response to the request.
+@end deftp
+
+@deftp Probe heap_new (void *@var{$arg1}, size_t @var{$arg2})
+This probe is hit after a new heap is @code{mmap}ed.  Argument
+@var{$arg1} is a pointer to the base of the memory area, where the
+@code{heap_info} data structure is held, and @var{$arg2} is the size of
+the heap.
+@end deftp
+
+@deftp Probe heap_free (void *@var{$arg1}, size_t @var{$arg2})
+This probe is hit before (unlike the other sbrk and heap probes) a heap
+is completely un@code{mmap}ped.  Argument @var{$arg1} is a pointer to
+the heap, and @var{$arg2} is the size of the heap.
+@end deftp
+
+@deftp Probe heap_less (void *@var{$arg1}, size_t @var{$arg2})
+This probe is hit after a trailing portion of an @code{mmap}ed heap is
+released.  Argument @var{$arg1} is a pointer to the heap, and
+@var{$arg2} is the new size of the heap.
+@end deftp
+
+@deftp Probe heap_more (void *@var{$arg1}, size_t @var{$arg2})
+This probe is hit after a trailing portion of an @code{mmap}ed heap is
+extended.  Argument @var{$arg1} is a pointer to the heap, and
+@var{$arg2} is the new size of the heap.
+@end deftp
+
 @deftp Probe malloc_retry (size_t @var{$arg1})
 @deftpx Probe realloc_retry (size_t @var{$arg1}, void *@var{$arg2})
 @deftpx Probe memalign_retry (size_t @var{$arg1}, size_t @var{$arg2})
-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist      Red Hat Brazil Compiler Engineer

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