Fix #110971: Replace our own barely-working backtrace on memleaks feature with ASAN utils.
Instead of storing the backtrace in all memory blocks, and trying to get meaningful info out of this list of pointers when printing leaked ones, just use `__asan_describe_address` when ASAN is enabled. This also work on Windows, in addition to linux and (presumably) OSX, but does require to build with ASAN enabled. The previous code was not working very well anymore, for some reason the call to `backtrace_symbols` seems to fail to give any meaningful information nowadays on most of Blender code. And it was only implemented for linux and OSX. Based on an idea from @LazyDodo, many thanks! Pull Request: https://projects.blender.org/blender/blender/pulls/111006
This commit is contained in:
@@ -92,24 +92,10 @@ typedef struct MemHead {
|
||||
#ifdef DEBUG_MEMDUPLINAME
|
||||
int need_free_name, pad;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_BACKTRACE
|
||||
void *backtrace[BACKTRACE_SIZE];
|
||||
int backtrace_size;
|
||||
#endif
|
||||
} MemHead;
|
||||
|
||||
typedef MemHead MemHeadAligned;
|
||||
|
||||
#ifdef DEBUG_BACKTRACE
|
||||
# if defined(__linux__) || defined(__APPLE__)
|
||||
# include <execinfo.h>
|
||||
// Windows is not supported yet.
|
||||
//# elif defined(_MSV_VER)
|
||||
//# include <DbgHelp.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef struct MemTail {
|
||||
int tag3, pad;
|
||||
} MemTail;
|
||||
@@ -366,38 +352,6 @@ void *MEM_guarded_recallocN_id(void *vmemh, size_t len, const char *str)
|
||||
return newp;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_BACKTRACE
|
||||
# if defined(__linux__) || defined(__APPLE__)
|
||||
static void make_memhead_backtrace(MemHead *memh)
|
||||
{
|
||||
memh->backtrace_size = backtrace(memh->backtrace, BACKTRACE_SIZE);
|
||||
}
|
||||
|
||||
static void print_memhead_backtrace(MemHead *memh)
|
||||
{
|
||||
char **strings;
|
||||
int i;
|
||||
|
||||
strings = backtrace_symbols(memh->backtrace, memh->backtrace_size);
|
||||
for (i = 0; i < memh->backtrace_size; i++) {
|
||||
print_error(" %s\n", strings[i]);
|
||||
}
|
||||
|
||||
free(strings);
|
||||
}
|
||||
# else
|
||||
static void make_memhead_backtrace(MemHead *memh)
|
||||
{
|
||||
(void)memh; /* Ignored. */
|
||||
}
|
||||
|
||||
static void print_memhead_backtrace(MemHead *memh)
|
||||
{
|
||||
(void)memh; /* Ignored. */
|
||||
}
|
||||
# endif /* defined(__linux__) || defined(__APPLE__) */
|
||||
#endif /* DEBUG_BACKTRACE */
|
||||
|
||||
static void make_memhead_header(MemHead *memh, size_t len, const char *str)
|
||||
{
|
||||
MemTail *memt;
|
||||
@@ -414,10 +368,6 @@ static void make_memhead_header(MemHead *memh, size_t len, const char *str)
|
||||
memh->need_free_name = 0;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_BACKTRACE
|
||||
make_memhead_backtrace(memh);
|
||||
#endif
|
||||
|
||||
memt = (MemTail *)(((char *)memh) + sizeof(MemHead) + len);
|
||||
memt->tag3 = MEMTAG3;
|
||||
|
||||
@@ -769,7 +719,9 @@ static void MEM_guarded_printmemlist_internal(int pydict)
|
||||
(void *)(membl + 1));
|
||||
#endif
|
||||
#ifdef DEBUG_BACKTRACE
|
||||
print_memhead_backtrace(membl);
|
||||
# ifdef WITH_ASAN
|
||||
__asan_describe_address(membl);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
if (membl->next) {
|
||||
|
||||
@@ -72,6 +72,21 @@ size_t malloc_usable_size(void *ptr);
|
||||
# define MEM_INLINE static inline
|
||||
#endif
|
||||
|
||||
/* BEGIN copied from BLI_asan.h */
|
||||
|
||||
/* Clang defines this. */
|
||||
#ifndef __has_feature
|
||||
# define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
#if (defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)) && \
|
||||
(!defined(_MSC_VER) || _MSC_VER > 1929) /* MSVC 2019 and below doesn't ship ASAN headers. */
|
||||
# include "sanitizer/asan_interface.h"
|
||||
# define WITH_ASAN
|
||||
#endif
|
||||
|
||||
/* END copied from BLI_asan.h */
|
||||
|
||||
#define IS_POW2(a) (((a) & ((a)-1)) == 0)
|
||||
|
||||
/* Extra padding which needs to be applied on MemHead to make it aligned. */
|
||||
|
||||
Reference in New Issue
Block a user