Really fixes trac:2104. There is a lengthy discussion about this patch on
#2322. The short version is that this patch consolidates two pieces of code that call the back-end munmap and ensures that (if dlsym is used) the corresponding dlsym is only invoked once and that the variable holding the result is volatile. This commit was SVN r22863. The following Trac tickets were found above: Ticket 2104 --> https://svn.open-mpi.org/trac/ompi/ticket/2104
Этот коммит содержится в:
родитель
62e751a95c
Коммит
136f926fd1
@ -292,7 +292,6 @@ ptmalloc_unlock_all2 __MALLOC_P((void))
|
||||
|
||||
#endif /* !defined NO_THREADS */
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
/* Initialization routine. */
|
||||
#ifdef _LIBC
|
||||
@ -519,40 +518,8 @@ dump_heap(heap) heap_info *heap;
|
||||
|
||||
#endif /* MALLOC_DEBUG > 1 */
|
||||
|
||||
int
|
||||
munmap_real(void *start, size_t length)
|
||||
{
|
||||
#if !defined(HAVE___MUNMAP) && \
|
||||
!(defined(HAVE_SYSCALL) && defined(__NR_munmap)) && defined(HAVE_DLSYM)
|
||||
static int (*realmunmap)(void*, size_t);
|
||||
#endif
|
||||
|
||||
{
|
||||
extern bool opal_memory_ptmalloc2_munmap_invoked;
|
||||
opal_memory_ptmalloc2_munmap_invoked = true;
|
||||
}
|
||||
|
||||
|
||||
#if defined(HAVE___MUNMAP)
|
||||
return __munmap(start, length);
|
||||
#elif defined(HAVE_SYSCALL) && defined(__NR_munmap)
|
||||
return syscall(__NR_munmap, start, length);
|
||||
#elif defined(HAVE_DLSYM)
|
||||
if (NULL == realmunmap) {
|
||||
union {
|
||||
int (*munmap_fp)(void*, size_t);
|
||||
void *munmap_p;
|
||||
} tmp;
|
||||
|
||||
tmp.munmap_p = dlsym(RTLD_NEXT, "munmap");
|
||||
realmunmap = tmp.munmap_fp;
|
||||
}
|
||||
|
||||
return realmunmap(start, length);
|
||||
#else
|
||||
#error "Can not determine how to call munmap"
|
||||
#endif
|
||||
}
|
||||
extern int opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc, int run_hooks);
|
||||
|
||||
|
||||
/* Create a new heap. size is automatically rounded up to a multiple
|
||||
@ -589,8 +556,9 @@ new_heap(size, top_pad) size_t size, top_pad;
|
||||
if(p1 != MAP_FAILED) {
|
||||
p2 = (char *)(((unsigned long)p1 + (HEAP_MAX_SIZE-1)) & ~(HEAP_MAX_SIZE-1));
|
||||
ul = p2 - p1;
|
||||
munmap_real(p1, ul);
|
||||
munmap_real(p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul);
|
||||
opal_mem_free_ptmalloc2_munmap(p1, ul, 1, 0);
|
||||
opal_mem_free_ptmalloc2_munmap(p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul,
|
||||
1, 0);
|
||||
} else {
|
||||
/* Try to take the chance that an allocation of only HEAP_MAX_SIZE
|
||||
is already aligned. */
|
||||
@ -598,12 +566,12 @@ new_heap(size, top_pad) size_t size, top_pad;
|
||||
if(p2 == MAP_FAILED)
|
||||
return 0;
|
||||
if((unsigned long)p2 & (HEAP_MAX_SIZE-1)) {
|
||||
munmap_real(p2, HEAP_MAX_SIZE);
|
||||
opal_mem_free_ptmalloc2_munmap(p2, HEAP_MAX_SIZE, 1, 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(mprotect(p2, size, PROT_READ|PROT_WRITE) != 0) {
|
||||
munmap_real(p2, HEAP_MAX_SIZE);
|
||||
opal_mem_free_ptmalloc2_munmap(p2, HEAP_MAX_SIZE, 1, 0);
|
||||
return 0;
|
||||
}
|
||||
h = (heap_info *)p2;
|
||||
|
@ -30,14 +30,14 @@ opal_mem_free_ptmalloc2_sbrk(int inc)
|
||||
return sbrk(inc);
|
||||
}
|
||||
|
||||
extern int opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc);
|
||||
extern int opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc, int run_hooks);
|
||||
|
||||
/* if we are trying to catch only allocations from and releases to the
|
||||
operating system, intercept sbrk, mmap, and munmap. If we want to
|
||||
intercept every call to malloc/realloc/free/etc., don't do this, as
|
||||
we need to add something into each of those calls anyway. */
|
||||
#define MORECORE opal_mem_free_ptmalloc2_sbrk
|
||||
#define munmap(a,b) opal_mem_free_ptmalloc2_munmap(a,b,1)
|
||||
#define munmap(a,b) opal_mem_free_ptmalloc2_munmap(a,b,1,1)
|
||||
|
||||
/* make some non-GCC compilers happy */
|
||||
#ifndef __GNUC__
|
||||
|
@ -50,7 +50,7 @@ int __munmap(void* addr, size_t len);
|
||||
OPAL_DECLSPEC int
|
||||
munmap(void* addr, size_t len)
|
||||
{
|
||||
return opal_mem_free_ptmalloc2_munmap(addr, len, 0);
|
||||
return opal_mem_free_ptmalloc2_munmap(addr, len, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -59,36 +59,43 @@ munmap(void* addr, size_t len)
|
||||
possible, try calling __munmap from munmap and let __munmap go. If
|
||||
that doesn't work, try dlsym */
|
||||
int
|
||||
opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc)
|
||||
opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc,
|
||||
int call_hooks)
|
||||
{
|
||||
#if !defined(HAVE___MUNMAP) && \
|
||||
!(defined(HAVE_SYSCALL) && defined(__NR_munmap)) && defined(HAVE_DLSYM)
|
||||
static int (*realmunmap)(void*, size_t);
|
||||
#endif
|
||||
|
||||
{
|
||||
extern bool opal_memory_ptmalloc2_munmap_invoked;
|
||||
opal_memory_ptmalloc2_munmap_invoked = true;
|
||||
}
|
||||
|
||||
opal_mem_hooks_release_hook(start, length, from_alloc);
|
||||
if (call_hooks) {
|
||||
opal_mem_hooks_release_hook(start, length, from_alloc);
|
||||
}
|
||||
|
||||
#if defined(HAVE___MUNMAP)
|
||||
return __munmap(start, length);
|
||||
#elif defined(HAVE_SYSCALL) && defined(__NR_munmap)
|
||||
return syscall(__NR_munmap, start, length);
|
||||
#elif defined(HAVE_DLSYM)
|
||||
if (NULL == realmunmap) {
|
||||
union {
|
||||
int (*munmap_fp)(void*, size_t);
|
||||
void *munmap_p;
|
||||
} tmp;
|
||||
{
|
||||
/* Must use a typedef here because we need volatile to be an
|
||||
attribute of the variable, not the function (which would be
|
||||
meaningless, anyway). */
|
||||
typedef int (*munmap_fn_t)(void*, size_t);
|
||||
static volatile munmap_fn_t realmunmap = NULL;
|
||||
|
||||
tmp.munmap_p = dlsym(RTLD_NEXT, "munmap");
|
||||
realmunmap = tmp.munmap_fp;
|
||||
if (NULL == realmunmap) {
|
||||
union {
|
||||
int (*munmap_fp)(void*, size_t);
|
||||
void *munmap_p;
|
||||
} tmp;
|
||||
|
||||
tmp.munmap_p = dlsym(RTLD_NEXT, "munmap");
|
||||
realmunmap = tmp.munmap_fp;
|
||||
++count;
|
||||
}
|
||||
|
||||
return realmunmap(start, length);
|
||||
}
|
||||
|
||||
return realmunmap(start, length);
|
||||
#else
|
||||
#error "Can not determine how to call munmap"
|
||||
#endif
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
OPAL_DECLSPEC int opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc);
|
||||
OPAL_DECLSPEC int opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc, int call_hooks);
|
||||
|
||||
OPAL_DECLSPEC int munmap(void* addr, size_t len);
|
||||
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user