add option to disable guardedalloc, helps for debugging memory errors
since guardedalloc confuses them. The option cases a warning on build, since its ownly for experimental use.
This commit is contained in:
@@ -281,6 +281,9 @@ mark_as_advanced(WITH_MEM_JEMALLOC)
|
|||||||
option(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation tracking (only enable for development)" OFF)
|
option(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation tracking (only enable for development)" OFF)
|
||||||
mark_as_advanced(WITH_CXX_GUARDEDALLOC)
|
mark_as_advanced(WITH_CXX_GUARDEDALLOC)
|
||||||
|
|
||||||
|
option(WITH_GUARDEDALLOC "Enable GuardedAlloc (DISABLE AT OWN RISK!)" ON)
|
||||||
|
mark_as_advanced(WITH_GUARDEDALLOC)
|
||||||
|
|
||||||
option(WITH_ASSERT_ABORT "Call abort() when raising an assertion through BLI_assert()" OFF)
|
option(WITH_ASSERT_ABORT "Call abort() when raising an assertion through BLI_assert()" OFF)
|
||||||
mark_as_advanced(WITH_ASSERT_ABORT)
|
mark_as_advanced(WITH_ASSERT_ABORT)
|
||||||
|
|
||||||
|
@@ -46,6 +46,12 @@ if(WIN32 AND NOT UNIX)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (WITH_GUARDEDALLOC)
|
||||||
|
add_definitions(-DWITH_GUARDEDALLOC)
|
||||||
|
else()
|
||||||
|
message(WARNING "Disabling GuardedAlloc is experemental, use at own risk!")
|
||||||
|
endif()
|
||||||
|
|
||||||
blender_add_lib(bf_intern_guardedalloc "${SRC}" "${INC}" "${INC_SYS}")
|
blender_add_lib(bf_intern_guardedalloc "${SRC}" "${INC}" "${INC_SYS}")
|
||||||
|
|
||||||
# Override C++ alloc, optional.
|
# Override C++ alloc, optional.
|
||||||
|
@@ -31,6 +31,9 @@ defs = []
|
|||||||
|
|
||||||
sources = ['intern/mallocn.c', 'intern/mmap_win.c']
|
sources = ['intern/mallocn.c', 'intern/mmap_win.c']
|
||||||
|
|
||||||
|
# could make this optional
|
||||||
|
defs.append('WITH_GUARDEDALLOC')
|
||||||
|
|
||||||
if env['WITH_BF_CXX_GUARDEDALLOC']:
|
if env['WITH_BF_CXX_GUARDEDALLOC']:
|
||||||
sources.append('cpp/mallocn.cpp')
|
sources.append('cpp/mallocn.cpp')
|
||||||
defs.append('WITH_CXX_GUARDEDALLOC')
|
defs.append('WITH_CXX_GUARDEDALLOC')
|
||||||
|
@@ -36,14 +36,6 @@
|
|||||||
#include <string.h> /* memcpy */
|
#include <string.h> /* memcpy */
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
/* Blame Microsoft for LLP64 and no inttypes.h, quick workaround needed: */
|
|
||||||
#if defined(WIN64)
|
|
||||||
# define SIZET_FORMAT "%I64u"
|
|
||||||
# define SIZET_ARG(a) ((unsigned long long)(a))
|
|
||||||
#else
|
|
||||||
# define SIZET_FORMAT "%lu"
|
|
||||||
# define SIZET_ARG(a) ((unsigned long)(a))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* mmap exception */
|
/* mmap exception */
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
@@ -58,6 +50,18 @@
|
|||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
/* should always be defined except for experemental cases */
|
||||||
|
#ifdef WITH_GUARDEDALLOC
|
||||||
|
|
||||||
|
/* Blame Microsoft for LLP64 and no inttypes.h, quick workaround needed: */
|
||||||
|
#if defined(WIN64)
|
||||||
|
# define SIZET_FORMAT "%I64u"
|
||||||
|
# define SIZET_ARG(a) ((unsigned long long)(a))
|
||||||
|
#else
|
||||||
|
# define SIZET_FORMAT "%lu"
|
||||||
|
# define SIZET_ARG(a) ((unsigned long)(a))
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Only for debugging:
|
/* Only for debugging:
|
||||||
* store original buffer's name when doing MEM_dupallocN
|
* store original buffer's name when doing MEM_dupallocN
|
||||||
* helpful to profile issues with non-freed "dup_alloc" buffers,
|
* helpful to profile issues with non-freed "dup_alloc" buffers,
|
||||||
@@ -702,6 +706,7 @@ void MEM_callbackmemlist(void (*func)(void *))
|
|||||||
mem_unlock_thread();
|
mem_unlock_thread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
short MEM_testN(void *vmemh)
|
short MEM_testN(void *vmemh)
|
||||||
{
|
{
|
||||||
MemHead *membl;
|
MemHead *membl;
|
||||||
@@ -727,6 +732,7 @@ short MEM_testN(void *vmemh)
|
|||||||
print_error("Memoryblock %p: pointer not in memlist\n", vmemh);
|
print_error("Memoryblock %p: pointer not in memlist\n", vmemh);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void MEM_printmemlist(void)
|
void MEM_printmemlist(void)
|
||||||
{
|
{
|
||||||
@@ -1043,3 +1049,146 @@ const char *MEM_name_ptr(void *vmemh)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* NDEBUG */
|
#endif /* NDEBUG */
|
||||||
|
|
||||||
|
#else /* !WITH_GUARDEDALLOC */
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
|
||||||
|
#else
|
||||||
|
# define UNUSED(x) UNUSED_ ## x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
size_t MEM_allocN_len(const void *vmemh)
|
||||||
|
{
|
||||||
|
return malloc_usable_size((void *)vmemh);
|
||||||
|
}
|
||||||
|
|
||||||
|
short MEM_freeN(void *vmemh)
|
||||||
|
{
|
||||||
|
free(vmemh);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MEM_dupallocN(const void *vmemh)
|
||||||
|
{
|
||||||
|
void *newp = NULL;
|
||||||
|
if (vmemh) {
|
||||||
|
const size_t prev_size = MEM_allocN_len(vmemh);
|
||||||
|
newp = malloc(prev_size);
|
||||||
|
memcpy(newp, vmemh, prev_size);
|
||||||
|
}
|
||||||
|
return newp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MEM_reallocN(void *vmemh, size_t len)
|
||||||
|
{
|
||||||
|
return realloc(vmemh, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MEM_recallocN(void *vmemh, size_t len)
|
||||||
|
{
|
||||||
|
void *newp = NULL;
|
||||||
|
|
||||||
|
if (vmemh) {
|
||||||
|
size_t vmemh_len = MEM_allocN_len(vmemh);
|
||||||
|
newp = malloc(len);
|
||||||
|
if (newp) {
|
||||||
|
if (len < vmemh_len) {
|
||||||
|
/* shrink */
|
||||||
|
memcpy(newp, vmemh, len);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(newp, vmemh, vmemh_len);
|
||||||
|
|
||||||
|
if (len > vmemh_len) {
|
||||||
|
/* grow */
|
||||||
|
/* zero new bytes */
|
||||||
|
memset(((char *)newp) + vmemh_len, 0, len - vmemh_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(vmemh);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newp = calloc(1, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MEM_callocN(size_t len, const char *UNUSED(str))
|
||||||
|
{
|
||||||
|
return calloc(1, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MEM_mallocN(size_t len, const char *UNUSED(str))
|
||||||
|
{
|
||||||
|
return malloc(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MEM_mapallocN(size_t len, const char *UNUSED(str))
|
||||||
|
{
|
||||||
|
/* could us mmap */
|
||||||
|
return calloc(1, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MEM_printmemlist_pydict(void) {}
|
||||||
|
void MEM_printmemlist(void) {}
|
||||||
|
|
||||||
|
/* unused */
|
||||||
|
void MEM_callbackmemlist(void (*func)(void *))
|
||||||
|
{
|
||||||
|
(void)func;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MEM_printmemlist_stats(void) {}
|
||||||
|
|
||||||
|
void MEM_set_error_callback(void (*func)(const char *))
|
||||||
|
{
|
||||||
|
(void)func;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MEM_check_memory_integrity(void)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MEM_set_lock_callback(void (*lock)(void), void (*unlock)(void))
|
||||||
|
{
|
||||||
|
(void)lock;
|
||||||
|
(void)unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MEM_set_memory_debug(void) {}
|
||||||
|
|
||||||
|
uintptr_t MEM_get_memory_in_use(void)
|
||||||
|
{
|
||||||
|
struct mallinfo mi;
|
||||||
|
mi = mallinfo();
|
||||||
|
return mi.uordblks;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t MEM_get_mapped_memory_in_use(void)
|
||||||
|
{
|
||||||
|
return MEM_get_memory_in_use();
|
||||||
|
}
|
||||||
|
|
||||||
|
int MEM_get_memory_blocks_in_use(void)
|
||||||
|
{
|
||||||
|
struct mallinfo mi;
|
||||||
|
mi = mallinfo();
|
||||||
|
return mi.smblks + mi.hblks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dummy */
|
||||||
|
void MEM_reset_peak_memory(void) {}
|
||||||
|
|
||||||
|
uintptr_t MEM_get_peak_memory(void)
|
||||||
|
{
|
||||||
|
return MEM_get_memory_in_use();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* WITH_GUARDEDALLOC */
|
||||||
|
Reference in New Issue
Block a user