mirror of
https://github.com/cryb-to/cryb-to.git
synced 2024-12-22 04:21:08 +00:00
Emit jemalloc-compatible trace events if possible.
This commit is contained in:
parent
277201a4bb
commit
bd69c34a11
1 changed files with 47 additions and 2 deletions
49
t/t_malloc.c
49
t/t_malloc.c
|
@ -29,9 +29,14 @@
|
||||||
|
|
||||||
#include "cryb/impl.h"
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/param.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_UTRACE
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <sys/ktrace.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -44,7 +49,8 @@
|
||||||
* Very simple, non-thread-safe malloc() implementation tailored for unit
|
* Very simple, non-thread-safe malloc() implementation tailored for unit
|
||||||
* tests. The most important feature of this implementation is the
|
* tests. The most important feature of this implementation is the
|
||||||
* t_malloc_fail flag, which can be used to force malloc(), calloc() and
|
* t_malloc_fail flag, which can be used to force malloc(), calloc() and
|
||||||
* realloc() calls to fail.
|
* realloc() calls to fail. It also emits jemalloc-compatible trace
|
||||||
|
* records on platforms that have utrace(2).
|
||||||
*
|
*
|
||||||
* Allocations are satisfied either from a bucket or by direct mapping.
|
* Allocations are satisfied either from a bucket or by direct mapping.
|
||||||
* The allocation size is first rounded to the nearest power of two or 16,
|
* The allocation size is first rounded to the nearest power of two or 16,
|
||||||
|
@ -115,6 +121,40 @@ int t_malloc_fail;
|
||||||
/* if non-zero, unintentional allocation failures are fatal */
|
/* if non-zero, unintentional allocation failures are fatal */
|
||||||
int t_malloc_fatal;
|
int t_malloc_fatal;
|
||||||
|
|
||||||
|
#if HAVE_UTRACE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record malloc() / realloc() / free() events
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
trace_malloc_event(const void *o, size_t s, const void *p)
|
||||||
|
{
|
||||||
|
struct { const void *o; size_t s; const void *p; } mu = { o, s, p };
|
||||||
|
int serrno = errno;
|
||||||
|
|
||||||
|
(void)utrace(&mu, sizeof mu);
|
||||||
|
errno = serrno;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UTRACE_MALLOC(s, p) \
|
||||||
|
trace_malloc_event(NULL, (s), (p))
|
||||||
|
#define UTRACE_REALLOC(o, s, p) \
|
||||||
|
trace_malloc_event((o), (s), (p))
|
||||||
|
#define UTRACE_FREE(o) \
|
||||||
|
trace_malloc_event((o), 0, NULL)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define UTRACE_MALLOC(s, p) \
|
||||||
|
do { (void)(s); (void)(p); } while (0)
|
||||||
|
#define UTRACE_REALLOC(o, s, p) \
|
||||||
|
do { (void)(o); (void)(s); (void)(p); } while (0)
|
||||||
|
#define UTRACE_FREE(o) \
|
||||||
|
do { (void)(o); } while (0)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return a pointer to inaccessible memory.
|
* Return a pointer to inaccessible memory.
|
||||||
*/
|
*/
|
||||||
|
@ -251,6 +291,7 @@ malloc(size_t size)
|
||||||
abort();
|
abort();
|
||||||
memset(p, BUCKET_FILL_ALLOC, size);
|
memset(p, BUCKET_FILL_ALLOC, size);
|
||||||
/* XXX fill the slop with garbage */
|
/* XXX fill the slop with garbage */
|
||||||
|
UTRACE_MALLOC(size, p);
|
||||||
return (p);
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,6 +313,7 @@ calloc(size_t n, size_t size)
|
||||||
abort();
|
abort();
|
||||||
memset(p, 0, n * size);
|
memset(p, 0, n * size);
|
||||||
/* XXX fill the slop with garbage */
|
/* XXX fill the slop with garbage */
|
||||||
|
UTRACE_MALLOC(size, p);
|
||||||
return (p);
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,6 +371,7 @@ found:
|
||||||
else
|
else
|
||||||
memcpy(p, o, size);
|
memcpy(p, o, size);
|
||||||
/* XXX fill the slop with garbage */
|
/* XXX fill the slop with garbage */
|
||||||
|
UTRACE_REALLOC(o, size, p);
|
||||||
free(o);
|
free(o);
|
||||||
return (p);
|
return (p);
|
||||||
}
|
}
|
||||||
|
@ -346,6 +389,8 @@ free(void *p)
|
||||||
struct bucket *b;
|
struct bucket *b;
|
||||||
unsigned int shift;
|
unsigned int shift;
|
||||||
|
|
||||||
|
UTRACE_FREE(p);
|
||||||
|
|
||||||
/* was this a zero-size allocation? */
|
/* was this a zero-size allocation? */
|
||||||
if (p == buckets[0].base) {
|
if (p == buckets[0].base) {
|
||||||
++buckets[0].nfree;
|
++buckets[0].nfree;
|
||||||
|
|
Loading…
Reference in a new issue