Commit 10ca4727 authored by marko's avatar marko

Improve memory debugging. This is follow-up to r1819.

mem_heap_validate(): Compile this function also if UNIV_MEM_DEBUG is
defined.  Previously, this function was only compiled with UNIV_DEBUG.

mem_heap_free_heap_top(): Flag the memory allocated, not freed, for
Valgrind.  Otherwise, Valgrind would complain on the second call of
mem_heap_empty().

UNIV_MEM_ASSERT_RW(), UNIV_MEM_ASSERT_W(): Display additional diagnostics
for failed Valgrind checks.
parent 4678dfac
...@@ -60,6 +60,14 @@ mem_heap_validate_or_print( ...@@ -60,6 +60,14 @@ mem_heap_validate_or_print(
ulint* n_blocks); /* out: number of blocks in the heap, ulint* n_blocks); /* out: number of blocks in the heap,
if a NULL pointer is passed as this if a NULL pointer is passed as this
argument, it is ignored */ argument, it is ignored */
/******************************************************************
Validates the contents of a memory heap. */
ibool
mem_heap_validate(
/*==============*/
/* out: TRUE if ok */
mem_heap_t* heap); /* in: memory heap */
#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */ #endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
/****************************************************************** /******************************************************************
...@@ -71,14 +79,6 @@ mem_heap_check( ...@@ -71,14 +79,6 @@ mem_heap_check(
/* out: TRUE if ok */ /* out: TRUE if ok */
mem_heap_t* heap); /* in: memory heap */ mem_heap_t* heap); /* in: memory heap */
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
/******************************************************************
Validates the contents of a memory heap. */
ibool
mem_heap_validate(
/*==============*/
/* out: TRUE if ok */
mem_heap_t* heap); /* in: memory heap */
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
/********************************************************************* /*********************************************************************
TRUE if no memory is currently allocated. */ TRUE if no memory is currently allocated. */
......
...@@ -278,8 +278,9 @@ mem_heap_free_heap_top( ...@@ -278,8 +278,9 @@ mem_heap_free_heap_top(
mem_current_allocated_memory -= (total_size - size); mem_current_allocated_memory -= (total_size - size);
mutex_exit(&mem_hash_mutex); mutex_exit(&mem_hash_mutex);
#else /* UNIV_MEM_DEBUG */ #else /* UNIV_MEM_DEBUG */
UNIV_MEM_ASSERT_AND_FREE(old_top, (byte*)block + block->len - old_top); UNIV_MEM_ASSERT_W(old_top, (byte*)block + block->len - old_top);
#endif /* UNIV_MEM_DEBUG */ #endif /* UNIV_MEM_DEBUG */
UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top);
/* If free == start, we may free the block if it is not the first /* If free == start, we may free the block if it is not the first
one */ one */
......
...@@ -308,10 +308,22 @@ typedef void* os_thread_ret_t; ...@@ -308,10 +308,22 @@ typedef void* os_thread_ret_t;
# define UNIV_MEM_INVALID(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size) # define UNIV_MEM_INVALID(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size)
# define UNIV_MEM_FREE(addr, size) VALGRIND_MAKE_MEM_NOACCESS(addr, size) # define UNIV_MEM_FREE(addr, size) VALGRIND_MAKE_MEM_NOACCESS(addr, size)
# define UNIV_MEM_ALLOC(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size) # define UNIV_MEM_ALLOC(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size)
# define UNIV_MEM_ASSERT_RW(addr, size) \ # define UNIV_MEM_ASSERT_RW(addr, size) do { \
VALGRIND_CHECK_MEM_IS_DEFINED(addr, size) const void* _p = (const void*) \
# define UNIV_MEM_ASSERT_W(addr, size) \ VALGRIND_CHECK_MEM_IS_DEFINED(addr, size); \
VALGRIND_CHECK_MEM_IS_ADDRESSABLE(addr, size) if (UNIV_LIKELY_NULL(_p)) \
fprintf(stderr, "%p[%u] undefined at %d\n", \
(const void*) (addr), (unsigned) (size), \
((const char*) _p) - ((const char*) (addr))); \
} while (0)
# define UNIV_MEM_ASSERT_W(addr, size) do { \
const void* _p = (const void*) \
VALGRIND_CHECK_MEM_IS_ADDRESSABLE(addr, size); \
if (UNIV_LIKELY_NULL(_p)) \
fprintf(stderr, "%p[%u] unwritable at %d\n", \
(const void*) (addr), (unsigned) (size), \
((const char*) _p) - ((const char*) (addr))); \
} while (0)
#else #else
# define UNIV_MEM_VALID(addr, size) do {} while(0) # define UNIV_MEM_VALID(addr, size) do {} while(0)
# define UNIV_MEM_INVALID(addr, size) do {} while(0) # define UNIV_MEM_INVALID(addr, size) do {} while(0)
......
...@@ -554,9 +554,7 @@ completed: ...@@ -554,9 +554,7 @@ completed:
} }
*error = FALSE; *error = FALSE;
} }
#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
#ifdef UNIV_DEBUG
/****************************************************************** /******************************************************************
Prints the contents of a memory heap. */ Prints the contents of a memory heap. */
static static
...@@ -582,20 +580,6 @@ mem_heap_print( ...@@ -582,20 +580,6 @@ mem_heap_print(
ut_a(!error); ut_a(!error);
} }
/******************************************************************
Checks that an object is a memory heap (or a block of it). */
ibool
mem_heap_check(
/*===========*/
/* out: TRUE if ok */
mem_heap_t* heap) /* in: memory heap */
{
ut_a(heap->magic_n == MEM_BLOCK_MAGIC_N);
return(TRUE);
}
/****************************************************************** /******************************************************************
Validates the contents of a memory heap. */ Validates the contents of a memory heap. */
...@@ -622,6 +606,22 @@ mem_heap_validate( ...@@ -622,6 +606,22 @@ mem_heap_validate(
return(TRUE); return(TRUE);
} }
#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
#ifdef UNIV_DEBUG
/******************************************************************
Checks that an object is a memory heap (or a block of it). */
ibool
mem_heap_check(
/*===========*/
/* out: TRUE if ok */
mem_heap_t* heap) /* in: memory heap */
{
ut_a(heap->magic_n == MEM_BLOCK_MAGIC_N);
return(TRUE);
}
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment