60 #define __USE_XOPEN_EXTENDED 63 #include <sys/types.h> 72 #undef _XOPEN_SOURCE // avoid complaint about redefinition 73 #define _XOPEN_SOURCE 600 101 #if defined(__i386__) 102 #ifndef USE_SYS_GCTXT 103 #define USE_SYS_GCTXT 138 #define MEMLEAK_USE_HYBRID_LAYOUT 1 140 #define MEMLEAK_MAGIC 0x68706374 141 #define MEMLEAK_DEFAULT_PAGESIZE 4096 143 #define HPCRUN_MEMLEAK_PROB "HPCRUN_MEMLEAK_PROB" 144 #define DEFAULT_PROB 0.1 146 #ifdef HPCRUN_STATIC_LINK 147 #define real_memalign __real_memalign 148 #define real_valloc __real_valloc 149 #define real_malloc __real_malloc 150 #define real_free __real_free 151 #define real_realloc __real_realloc 153 #define real_memalign __libc_memalign 154 #define real_valloc __libc_valloc 155 #define real_malloc __libc_malloc 156 #define real_free __libc_free 157 #define real_realloc __libc_realloc 190 NULL,
"header",
"footer",
"none" 216 if (memleak_tree_root !=
NULL) {
217 memleak_tree_root =
splay(memleak_tree_root, memblock);
219 if (memblock < memleak_tree_root->memblock) {
220 node->
left = memleak_tree_root->
left;
223 }
else if (memblock > memleak_tree_root->
memblock) {
228 TMSG(MEMLEAK,
"memleak splay tree: unable to insert %p (already present)",
233 memleak_tree_root =
node;
244 if (memleak_tree_root ==
NULL) {
246 TMSG(MEMLEAK,
"memleak splay tree empty: unable to delete %p", memblock);
250 memleak_tree_root =
splay(memleak_tree_root, memblock);
252 if (memblock != memleak_tree_root->
memblock) {
254 TMSG(MEMLEAK,
"memleak splay tree: %p not in tree", memblock);
260 if (memleak_tree_root->
left ==
NULL) {
261 memleak_tree_root = memleak_tree_root->
right;
266 memleak_tree_root->
left =
splay(memleak_tree_root->
left, memblock);
268 memleak_tree_root = memleak_tree_root->
left;
286 if (strchr(str,
'/') !=
NULL) {
287 if (sscanf(str,
"%d/%d", &x, &y) == 2 && y > 0) {
288 ans = (float)x / (
float)y;
293 if (sscanf(str,
"%f", &ans) < 1) {
322 if (prob_str !=
NULL) {
328 fd = open(
"/dev/urandom", O_RDONLY);
330 read(fd, &seed,
sizeof(seed));
333 gettimeofday(&tv,
NULL);
334 seed += (getpid() << 16) + (tv.tv_usec << 4);
342 TMSG(MEMLEAK,
"init");
351 uintptr_t n1 = (uintptr_t) p1;
352 uintptr_t n2 = (uintptr_t) p2;
375 #if MEMLEAK_USE_HYBRID_LAYOUT 376 if ( (!
ENABLED(MEMLEAK_NO_HEADER)) && align == 0
387 *info_ptr = sys_ptr +
bytes;
402 #if MEMLEAK_USE_HYBRID_LAYOUT 407 && (*info_ptr)->memblock == appl_ptr) {
408 *sys_ptr = *info_ptr;
416 if (*info_ptr ==
NULL) {
420 && (*info_ptr)->memblock == appl_ptr) {
427 if (num_errors < 100) {
428 AMSG(
"MEMLEAK: Warning: memory corruption in leakinfo node: %p " 429 "sys: %p appl: %p magic: 0x%lx context: %p bytes: %ld memblock: %p",
430 *info_ptr, *sys_ptr, appl_ptr, (*info_ptr)->
magic, (*info_ptr)->context,
431 (*info_ptr)->bytes, (*info_ptr)->memblock);
448 if (info_ptr ==
NULL) {
449 TMSG(MEMLEAK,
"Warning: %s: bytes: %ld sys: %p appl: %p info: %p " 450 "(NULL leakinfo pointer, this should not happen)",
451 name, bytes, sys_ptr, appl_ptr, info_ptr);
469 loc_str =
"inactive";
475 TMSG(MEMLEAK,
"%s: bytes: %ld sys: %p appl: %p info: %p cct: %p (%s)",
476 name, bytes, sys_ptr, appl_ptr, info_ptr, info_ptr->
context, loc_str);
490 int clear, ucontext_t *
uc,
int *ret)
492 void *sys_ptr, *appl_ptr;
494 char *inactive_mesg =
"inactive";
498 TMSG(MEMLEAK,
"%s: bytes: %ld", name, bytes);
505 }
else if (
TD_GET(inside_dlfcn)) {
507 inactive_mesg =
"unable to monitor: inside dlfcn";
510 inactive_mesg =
"not sampled";
518 *ret = (sys_ptr ==
NULL) ? errno : 0;
523 if (clear && sys_ptr !=
NULL) {
524 memset(sys_ptr, 0, size);
529 TMSG(MEMLEAK,
"%s: bytes: %ld, sys: %p (%s)",
530 name, bytes, sys_ptr, inactive_mesg);
533 if (sys_ptr ==
NULL) {
534 TMSG(MEMLEAK,
"%s: bytes: %ld, sys: %p (failed)",
535 name, bytes, sys_ptr);
560 if (info_ptr ==
NULL) {
561 TMSG(MEMLEAK,
"%s: sys: %p appl: %p (no malloc)", name, sys_ptr, appl_ptr);
569 loc_str =
"inactive";
573 TMSG(MEMLEAK,
"%s: bytes: %ld sys: %p appl: %p info: %p cct: %p (%s)",
574 name, info_ptr->
bytes, sys_ptr, appl_ptr, info_ptr,
618 return (*memptr ==
NULL) ? errno : 0;
624 #else // ! USE_SYS_GCTXT 626 #endif // USE_SYS_GCTXT 647 #else // ! USE_SYS_GCTXT 649 #endif // USE_SYS_GCTXT 670 #else // ! USE_SYS_GCTXT 672 #endif // USE_SYS_GCTXT 693 #else // ! USE_SYS_GCTXT 695 #endif // USE_SYS_GCTXT 712 memset(ptr, 0, nmemb * bytes);
720 #else // ! USE_SYS_GCTXT 722 #endif // USE_SYS_GCTXT 747 TMSG(MEMLEAK,
"free: ptr: %p", ptr);
751 TMSG(MEMLEAK,
"free: ptr: %p (inactive)", ptr);
775 void *ptr2, *appl_ptr, *sys_ptr;
776 char *inactive_mesg =
"inactive";
777 int loc, loc2, active;
783 TMSG(MEMLEAK,
"realloc: ptr: %p bytes: %ld", ptr,
bytes);
792 #else // ! USE_SYS_GCTXT 794 #endif // USE_SYS_GCTXT 819 }
else if (
TD_GET(inside_dlfcn)) {
821 inactive_mesg =
"unable to monitor: inside dlfcn";
824 inactive_mesg =
"not sampled";
829 memmove(sys_ptr, ptr,
bytes);
832 TMSG(MEMLEAK,
"realloc: bytes: %ld ptr: %p (%s)",
833 bytes, appl_ptr, inactive_mesg);
845 memmove(ptr2, ptr2 + leakinfo_size,
bytes);
849 memmove(ptr2 + leakinfo_size, ptr,
bytes);
static struct leakinfo_s * splay_delete(void *memblock)
void *MONITOR_EXT_WRAP_NAME() realloc(void *ptr, size_t bytes)
int hpcrun_memleak_alloc_id()
static int memleak_get_malloc_loc(void *sys_ptr, size_t bytes, size_t align, void **appl_ptr, leakinfo_t **info_ptr)
int MONITOR_EXT_WRAP_NAME() posix_memalign(void **memptr, size_t alignment, size_t bytes)
static void * memleak_malloc_helper(const char *name, size_t bytes, size_t align, int clear, ucontext_t *uc, int *ret)
#define MEMLEAK_DEFAULT_PAGESIZE
static void splay_insert(struct leakinfo_s *node)
void * memalign_fcn(size_t, size_t)
static void hpcrun_safe_exit(void)
#define HPCRUN_MEMLEAK_PROB
sample_val_t hpcrun_sample_callpath(void *context, int metricId, hpcrun_metricVal_t metricIncr, int skipInner, int isSync, sampling_info_t *data)
static int use_memleak_prob
static float string_to_prob(char *str)
#define MONITOR_EXT_WRAP_NAME(name)
static void spinlock_unlock(spinlock_t *l)
static char * loc_name[4]
void * malloc_fcn(size_t)
#define REGULAR_SPLAY_TREE(type, root, key, value, left, right)
static struct leakinfo_s * splay(struct leakinfo_s *root, void *key)
static int memleak_get_free_loc(void *appl_ptr, void **sys_ptr, leakinfo_t **info_ptr)
static long memleak_pagesize
static float memleak_prob
int hpcrun_memleak_active()
void *MONITOR_EXT_WRAP_NAME() memalign(size_t boundary, size_t bytes)
static spinlock_t memtree_lock
void * valloc_fcn(size_t)
void *MONITOR_EXT_WRAP_NAME() calloc(size_t nmemb, size_t bytes)
void *MONITOR_EXT_WRAP_NAME() valloc(size_t bytes)
struct leakinfo_s leakinfo_t
static void spinlock_lock(spinlock_t *l)
void hpcrun_free_inc(cct_node_t *node, int incr)
ssize_t MONITOR_EXT_WRAP_NAME() read(int fd, void *buf, size_t count)
static int leak_detection_init
static int memleak_same_page(void *p1, void *p2)
void MONITOR_EXT_WRAP_NAME() free(void *ptr)
static void memleak_add_leakinfo(const char *name, void *sys_ptr, void *appl_ptr, leakinfo_t *info_ptr, size_t bytes, ucontext_t *uc, int loc)
static struct leakinfo_s * memleak_tree_root
static void memleak_initialize(void)
static int leak_detection_enabled
void * realloc_fcn(void *, size_t)
struct leakinfo_s * right
#define SPINLOCK_UNLOCKED
void *MONITOR_EXT_WRAP_NAME() malloc(size_t bytes)
static int hpcrun_safe_enter(void)
static void memleak_free_helper(const char *name, void *sys_ptr, void *appl_ptr, leakinfo_t *info_ptr, int loc)
#define INLINE_ASM_GCTXT(uc)