- Add configure-time switch (--enable-ptmalloc2-opt-sbrk) to control when
the ptmalloc2 memory hooks component triggers callbacks for memory allocation / deallocation. If enabled (the default) it is only when memory is actually obtained from or released to the OS (so little malloc calls only trigger callbacks if sbrk is called). If disabled, callbacks are triggered every time malloc/free/etc. is called * It turns out that syscall and mmap aren't good friends due to the return type of mmap and some old legacy issues with syscall functions that take more than 5 parameters. For now, default to either loading the symbol from glibc using dlsym or using the __m{un,}map functions. Thanks to George for finding this. * Fix some dumb typos in the mmap / munmap catching code This commit was SVN r8410.
Этот коммит содержится в:
родитель
5232519235
Коммит
364ca3f075
@ -469,10 +469,15 @@ ptmalloc_init __MALLOC_P((void))
|
||||
/* don't use __hook for this, as someone might want to use those
|
||||
features */
|
||||
opal_mem_hooks_set_support(OPAL_MEMORY_FREE_SUPPORT |
|
||||
#if defined(HAVE_SYSCALL) || defined(HAVE___MMAP)
|
||||
#if defined(HAVE___MMAP) || defined(HAVE_DLSYM)
|
||||
OPAL_MEMORY_MALLOC_SUPPORT |
|
||||
#endif
|
||||
OPAL_MEMORY_CHUNK_SUPPORT);
|
||||
#if OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
OPAL_MEMORY_CHUNK_SUPPORT
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
);
|
||||
/********************* BEGIN OMPI CHANGES ******************************/
|
||||
|
||||
__malloc_initialized = 1;
|
||||
|
@ -33,6 +33,21 @@ AC_DEFUN([MCA_memory_ptmalloc2_CONFIG],[
|
||||
[Use TYPE for intercepting memory management
|
||||
calls to control memory pinning.])])
|
||||
|
||||
AC_ARG_ENABLE([ptmalloc2-opt-sbrk],
|
||||
[AC_HELP_STRING([--enable-ptmalloc2-opt-sbrk],
|
||||
[Only trigger callbacks when sbrk is used for small
|
||||
allocations, rather than every call to malloc/free.
|
||||
(default: enabled)])])
|
||||
|
||||
if test "$enable_ptmalloc2_opt_sbrk" = "no" ; then
|
||||
memory_ptmalloc2_opt_sbrk=0
|
||||
else
|
||||
memory_ptmalloc2_opt_sbrk=1
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED([OMPI_MEMORY_PTMALLOC2_OPT_SBRK],
|
||||
[$memory_ptmalloc2_opt_sbrk],
|
||||
[Trigger callbacks on sbrk instead of malloc or free])
|
||||
|
||||
AS_IF([test "$with_memory_manager" = "ptmalloc2"],
|
||||
[if test "`echo $host | grep apple-darwin`" != "" ; then
|
||||
AC_MSG_WARN([*** Using ptmalloc with OS X will result in failure.])
|
||||
@ -45,11 +60,6 @@ AC_DEFUN([MCA_memory_ptmalloc2_CONFIG],[
|
||||
[memory_ptmalloc2_happy="yes"],
|
||||
[memory_ptmalloc2_happy="no"])])
|
||||
|
||||
AS_IF([test "$memory_ptmalloc2_happy" = "yes"],
|
||||
[AS_IF([test "$enable_mpi_threads" = "yes" -o \
|
||||
"$enable_progress_threads" = "yes"],
|
||||
[memory_ptmalloc2_happy="no"])])
|
||||
|
||||
AS_IF([test "$memory_ptmalloc2_happy" = "yes"],
|
||||
[# check for malloc.h
|
||||
AC_CHECK_HEADER([malloc.h],
|
||||
@ -74,28 +84,35 @@ AC_DEFUN([MCA_memory_ptmalloc2_CONFIG],[
|
||||
#
|
||||
AS_IF([test "$memory_ptmalloc2_happy" = "yes"],
|
||||
[memory_ptmalloc2_mmap=0
|
||||
AS_IF([test "$memory_ptmalloc2_mmap" = "0"],
|
||||
[AC_CHECK_HEADER([syscall.h],
|
||||
[AC_CHECK_FUNCS([syscall], [memory_ptmalloc2_mmap=1])])])
|
||||
memory_ptmalloc2_munmap=1
|
||||
|
||||
AS_IF([test "$memory_ptmalloc2_mmap" = "0"],
|
||||
[AC_CHECK_FUNCS([__munmap], [memory_ptmalloc2_mmap=1])
|
||||
AC_CHECK_FUNCS([__mmap])])
|
||||
# it's nearly impossible to call mmap from syscall(), so
|
||||
# only go this route if we can't get at munmap any other
|
||||
# way.
|
||||
AC_CHECK_HEADER([syscall.h],
|
||||
[AC_CHECK_FUNCS([syscall], [], [memory_ptmalloc2_munmap=0])])
|
||||
|
||||
# Always look for __munmap and __mmap
|
||||
AC_CHECK_FUNCS([__munmap], [memory_ptmalloc2_mmap=1])
|
||||
AC_CHECK_FUNCS([__mmap])
|
||||
|
||||
# only allow dlsym (and therefore add -ldl) if we
|
||||
# really need to
|
||||
AS_IF([test "$memory_ptmalloc2_mmap" = "0"],
|
||||
[memory_ptmalloc2_LIBS_SAVE="$LIBS"
|
||||
AC_CHECK_LIB([dl],
|
||||
[dlsym],
|
||||
[memory_ptmalloc2_LIBS="-ldl"
|
||||
[LIBS="$LIBS -ldl"
|
||||
memory_ptmalloc2_LIBS="-ldl"
|
||||
memory_ptmalloc2_mmap=1])
|
||||
AC_CHECK_FUNCS([dlsym])
|
||||
LIBS="$memory_ptmalloc2_LIBS_SAVE"])
|
||||
|
||||
AS_IF([test "$memory_ptmalloc2_mmap" = "0"],
|
||||
AS_IF([test "$memory_ptmalloc2_mmap" = "0" -a "$memory_ptmalloc2_munmap" = "0"],
|
||||
[memory_ptmalloc2_happy="no"])])
|
||||
|
||||
AS_IF([test "$memory_ptmalloc2_happy" = "yes"],
|
||||
[memory_ptmalloc2_WRAPPER_EXTRA_LIBS="$memory_ptmalloc2_LIBS"])
|
||||
AS_IF([test "$memory_ptmalloc2_happy" = "yes"],
|
||||
[memory_ptmalloc2_WRAPPER_EXTRA_LIBS="$memory_ptmalloc2_LIBS"])
|
||||
|
||||
AS_IF([test "$memory_ptmalloc2_happy" = "no" -a \
|
||||
"$memory_malloc_hoooks_should_use" = "1"],
|
||||
|
@ -15,13 +15,16 @@
|
||||
void *sbrk();
|
||||
#endif
|
||||
|
||||
|
||||
#if OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
|
||||
static void*
|
||||
opal_mem_free_ptmalloc2_sbrk(int inc)
|
||||
{
|
||||
if (inc < 0) {
|
||||
long oldp = (long) sbrk(0);
|
||||
opal_mem_hooks_release_hook((void*) (oldp + inc), -inc);
|
||||
#if defined(HAVE_SYSCALL) || defined(HAVE___MMAP)
|
||||
#if defined(HAVE___MMAP) || defined(HAVE_DLSYM)
|
||||
} else if (inc > 0) {
|
||||
long oldp = (long) sbrk(0);
|
||||
opal_mem_hooks_alloc_hook((void*) oldp, inc);
|
||||
@ -32,13 +35,24 @@ opal_mem_free_ptmalloc2_sbrk(int inc)
|
||||
}
|
||||
|
||||
extern int opal_mem_free_ptmalloc2_munmap(void *start, size_t length);
|
||||
#if defined(HAVE___MMAP) || defined(HAVE_DLSYM)
|
||||
extern void* opal_mem_free_ptmalloc2_mmap(void *start, size_t length,
|
||||
int prot, int flags,
|
||||
int fd, off_t offset);
|
||||
#endif
|
||||
|
||||
/* 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)
|
||||
#define mmap(a, b, c, d, e, f) opal_mem_free_ptmalloc2_mmap(a, b, c, d, e, f)
|
||||
#if defined(HAVE___MMAP) || defined(HAVE_DLSYM)
|
||||
#define mmap(a,b,c,d,e,f) opal_mem_free_ptmalloc2_mmap(a,b,c,d,e,f)
|
||||
#endif
|
||||
|
||||
#endif /* OMPI_MEMORY_PTMALLOC2_OPT_SBRK */
|
||||
|
||||
/* easier to just not use mremap - having it makes tracking more
|
||||
difficult */
|
||||
#define HAVE_MREMAP 0
|
||||
@ -3430,6 +3444,12 @@ public_mALLOc(size_t bytes)
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
assert(!victim || chunk_is_mmapped(mem2chunk(victim)) ||
|
||||
ar_ptr == arena_for_chunk(mem2chunk(victim)));
|
||||
|
||||
/* OMPI Change */
|
||||
#if !OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
opal_mem_hooks_alloc_hook(victim, mUSABLe(victim));
|
||||
#endif
|
||||
|
||||
return victim;
|
||||
}
|
||||
#ifdef libc_hidden_def
|
||||
@ -3448,6 +3468,10 @@ public_fREe(Void_t* mem)
|
||||
(*hook)(mem, RETURN_ADDRESS (0));
|
||||
return;
|
||||
}
|
||||
/* OMPI change */
|
||||
#if !OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
opal_mem_hooks_release_hook(mem, mUSABLe(mem));
|
||||
#endif
|
||||
|
||||
if (mem == 0) /* free(0) has no effect */
|
||||
return;
|
||||
@ -3496,6 +3520,10 @@ public_rEALLOc(Void_t* oldmem, size_t bytes)
|
||||
__realloc_hook;
|
||||
if (hook != NULL)
|
||||
return (*hook)(oldmem, bytes, RETURN_ADDRESS (0));
|
||||
/* OMPI change */
|
||||
#if !OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
opal_mem_hooks_release_hook(mem, mUSABLe(mem));
|
||||
#endif
|
||||
|
||||
#if REALLOC_ZERO_BYTES_FREES
|
||||
if (bytes == 0 && oldmem != NULL) { public_fREe(oldmem); return 0; }
|
||||
@ -3516,15 +3544,29 @@ public_rEALLOc(Void_t* oldmem, size_t bytes)
|
||||
|
||||
#if HAVE_MREMAP
|
||||
newp = mremap_chunk(oldp, nb);
|
||||
if(newp) return chunk2mem(newp);
|
||||
if(newp) {
|
||||
/* OMPI Change */
|
||||
#if !OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
opal_mem_hooks_alloc_hook(newp, mUSABLe(newp));
|
||||
#endif
|
||||
return chunk2mem(newp);
|
||||
}
|
||||
#endif
|
||||
/* Note the extra SIZE_SZ overhead. */
|
||||
if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */
|
||||
if(oldsize - SIZE_SZ >= nb) {
|
||||
#if !OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
opal_mem_hooks_alloc_hook(oldmem, mUSABLe(oldmem));
|
||||
#endif
|
||||
return oldmem; /* do nothing */
|
||||
}
|
||||
/* Must alloc, copy, free. */
|
||||
newmem = public_mALLOc(bytes);
|
||||
if (newmem == 0) return 0; /* propagate failure */
|
||||
MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ);
|
||||
munmap_chunk(oldp);
|
||||
#if !OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
opal_mem_hooks_alloc_hook(newmem, mUSABLe(newmem));
|
||||
#endif
|
||||
return newmem;
|
||||
}
|
||||
#endif
|
||||
@ -3551,6 +3593,9 @@ public_rEALLOc(Void_t* oldmem, size_t bytes)
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
assert(!newp || chunk_is_mmapped(mem2chunk(newp)) ||
|
||||
ar_ptr == arena_for_chunk(mem2chunk(newp)));
|
||||
#if !OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
opal_mem_hooks_alloc_hook(newp, mUSABLe(newp));
|
||||
#endif
|
||||
return newp;
|
||||
}
|
||||
#ifdef libc_hidden_def
|
||||
@ -3599,6 +3644,9 @@ public_mEMALIGn(size_t alignment, size_t bytes)
|
||||
}
|
||||
assert(!p || chunk_is_mmapped(mem2chunk(p)) ||
|
||||
ar_ptr == arena_for_chunk(mem2chunk(p)));
|
||||
#if !OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
opal_mem_hooks_alloc_hook(p, mUSABLe(p));
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
#ifdef libc_hidden_def
|
||||
@ -3618,6 +3666,9 @@ public_vALLOc(size_t bytes)
|
||||
return 0;
|
||||
p = _int_valloc(ar_ptr, bytes);
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
#if !OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
opal_mem_hooks_alloc_hook(p, mUSABLe(p));
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -3632,6 +3683,9 @@ public_pVALLOc(size_t bytes)
|
||||
arena_get(ar_ptr, bytes + 2*mp_.pagesize + MINSIZE);
|
||||
p = _int_pvalloc(ar_ptr, bytes);
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
#if !OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
opal_mem_hooks_alloc_hook(p, mUSABLe(p));
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -3668,6 +3722,9 @@ public_cALLOc(size_t n, size_t elem_size)
|
||||
return memset(mem, 0, sz);
|
||||
#else
|
||||
while(sz > 0) ((char*)mem)[--sz] = 0; /* rather inefficient */
|
||||
#if !OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
opal_mem_hooks_alloc_hook(mem, mUSABLe(mem));
|
||||
#endif
|
||||
return mem;
|
||||
#endif
|
||||
}
|
||||
@ -3722,8 +3779,12 @@ public_cALLOc(size_t n, size_t elem_size)
|
||||
|
||||
/* Two optional cases in which clearing not necessary */
|
||||
#if HAVE_MMAP
|
||||
if (chunk_is_mmapped(p))
|
||||
if (chunk_is_mmapped(p)) {
|
||||
#if !OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
opal_mem_hooks_alloc_hook(mem, mUSABLe(mem));
|
||||
#endif
|
||||
return mem;
|
||||
}
|
||||
#endif
|
||||
|
||||
csz = chunksize(p);
|
||||
@ -3764,6 +3825,9 @@ public_cALLOc(size_t n, size_t elem_size)
|
||||
}
|
||||
}
|
||||
|
||||
#if !OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
opal_mem_hooks_alloc_hook(mem, mUSABLe(mem));
|
||||
#endif
|
||||
return mem;
|
||||
}
|
||||
|
||||
@ -3779,6 +3843,9 @@ public_iCALLOc(size_t n, size_t elem_size, Void_t** chunks)
|
||||
|
||||
m = _int_icalloc(ar_ptr, n, elem_size, chunks);
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
#if !OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
opal_mem_hooks_alloc_hook(m, mUSABLe(m));
|
||||
#endif
|
||||
return m;
|
||||
}
|
||||
|
||||
@ -3794,6 +3861,9 @@ public_iCOMALLOc(size_t n, size_t sizes[], Void_t** chunks)
|
||||
|
||||
m = _int_icomalloc(ar_ptr, n, sizes, chunks);
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
#if !OMPI_MEMORY_PTMALLOC2_OPT_SBRK
|
||||
opal_mem_hooks_alloc_hook(m, mUSABLe(m));
|
||||
#endif
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -21,14 +21,16 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#if defined(HAVE_SYSCALL)
|
||||
#if defined(HAVE___MUNMAP)
|
||||
/* here so we only include dlfcn if we absolutely have to */
|
||||
#elif defined(HAVE_DLSYM)
|
||||
#ifndef __USE_GNU
|
||||
#define __USE_GNU
|
||||
#endif
|
||||
#include <dlfcn.h>
|
||||
#elif defined(HAVE_SYSCALL)
|
||||
#include <syscall.h>
|
||||
#include <unistd.h>
|
||||
#elif defined(HAVE___MUNMAP)
|
||||
/* here only so that we only include dlfcn.h if needed */
|
||||
#elif defined(HAVE_DLSYM)
|
||||
#define __USE_GNU
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include "opal/memoryhooks/memory_internal.h"
|
||||
@ -37,7 +39,7 @@
|
||||
* munmap is always intercepted
|
||||
*/
|
||||
int opal_mem_free_ptmalloc2_munmap(void *start, size_t length);
|
||||
#if defined(HAVE_SYSCALL) || defined(HAVE___MUNMAP)
|
||||
#if defined(HAVE___MUNMAP)
|
||||
int __munmap(void* addr, size_t len);
|
||||
#endif
|
||||
|
||||
@ -50,16 +52,6 @@ munmap(void* addr, size_t len)
|
||||
}
|
||||
|
||||
|
||||
/* with syscall, we can safely intercept this as well */
|
||||
#if defined(HAVE_SYSCALL)
|
||||
int
|
||||
__munmap(void* addr, size_t len)
|
||||
{
|
||||
return opal_mem_free_ptmalloc2_munmap(addr, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* three ways to call munmap. Prefered is to just call syscall, so
|
||||
that we can intercept both munmap and __munmap. If that isn't
|
||||
possible, try calling __munmap from munmap and let __munmap go. If
|
||||
@ -67,29 +59,35 @@ __munmap(void* addr, size_t len)
|
||||
int
|
||||
opal_mem_free_ptmalloc2_munmap(void *start, size_t length)
|
||||
{
|
||||
#ifdef HAVE_DLSYM
|
||||
#if !defined(HAVE___MUNMAP) && defined(HAVE_DLSYM)
|
||||
static int (*realmunmap)(void*, size_t);
|
||||
#endif
|
||||
|
||||
opal_mem_hooks_release_hook(start, length);
|
||||
|
||||
#if defined(HAVE_SYSCALL)
|
||||
return syscall(__NR_munmap, start, length);
|
||||
#elif defined(HAVE___MUNMAP)
|
||||
#if defined(HAVE___MUNMAP)
|
||||
return __munmap(start, length);
|
||||
#elif defined(HAVE_DLSYM)
|
||||
if (NULL == realmunmap) {
|
||||
realmunmap = (int (*)(void*, size_t)) dlsym(RTLD_NEXT, "munmap");
|
||||
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);
|
||||
#elif defined(HAVE_SYSCALL)
|
||||
return syscall(__NR_munmap, start, length);
|
||||
#else
|
||||
#error "Can not determine how to call munmap"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(HAVE_SYSCALL) || defined(HAVE___MMAP)
|
||||
#if defined(HAVE___MMAP) || defined(HAVE_DLSYM)
|
||||
/*
|
||||
* mmap is only intercepted if we have a chance of finding it (ie, a
|
||||
* syscall or weak symbol)
|
||||
@ -98,8 +96,10 @@ void* opal_mem_free_ptmalloc2_mmap(void *start, size_t length,
|
||||
int prot, int flags,
|
||||
int fd, off_t offset);
|
||||
|
||||
#if defined(HAVE___MMAP)
|
||||
void* __mmap(void *start, size_t length, int prot, int flags,
|
||||
int fd, off_t offset);
|
||||
#endif
|
||||
|
||||
|
||||
void*
|
||||
@ -110,36 +110,37 @@ mmap(void *start, size_t length, int prot, int flags,
|
||||
fd, offset);
|
||||
}
|
||||
|
||||
#if defined(HAVE_SYSCALL)
|
||||
/* with syscall, we can safely intercept this as well */
|
||||
void*
|
||||
__mmap(void *start, size_t length, int prot, int flags,
|
||||
int fd, off_t offset)
|
||||
{
|
||||
return opal_mem_free_ptmalloc2_mmap(start, length, prot, flags,
|
||||
fd, offset);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* three ways to call mmap. Prefered is to just call syscall, so that
|
||||
we can intercept both munmap and __munmap. If that isn't possible,
|
||||
try calling __mmap from mmap and let __mmap go. Do not try to
|
||||
dlsym, as that generally requires calling mmap.
|
||||
*/
|
||||
void* opal_mem_free_ptmalloc2_mmap(void *start, size_t length,
|
||||
int prot, int flags,
|
||||
int fd, off_t offset)
|
||||
{
|
||||
opal_mem_hooks_alloc_hook(start, length);
|
||||
#if !defined(HAVE___MMAP) && defined(HAVE_DLSYM)
|
||||
static void* (*realmmap)(void *, size_t, int, int, int, off_t);
|
||||
#endif
|
||||
void *tmp;
|
||||
|
||||
#if defined(HAVE___MUNMAP)
|
||||
tmp = __mmap(start, length, prot, flags, fd, offset);
|
||||
#elif defined(HAVE_DLSYM)
|
||||
if (NULL == realmmap) {
|
||||
union {
|
||||
void* (*mmap_fp)(void *, size_t, int, int, int, off_t);
|
||||
void *mmap_p;
|
||||
} tmp;
|
||||
|
||||
tmp.mmap_p = dlsym(RTLD_NEXT, "mmap");
|
||||
realmmap = tmp.mmap_fp;
|
||||
}
|
||||
tmp = realmmap(start, length, prot, flags, fd, offset);
|
||||
|
||||
#if defined(HAVE_SYSCALL)
|
||||
return (void*) syscall(__NR_mmap, start, length, prot, flags, fd, offset);
|
||||
#elif defined(HAVE___MUNMAP)
|
||||
return __mmap(start, length, prot, flags, fd, offset);
|
||||
#else
|
||||
#error "Can not determine how to call mmap"
|
||||
#endif
|
||||
|
||||
opal_mem_hooks_alloc_hook(tmp, length);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
#endif /* #if defined(HAVE_SYSCALL) || defined(HAVE___MMAP) */
|
||||
#endif /* defined(HAVE___MMAP) || defined(HAVE_DLSYM) */
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user