raster pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=f32f0d89f4c42080ff28d2b5a201f6ce8e0206b1
commit f32f0d89f4c42080ff28d2b5a201f6ce8e0206b1 Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com> Date: Fri Jan 12 02:59:34 2018 +0900 mmap memory allocation - do not used when under valgrind we can't sensibly use things like massif to track memory if we bypass itr with mmaping -1 fd anonymous memory... so if built with valgrind support and running under valgrind, use malloc/calloc and free so these tools actually do something useful for these bits of memory. --- src/lib/eina/eina_debug_chunk.c | 23 ++++++++-- src/lib/eina/eina_evlog.c | 33 ++++++++++---- src/lib/eina/eina_safepointer.c | 83 ++++++++++++++++++++++------------- src/lib/eo/eo.c | 46 ++++++++++++++----- src/lib/eo/eo_add_fallback.c | 39 +++++++++++----- src/lib/eo/eo_ptr_indirection.x | 81 ++++++++++++++++++++++------------ src/lib/evas/common/evas_image_main.c | 5 +++ 7 files changed, 214 insertions(+), 96 deletions(-) diff --git a/src/lib/eina/eina_debug_chunk.c b/src/lib/eina/eina_debug_chunk.c index 36629198a0..4ee9655140 100644 --- a/src/lib/eina/eina_debug_chunk.c +++ b/src/lib/eina/eina_debug_chunk.c @@ -24,6 +24,11 @@ # include "config.h" # endif +#ifdef HAVE_VALGRIND +# include <valgrind.h> +# include <memcheck.h> +#endif + #ifdef HAVE_MMAP # include <sys/mman.h> @@ -50,9 +55,15 @@ _eina_debug_chunk_need(int size) { void *ptr; - ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); - if (ptr == MAP_FAILED) return NULL; +#ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) ptr = malloc(size); + else +#endif + { + ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (ptr == MAP_FAILED) return NULL; + } return ptr; } @@ -60,7 +71,11 @@ _eina_debug_chunk_need(int size) static void _eina_debug_chunk_noneed(void *ptr, int size) { - munmap(ptr, size); +#ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) free(ptr); + else +#endif + munmap(ptr, size); } // push a new bit of mem on our growing stack of mem - given our workload, diff --git a/src/lib/eina/eina_evlog.c b/src/lib/eina/eina_evlog.c index 9c9cbccdaf..3e5f3c55f2 100644 --- a/src/lib/eina/eina_evlog.c +++ b/src/lib/eina/eina_evlog.c @@ -20,6 +20,11 @@ # include "config.h" #endif +#ifdef HAVE_VALGRIND +# include <valgrind.h> +# include <memcheck.h> +#endif + #include "Eina.h" #include "eina_evlog.h" #include "eina_debug.h" @@ -97,13 +102,19 @@ alloc_buf(Eina_Evlog_Buf *b, unsigned int size) if (b->buf) return; b->size = size; b->top = 0; -# ifdef HAVE_MMAP - b->buf = mmap(NULL, size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); - if (b->buf == MAP_FAILED) b->buf = NULL; -# else - b->buf = malloc(size); +#ifdef HAVE_MMAP +# ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) b->buf = malloc(size); + else # endif + { + b->buf = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (b->buf == MAP_FAILED) b->buf = NULL; + } +#else + b->buf = malloc(size); +#endif b->overflow = 0; } @@ -111,11 +122,15 @@ static void free_buf(Eina_Evlog_Buf *b) { if (!b->buf) return; -# ifdef HAVE_MMAP +#ifdef HAVE_MMAP +# ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) free(b->buf); + else +# endif munmap(b->buf, b->size); -# else +#else free(b->buf); -# endif +#endif b->buf = NULL; b->size = 0; b->top = 0; diff --git a/src/lib/eina/eina_safepointer.c b/src/lib/eina/eina_safepointer.c index 94ec1ab557..1a19f851c7 100644 --- a/src/lib/eina/eina_safepointer.c +++ b/src/lib/eina/eina_safepointer.c @@ -2,6 +2,11 @@ # include "config.h" #endif +#ifdef HAVE_VALGRIND +# include <valgrind.h> +# include <memcheck.h> +#endif + #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -66,26 +71,32 @@ static void * _eina_safepointer_calloc(int number, size_t size) { #ifdef HAVE_MMAP - Eina_Memory_Header *header; - size_t newsize; +# ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) return calloc(number, size); + else +# endif + { + Eina_Memory_Header *header; + size_t newsize; - size = size * number + sizeof (Eina_Memory_Header); - newsize = ((size / MEM_PAGE_SIZE) + - (size % MEM_PAGE_SIZE ? 1 : 0)) - * MEM_PAGE_SIZE; + size = size * number + sizeof (Eina_Memory_Header); + newsize = ((size / MEM_PAGE_SIZE) + + (size % MEM_PAGE_SIZE ? 1 : 0)) + * MEM_PAGE_SIZE; - header = mmap(NULL, newsize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); - if (header == MAP_FAILED) - { - ERR("mmap of Eina_Safepointer table region failed."); - return NULL; - } + header = mmap(NULL, newsize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (header == MAP_FAILED) + { + ERR("mmap of Eina_Safepointer table region failed."); + return NULL; + } - header->size = newsize; - EINA_MAGIC_SET(header, SAFEPOINTER_MAGIC); + header->size = newsize; + EINA_MAGIC_SET(header, SAFEPOINTER_MAGIC); - return (void*)(header + 1); + return (void *)(header + 1); + } #else return calloc(number, size); #endif @@ -95,18 +106,24 @@ static void _eina_safepointer_free(void *pointer) { #ifdef HAVE_MMAP - Eina_Memory_Header *header; +# ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) free((void *)((uintptr_t) pointer & ~0x3)); + else +# endif + { + Eina_Memory_Header *header; - if (!pointer) return ; + if (!pointer) return; - header = (Eina_Memory_Header*)(pointer) - 1; - if (!EINA_MAGIC_CHECK(header, SAFEPOINTER_MAGIC)) - EINA_MAGIC_FAIL(header, SAFEPOINTER_MAGIC); + header = (Eina_Memory_Header*)(pointer) - 1; + if (!EINA_MAGIC_CHECK(header, SAFEPOINTER_MAGIC)) + EINA_MAGIC_FAIL(header, SAFEPOINTER_MAGIC); - EINA_MAGIC_SET(header, 0); - munmap(header, header->size); + EINA_MAGIC_SET(header, 0); + munmap(header, header->size); + } #else - free((void*) ((uintptr_t) pointer & ~0x3)); + free((void *)((uintptr_t) pointer & ~0x3)); #endif } @@ -115,15 +132,21 @@ static void _eina_safepointer_protect(void *pointer, Eina_Bool may_not_write) { #ifdef HAVE_MMAP - Eina_Memory_Header *header; +# ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) { (void) pointer; } + else +# endif + { + Eina_Memory_Header *header; - if (!pointer) return ; + if (!pointer) return; - header = (Eina_Memory_Header*)(pointer) - 1; - if (!EINA_MAGIC_CHECK(header, SAFEPOINTER_MAGIC)) - EINA_MAGIC_FAIL(header, SAFEPOINTER_MAGIC); + header = (Eina_Memory_Header*)(pointer) - 1; + if (!EINA_MAGIC_CHECK(header, SAFEPOINTER_MAGIC)) + EINA_MAGIC_FAIL(header, SAFEPOINTER_MAGIC); - mprotect(header, header->size, PROT_READ | ( may_not_write ? 0 : PROT_WRITE)); + mprotect(header, header->size, PROT_READ | ( may_not_write ? 0 : PROT_WRITE)); + } #else (void) pointer; #endif diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index d421c58bc8..50df250acf 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -1383,10 +1383,16 @@ static inline void _eo_classes_release(void) { #ifdef HAVE_MMAP - size_t size; +# ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) free(_eo_classes); + else +# endif + { + size_t size; - size = _eo_classes_alloc * sizeof(_Efl_Class *); - if (_eo_classes) munmap(_eo_classes, size); + size = _eo_classes_alloc * sizeof(_Efl_Class *); + if (_eo_classes) munmap(_eo_classes, size); + } #else free(_eo_classes); #endif @@ -1405,17 +1411,33 @@ _eo_classes_expand(void) if (_eo_classes_last_id <= _eo_classes_alloc) return; psize = _eo_classes_alloc * sizeof(_Efl_Class *); #ifdef HAVE_MMAP - _eo_classes_alloc += (MEM_PAGE_SIZE / sizeof(_Efl_Class *)); - newsize = _eo_classes_alloc * sizeof(_Efl_Class *); - ptr = mmap(NULL, newsize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); - if (ptr == MAP_FAILED) +# ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) { - ERR("mmap of eo class table region failed!"); - abort(); + _eo_classes_alloc += 128; + newsize = _eo_classes_alloc * sizeof(_Efl_Class *); + ptr = realloc(_eo_classes, newsize); + if (!ptr) + { + ERR("realloc of eo class table region faile!!"); + abort(); + } + } + else +# endif + { + _eo_classes_alloc += (MEM_PAGE_SIZE / sizeof(_Efl_Class *)); + newsize = _eo_classes_alloc * sizeof(_Efl_Class *); + ptr = mmap(NULL, newsize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (ptr == MAP_FAILED) + { + ERR("mmap of eo class table region failed!"); + abort(); + } + if (psize > 0) memcpy(ptr, _eo_classes, psize); + if (_eo_classes) munmap(_eo_classes, psize); } - if (psize > 0) memcpy(ptr, _eo_classes, psize); - if (_eo_classes) munmap(_eo_classes, psize); #else _eo_classes_alloc += 128; newsize = _eo_classes_alloc * sizeof(_Efl_Class *); diff --git a/src/lib/eo/eo_add_fallback.c b/src/lib/eo/eo_add_fallback.c index c38a827b28..f3a82f25d6 100644 --- a/src/lib/eo/eo_add_fallback.c +++ b/src/lib/eo/eo_add_fallback.c @@ -2,6 +2,11 @@ # include <config.h> #endif +#ifdef HAVE_VALGRIND +# include <valgrind.h> +# include <memcheck.h> +#endif + #if defined HAVE_DLADDR && ! defined _WIN32 # include <dlfcn.h> #endif @@ -32,20 +37,26 @@ static void * _eo_call_stack_mem_alloc(size_t size) { #ifdef HAVE_MMAP - // allocate eo call stack via mmped anon segment if on linux - more - // secure and safe. also gives page aligned memory allowing madvise - void *ptr; - size_t newsize; - newsize = MEM_PAGE_SIZE * ((size + MEM_PAGE_SIZE - 1) / - MEM_PAGE_SIZE); - ptr = mmap(NULL, newsize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); - if (ptr == MAP_FAILED) +# ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) return calloc(1, size); + else +# endif { - ERR("eo call stack mmap failed."); - return NULL; + // allocate eo call stack via mmped anon segment if on linux - more + // secure and safe. also gives page aligned memory allowing madvise + void *ptr; + size_t newsize; + newsize = MEM_PAGE_SIZE * ((size + MEM_PAGE_SIZE - 1) / + MEM_PAGE_SIZE); + ptr = mmap(NULL, newsize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (ptr == MAP_FAILED) + { + ERR("eo call stack mmap failed."); + return NULL; + } + return ptr; } - return ptr; #else //in regular cases just use malloc return calloc(1, size); @@ -56,6 +67,10 @@ static void _eo_call_stack_mem_free(void *ptr, size_t size) { #ifdef HAVE_MMAP +# ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) free(ptr); + else +# endif munmap(ptr, size); #else (void) size; diff --git a/src/lib/eo/eo_ptr_indirection.x b/src/lib/eo/eo_ptr_indirection.x index f4311e1c3a..d6affe0cc6 100644 --- a/src/lib/eo/eo_ptr_indirection.x +++ b/src/lib/eo/eo_ptr_indirection.x @@ -6,6 +6,11 @@ #include <sys/mman.h> #endif +#ifdef HAVE_VALGRIND +# include <valgrind.h> +# include <memcheck.h> +#endif + /* Start of pointer indirection: * * This feature is responsible of hiding from the developer the real pointer of @@ -149,23 +154,29 @@ static void * _eo_id_mem_alloc(size_t size) { #ifdef HAVE_MMAP - void *ptr; - Mem_Header *hdr; - size_t newsize; - newsize = MEM_PAGE_SIZE * ((size + MEM_HEADER_SIZE + MEM_PAGE_SIZE - 1) / - MEM_PAGE_SIZE); - ptr = mmap(NULL, newsize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); - if (ptr == MAP_FAILED) +# ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) return malloc(size); + else +# endif { - ERR("mmap of eo id table region failed!"); - return NULL; + void *ptr; + Mem_Header *hdr; + size_t newsize; + newsize = MEM_PAGE_SIZE * ((size + MEM_HEADER_SIZE + MEM_PAGE_SIZE - 1) / + MEM_PAGE_SIZE); + ptr = mmap(NULL, newsize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (ptr == MAP_FAILED) + { + ERR("mmap of eo id table region failed!"); + return NULL; + } + hdr = ptr; + hdr->size = newsize; + hdr->magic = MEM_MAGIC; + /* DBG("asked:%lu allocated:%lu wasted:%lu bytes", size, newsize, (newsize - size)); */ + return (void *)(((unsigned char *)ptr) + MEM_HEADER_SIZE); } - hdr = ptr; - hdr->size = newsize; - hdr->magic = MEM_MAGIC; - /* DBG("asked:%lu allocated:%lu wasted:%lu bytes", size, newsize, (newsize - size)); */ - return (void *)(((unsigned char *)ptr) + MEM_HEADER_SIZE); #else return malloc(size); #endif @@ -184,15 +195,21 @@ static void _eo_id_mem_free(void *ptr) { #ifdef HAVE_MMAP - Mem_Header *hdr; - if (!ptr) return; - hdr = (Mem_Header *)(((unsigned char *)ptr) - MEM_HEADER_SIZE); - if (hdr->magic != MEM_MAGIC) +# ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) free(ptr); + else +# endif { - ERR("unmap of eo table region has bad magic!"); - return; + Mem_Header *hdr; + if (!ptr) return; + hdr = (Mem_Header *)(((unsigned char *)ptr) - MEM_HEADER_SIZE); + if (hdr->magic != MEM_MAGIC) + { + ERR("unmap of eo table region has bad magic!"); + return; + } + munmap(hdr, hdr->size); } - munmap(hdr, hdr->size); #else free(ptr); #endif @@ -203,15 +220,21 @@ static void _eo_id_mem_protect(void *ptr, Eina_Bool may_not_write) { # ifdef HAVE_MMAP - Mem_Header *hdr; - if (!ptr) return; - hdr = (Mem_Header *)(((unsigned char *)ptr) - MEM_HEADER_SIZE); - if (hdr->magic != MEM_MAGIC) +# ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) { return; } + else +# endif { - ERR("mprotect of eo table region has bad magic!"); - return; + Mem_Header *hdr; + if (!ptr) return; + hdr = (Mem_Header *)(((unsigned char *)ptr) - MEM_HEADER_SIZE); + if (hdr->magic != MEM_MAGIC) + { + ERR("mprotect of eo table region has bad magic!"); + return; + } + mprotect(hdr, hdr->size, PROT_READ | ( may_not_write ? 0 : PROT_WRITE) ); } - mprotect(hdr, hdr->size, PROT_READ | ( may_not_write ? 0 : PROT_WRITE) ); # endif } # define PROTECT(_ptr_) _eo_id_mem_protect((_ptr_), EINA_TRUE) diff --git a/src/lib/evas/common/evas_image_main.c b/src/lib/evas/common/evas_image_main.c index 591f82fb99..404c70b566 100644 --- a/src/lib/evas/common/evas_image_main.c +++ b/src/lib/evas/common/evas_image_main.c @@ -17,6 +17,7 @@ //#include "evas_cs.h" #ifdef HAVE_VALGRIND +# include <valgrind.h> # include <memcheck.h> #endif @@ -115,6 +116,10 @@ _evas_common_rgba_image_surface_size(unsigned int w, unsigned int h, int siz, block_size = 8; Eina_Bool reset_borders = EINA_TRUE; +#ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) evas_image_no_mmap = 1; +#endif + if (EINA_UNLIKELY(evas_image_no_mmap == -1)) { const char *s = getenv("EVAS_IMAGE_NO_MMAP"); --