Removes the memory allocation sanity checks feature (#2218)

* Removes the memory allocation sanity checks feature

* Committing clang-format changes

* Removes zero size checks for H5MM_(c|m)alloc()

* Explicitly return NULL when size == 0 in H5allocate_memory()

* Committing clang-format changes

* Format fix

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Dana Robinson 2022-11-03 16:30:08 -07:00 committed by GitHub
parent 40a0e3c7b5
commit 018f093c09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 63 additions and 654 deletions

View File

@ -560,14 +560,6 @@ if (HDF5_ENABLE_USING_MEMCHECKER)
set (H5_USING_MEMCHECKER 1)
endif ()
#-----------------------------------------------------------------------------
# Option to indicate internal memory allocation sanity checks are enabled
#-----------------------------------------------------------------------------
option (HDF5_MEMORY_ALLOC_SANITY_CHECK "Indicate that internal memory allocation sanity checks are enabled" OFF)
if (HDF5_MEMORY_ALLOC_SANITY_CHECK)
set (H5_MEMORY_ALLOC_SANITY_CHECK 1)
endif ()
#-----------------------------------------------------------------------------
# Option to enable/disable using pread/pwrite for VFDs
#-----------------------------------------------------------------------------

View File

@ -76,7 +76,6 @@ $Source = "";
"H5G_obj_t" => "Go",
"H5G_stat_t" => "Gs",
"hsize_t" => "h",
"H5_alloc_stats_t" => "Ha",
"H5_atclose_func_t" => "Hc",
"hssize_t" => "Hs",
"H5E_major_t" => "i", # H5E_major_t is typedef'd to hid_t

View File

@ -125,7 +125,6 @@ CHECK_INCLUDE_FILE_CONCAT ("srbclient.h" ${HDF_PREFIX}_HAVE_SRBCLIENT_H)
CHECK_INCLUDE_FILE_CONCAT ("string.h" ${HDF_PREFIX}_HAVE_STRING_H)
CHECK_INCLUDE_FILE_CONCAT ("strings.h" ${HDF_PREFIX}_HAVE_STRINGS_H)
CHECK_INCLUDE_FILE_CONCAT ("stdlib.h" ${HDF_PREFIX}_HAVE_STDLIB_H)
CHECK_INCLUDE_FILE_CONCAT ("memory.h" ${HDF_PREFIX}_HAVE_MEMORY_H)
CHECK_INCLUDE_FILE_CONCAT ("dlfcn.h" ${HDF_PREFIX}_HAVE_DLFCN_H)
CHECK_INCLUDE_FILE_CONCAT ("netinet/in.h" ${HDF_PREFIX}_HAVE_NETINET_IN_H)
CHECK_INCLUDE_FILE_CONCAT ("netdb.h" ${HDF_PREFIX}_HAVE_NETDB_H)

View File

@ -228,9 +228,6 @@
/* Define if the map API (H5M) should be compiled */
#cmakedefine H5_HAVE_MAP_API @H5_HAVE_MAP_API@
/* Define to 1 if you have the <memory.h> header file. */
#cmakedefine H5_HAVE_MEMORY_H @H5_HAVE_MEMORY_H@
/* Define whether the Mirror virtual file driver (VFD) will be compiled */
#cmakedefine H5_HAVE_MIRROR_VFD @H5_HAVE_MIRROR_VFD@
@ -439,9 +436,6 @@
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#cmakedefine H5_LT_OBJDIR @H5_LT_OBJDIR@
/* Define to enable internal memory allocation sanity checking. */
#cmakedefine H5_MEMORY_ALLOC_SANITY_CHECK @H5_MEMORY_ALLOC_SANITY_CHECK@
/* Define if deprecated public API symbols are disabled */
#cmakedefine H5_NO_DEPRECATED_SYMBOLS @H5_NO_DEPRECATED_SYMBOLS@

View File

@ -194,10 +194,3 @@ endif ()
# Enable strict checking of the file format
list (APPEND HDF5_DEVELOPER_DEFS H5_STRICT_FORMAT_CHECKS)
# Enable printing of library memory stats
option (HDF5_ENABLE_MEMORY_STATS "Enable printing of library memory stats" OFF)
mark_as_advanced (HDF5_ENABLE_MEMORY_STATS)
if (HDF5_ENABLE_MEMORY_STATS)
list (APPEND HDF5_DEVELOPER_DEFS H5MM_PRINT_MEMORY_STATS)
endif ()

View File

@ -87,7 +87,6 @@ Dimension scales w/ new references: @DIMENSION_SCALES_WITH_NEW_REF@
Packages w/ extra debug output: @INTERNAL_DEBUG_OUTPUT@
API Tracing: @HDF5_ENABLE_TRACE@
Using memory checker: @HDF5_ENABLE_USING_MEMCHECKER@
Memory allocation sanity checks: @HDF5_MEMORY_ALLOC_SANITY_CHECK@
Function Stack Tracing: @HDF5_ENABLE_CODESTACK@
Use file locking: @HDF5_FILE_LOCKING_SETTING@
Strict File Format Checks: @HDF5_STRICT_FORMAT_CHECKS@

View File

@ -2657,8 +2657,6 @@ AC_ARG_ENABLE([using-memchecker],
library. Enabling this causes the library to be
more picky about its memory operations and also
disables the library's free space manager code.
This option is orthogonal to the
--enable-memory-alloc-sanity-check option.
[default=no]
])],
[USINGMEMCHECKER=$enableval])
@ -2688,50 +2686,6 @@ case "X-$USINGMEMCHECKER" in
;;
esac
## ----------------------------------------------------------------------
## Check if they would like to enable the internal memory allocation sanity
## checking code.
##
AC_MSG_CHECKING([whether internal memory allocation sanity checking is used])
AC_ARG_ENABLE([memory-alloc-sanity-check],
[AS_HELP_STRING([--enable-memory-alloc-sanity-check],
[Enable this option to turn on internal memory
allocation sanity checking. This could cause
more memory use and somewhat slower allocation.
This option may also cause issues with HDF5
filter plugins, so should not be enabled if
filters are to be used. This option is orthogonal
to the --enable-using-memchecker option.
[default=no]
])],
[MEMORYALLOCSANITYCHECK=$enableval])
## Allow this variable to be substituted in
## other files (src/libhdf5.settings.in, etc.)
AC_SUBST([MEMORYALLOCSANITYCHECK])
## Set default
if test "X-$MEMORYALLOCSANITYCHECK" = X- ; then
# Should consider enabling this option by default for
# 'developer' builds if that build mode is added in
# the future
MEMORYALLOCSANITYCHECK=no
fi
case "X-$MEMORYALLOCSANITYCHECK" in
X-yes)
AC_DEFINE([MEMORY_ALLOC_SANITY_CHECK], [1],
[Define to enable internal memory allocation sanity checking.])
AC_MSG_RESULT([yes])
;;
X-no)
AC_MSG_RESULT([no])
;;
*)
AC_MSG_ERROR([Unrecognized value: $MEMORYALLOCSANITYCHECK])
;;
esac
## Checkpoint the cache
AC_CACHE_SAVE

View File

@ -785,7 +785,6 @@ HDF5_ENABLE_USING_MEMCHECKER "Indicate that a memory checker is used"
HDF5_GENERATE_HEADERS "Rebuild Generated Files" ON
HDF5_BUILD_GENERATORS "Build Test Generators" OFF
HDF5_JAVA_PACK_JRE "Package a JRE installer directory" OFF
HDF5_MEMORY_ALLOC_SANITY_CHECK "Indicate that internal memory allocation sanity checks are enabled" OFF
HDF5_NO_PACKAGES "Do not include CPack Packaging" OFF
HDF5_PACK_EXAMPLES "Package the HDF5 Library Examples Compressed File" OFF
HDF5_PACK_MACOSX_FRAMEWORK "Package the HDF5 Library in a Frameworks" OFF

View File

@ -47,13 +47,40 @@ New Features
Configuration:
-------------
-
- Removal of memory allocation sanity checks configure options
With the removal of the memory allocation sanity checks feature, the
following configure options are no longer necessary and have been
removed:
Autotools:
--enable-memory-alloc-sanity-check
CMake:
HDF5_MEMORY_ALLOC_SANITY_CHECK
HDF5_ENABLE_MEMORY_STATS
(DER - 2022/11/03)
Library:
--------
-
- Removal of memory allocation sanity checks feature
This feature added heap canaries and statistics tracking for internal
library memory operations. Unfortunately, the heap canaries caused
problems when library memory operations were mixed with standard C
library memory operations (such as in the filter pipeline, where
buffers may have to be reallocated). Since any platform with a C
compiler also usually has much more sophisticated memory sanity
checking tools than the HDF5 library provided (e.g., valgrind), we
have decided to to remove the feature entirely.
In addition to the configure changes described above, this also removes
the following from the public API:
H5get_alloc_stats()
H5_alloc_stats_t
(DER - 2022/11/03)
Parallel Library:
-----------------
@ -125,7 +152,7 @@ Bug Fixes since HDF5-1.13.3 release
an application or library was built with the C library. Also updated the
CMake target link command to use the newer style MPI::MPI_C link variable.
(ADB - 2022/20/27)
(ADB - 2022/10/27)
Tools

View File

@ -540,11 +540,6 @@ H5_term_library(void)
(void)H5MM_free(tmp_open_stream);
} /* end while */
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
/* Sanity check memory allocations */
H5MM_final_sanity_check();
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
/* Reset flag indicating that the library is being shut down */
H5_TERM_GLOBAL = FALSE;
@ -715,46 +710,6 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5get_free_list_sizes() */
/*-------------------------------------------------------------------------
* Function: H5get_alloc_stats
*
* Purpose: Gets the memory allocation statistics for the library, if the
* --enable-memory-alloc-sanity-check option was given when building the
* library. Applications can check whether this option was enabled by
* detecting if the 'H5_MEMORY_ALLOC_SANITY_CHECK' macro is defined. This
* option is enabled by default for debug builds of the library and
* disabled by default for non-debug builds. If the option is not enabled,
* all the values returned with be 0. These statistics are global for the
* entire library, but don't include allocations from chunked dataset I/O
* filters or non-native VOL connectors.
*
* Parameters:
* H5_alloc_stats_t *stats; OUT: Memory allocation statistics
*
* Return: Success: non-negative
* Failure: negative
*
* Programmer: Quincey Koziol
* Saturday, March 7, 2020
*
*-------------------------------------------------------------------------
*/
herr_t
H5get_alloc_stats(H5_alloc_stats_t *stats /*out*/)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE1("e", "x", stats);
/* Call the internal allocation stat routine to get the values */
if (H5MM_get_alloc_stats(stats) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't get allocation stats")
done:
FUNC_LEAVE_API(ret_value)
} /* end H5get_alloc_stats() */
/*-------------------------------------------------------------------------
* Function: H5__debug_mask
*
@ -1207,9 +1162,10 @@ H5close(void)
*
* Return:
*
* Success: A pointer to the allocated buffer.
* Success: A pointer to the allocated buffer or NULL if the size
* parameter is zero.
*
* Failure: NULL
* Failure: NULL (but may also be NULL w/ size 0!)
*
*-------------------------------------------------------------------------
*/
@ -1221,6 +1177,9 @@ H5allocate_memory(size_t size, hbool_t clear)
FUNC_ENTER_API_NOINIT
H5TRACE2("*x", "zb", size, clear);
if (0 == size)
return NULL;
if (clear)
ret_value = H5MM_calloc(size);
else

View File

@ -13,8 +13,6 @@
/*-------------------------------------------------------------------------
*
* Created: H5MM.c
* Jul 10 1997
* Robb Matzke
*
* Purpose: Memory management functions
*
@ -35,45 +33,14 @@
/****************/
/* Local Macros */
/****************/
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
#define H5MM_SIG_SIZE 4
#define H5MM_HEAD_GUARD_SIZE 8
#define H5MM_TAIL_GUARD_SIZE 8
#define H5MM_BLOCK_FROM_BUF(mem) \
((H5MM_block_t *)((void *)((unsigned char *)mem - (offsetof(H5MM_block_t, b) + H5MM_HEAD_GUARD_SIZE))))
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
/******************/
/* Local Typedefs */
/******************/
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
/* Memory allocation "block", wrapped around each allocation */
struct H5MM_block_t; /* Forward declaration for typedef */
typedef struct H5MM_block_t {
unsigned char
sig[H5MM_SIG_SIZE]; /* Signature for the block, to indicate it was allocated with H5MM* interface */
struct H5MM_block_t *next; /* Pointer to next block in the list of allocated blocks */
struct H5MM_block_t *prev; /* Pointer to previous block in the list of allocated blocks */
union {
struct {
size_t size; /* Size of allocated block */
hbool_t in_use; /* Whether the block is in use or is free */
} info;
double _align; /* Align following buffer (b) to double boundary (unused) */
} u;
unsigned char b[]; /* Buffer for caller (includes header and footer) */
} H5MM_block_t;
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
/********************/
/* Local Prototypes */
/********************/
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
static hbool_t H5MM__is_our_block(void *mem);
static void H5MM__sanity_check_block(const H5MM_block_t *block);
static void H5MM__sanity_check(void *mem);
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
/*********************/
/* Package Variables */
@ -87,152 +54,6 @@ static void H5MM__sanity_check(void *mem);
/* Local Variables */
/*******************/
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
/* Constant strings for block signature, head & tail guards */
static const char H5MM_block_signature_s[H5MM_SIG_SIZE] = {'H', '5', 'M', 'M'};
static const char H5MM_block_head_guard_s[H5MM_HEAD_GUARD_SIZE] = {'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F'};
static const char H5MM_block_tail_guard_s[H5MM_TAIL_GUARD_SIZE] = {'B', 'E', 'E', 'F', 'D', 'E', 'A', 'D'};
/* Flag to indicate the the interface has been initialized */
static hbool_t H5MM_init_s = FALSE;
/* Head of the list of allocated blocks */
static H5MM_block_t H5MM_block_head_s;
/* Statistics about block allocations */
static unsigned long long H5MM_total_alloc_bytes_s = 0;
static size_t H5MM_curr_alloc_bytes_s = 0;
static size_t H5MM_peak_alloc_bytes_s = 0;
static size_t H5MM_max_block_size_s = 0;
static size_t H5MM_total_alloc_blocks_count_s = 0;
static size_t H5MM_curr_alloc_blocks_count_s = 0;
static size_t H5MM_peak_alloc_blocks_count_s = 0;
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
/*-------------------------------------------------------------------------
* Function: H5MM__is_our_block
*
* Purpose: Try to determine if a memory buffer has been allocated through
* the H5MM* interface, instead of the system's malloc() routines.
*
* Return: Success: TRUE/FALSE
* Failure: (Can't fail)
*
* Programmer: Quincey Koziol
* Dec 30 2015
*
*-------------------------------------------------------------------------
*/
static hbool_t
H5MM__is_our_block(void *mem)
{
H5MM_block_t *block = H5MM_BLOCK_FROM_BUF(mem);
return (0 == HDmemcmp(block->sig, H5MM_block_signature_s, H5MM_SIG_SIZE));
}
/*-------------------------------------------------------------------------
* Function: H5MM__sanity_check_block
*
* Purpose: Check a block wrapper around a buffer to validate it.
*
* Return: N/A (void)
*
* Programmer: Quincey Koziol
* Dec 30 2015
*
*-------------------------------------------------------------------------
*/
static void
H5MM__sanity_check_block(const H5MM_block_t *block)
{
HDassert(block->u.info.size > 0);
HDassert(block->u.info.in_use);
/* Check for head & tail guards, if not head of linked list */
if (block->u.info.size != SIZE_MAX) {
HDassert(0 == HDmemcmp(block->b, H5MM_block_head_guard_s, H5MM_HEAD_GUARD_SIZE));
HDassert(0 == HDmemcmp(block->b + H5MM_HEAD_GUARD_SIZE + block->u.info.size, H5MM_block_tail_guard_s,
H5MM_TAIL_GUARD_SIZE));
}
}
/*-------------------------------------------------------------------------
* Function: H5MM__sanity_check
*
* Purpose: Check a buffer to validate it (just calls
* H5MM__sanity_check_block after finding block for buffer)
*
* Return: N/A (void)
*
* Programmer: Quincey Koziol
* Dec 30 2015
*
*-------------------------------------------------------------------------
*/
static void
H5MM__sanity_check(void *mem)
{
H5MM_block_t *block = H5MM_BLOCK_FROM_BUF(mem);
H5MM__sanity_check_block(block);
}
/*-------------------------------------------------------------------------
* Function: H5MM_sanity_check_all
*
* Purpose: Sanity check all current memory allocations.
*
* Return: N/A (void)
*
* Programmer: Quincey Koziol
* Jan 5 2016
*
*-------------------------------------------------------------------------
*/
void
H5MM_sanity_check_all(void)
{
H5MM_block_t *curr = NULL;
curr = H5MM_block_head_s.next;
while (curr != &H5MM_block_head_s) {
H5MM__sanity_check_block(curr);
curr = curr->next;
} /* end while */
} /* end H5MM_sanity_check_all() */
/*-------------------------------------------------------------------------
* Function: H5MM_final_sanity_check
*
* Purpose: Final sanity checks on memory allocation.
*
* Return: N/A (void)
*
* Programmer: Quincey Koziol
* Jan 1 2016
*
*-------------------------------------------------------------------------
*/
void
H5MM_final_sanity_check(void)
{
HDassert(0 == H5MM_curr_alloc_bytes_s);
HDassert(0 == H5MM_curr_alloc_blocks_count_s);
HDassert(H5MM_block_head_s.next == &H5MM_block_head_s);
HDassert(H5MM_block_head_s.prev == &H5MM_block_head_s);
#ifdef H5MM_PRINT_MEMORY_STATS
HDfprintf(stderr, "%s: H5MM_total_alloc_bytes_s = %llu\n", __func__, H5MM_total_alloc_bytes_s);
HDfprintf(stderr, "%s: H5MM_peak_alloc_bytes_s = %zu\n", __func__, H5MM_peak_alloc_bytes_s);
HDfprintf(stderr, "%s: H5MM_max_block_size_s = %zu\n", __func__, H5MM_max_block_size_s);
HDfprintf(stderr, "%s: H5MM_total_alloc_blocks_count_s = %zu\n", __func__,
H5MM_total_alloc_blocks_count_s);
HDfprintf(stderr, "%s: H5MM_peak_alloc_blocks_count_s = %zu\n", __func__, H5MM_peak_alloc_blocks_count_s);
#endif /* H5MM_PRINT_MEMORY_STATS */
}
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
/*-------------------------------------------------------------------------
* Function: H5MM_malloc
*
@ -246,10 +67,6 @@ H5MM_final_sanity_check(void)
*
* Return: Success: Pointer to new memory
* Failure: NULL
*
* Programmer: Quincey Koziol
* Nov 8 2003
*
*-------------------------------------------------------------------------
*/
void *
@ -260,60 +77,7 @@ H5MM_malloc(size_t size)
/* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
FUNC_ENTER_NOAPI_NOINIT_NOERR
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
/* Initialize block list head singleton */
if (!H5MM_init_s) {
H5MM_memcpy(H5MM_block_head_s.sig, H5MM_block_signature_s, H5MM_SIG_SIZE);
H5MM_block_head_s.next = &H5MM_block_head_s;
H5MM_block_head_s.prev = &H5MM_block_head_s;
H5MM_block_head_s.u.info.size = SIZE_MAX;
H5MM_block_head_s.u.info.in_use = TRUE;
H5MM_init_s = TRUE;
} /* end if */
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
if (size) {
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
H5MM_block_t *block;
size_t alloc_size = sizeof(H5MM_block_t) + size + H5MM_HEAD_GUARD_SIZE + H5MM_TAIL_GUARD_SIZE;
if (NULL != (block = (H5MM_block_t *)HDmalloc(alloc_size))) {
/* Set up block */
H5MM_memcpy(block->sig, H5MM_block_signature_s, H5MM_SIG_SIZE);
block->next = H5MM_block_head_s.next;
H5MM_block_head_s.next = block;
block->next->prev = block;
block->prev = &H5MM_block_head_s;
block->u.info.size = size;
block->u.info.in_use = TRUE;
H5MM_memcpy(block->b, H5MM_block_head_guard_s, H5MM_HEAD_GUARD_SIZE);
H5MM_memcpy(block->b + H5MM_HEAD_GUARD_SIZE + size, H5MM_block_tail_guard_s,
H5MM_TAIL_GUARD_SIZE);
/* Update statistics */
H5MM_total_alloc_bytes_s += size;
H5MM_curr_alloc_bytes_s += size;
if (H5MM_curr_alloc_bytes_s > H5MM_peak_alloc_bytes_s)
H5MM_peak_alloc_bytes_s = H5MM_curr_alloc_bytes_s;
if (size > H5MM_max_block_size_s)
H5MM_max_block_size_s = size;
H5MM_total_alloc_blocks_count_s++;
H5MM_curr_alloc_blocks_count_s++;
if (H5MM_curr_alloc_blocks_count_s > H5MM_peak_alloc_blocks_count_s)
H5MM_peak_alloc_blocks_count_s = H5MM_curr_alloc_blocks_count_s;
/* Set buffer to return */
ret_value = block->b + H5MM_HEAD_GUARD_SIZE;
} /* end if */
else
ret_value = NULL;
#else /* H5_MEMORY_ALLOC_SANITY_CHECK */
ret_value = HDmalloc(size);
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
} /* end if */
else
ret_value = NULL;
ret_value = HDmalloc(size);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MM_malloc() */
@ -330,13 +94,8 @@ H5MM_malloc(size_t size)
* considered an error condition since allocations of zero
* bytes usually indicate problems.
*
*
* Return: Success: Pointer to new memory
* Failure: NULL
*
* Programmer: Quincey Koziol
* Nov 8 2003
*
*-------------------------------------------------------------------------
*/
void *
@ -347,16 +106,7 @@ H5MM_calloc(size_t size)
/* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
FUNC_ENTER_NOAPI_NOINIT_NOERR
if (size) {
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
if (NULL != (ret_value = H5MM_malloc(size)))
HDmemset(ret_value, 0, size);
#else /* H5_MEMORY_ALLOC_SANITY_CHECK */
ret_value = HDcalloc((size_t)1, size);
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
} /* end if */
else
ret_value = NULL;
ret_value = HDcalloc(1, size);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MM_calloc() */
@ -377,10 +127,6 @@ H5MM_calloc(size_t size)
* Return: Success: Ptr to new memory if size > 0
* NULL if size is zero
* Failure: NULL (input buffer is unchanged on failure)
*
* Programmer: Robb Matzke
* Jul 10 1997
*
*-------------------------------------------------------------------------
*/
void *
@ -395,35 +141,12 @@ H5MM_realloc(void *mem, size_t size)
/* Not defined in the standard, return NULL */
ret_value = NULL;
else {
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
if (size > 0) {
if (mem) {
if (H5MM__is_our_block(mem)) {
H5MM_block_t *block = H5MM_BLOCK_FROM_BUF(mem);
size_t old_size = block->u.info.size;
H5MM__sanity_check(mem);
ret_value = H5MM_malloc(size);
H5MM_memcpy(ret_value, mem, MIN(size, old_size));
H5MM_xfree(mem);
} /* end if */
else
ret_value = HDrealloc(mem, size);
}
else
ret_value = H5MM_malloc(size);
}
else
ret_value = H5MM_xfree(mem);
#else /* H5_MEMORY_ALLOC_SANITY_CHECK */
ret_value = HDrealloc(mem, size);
/* Some platforms do not return NULL if size is zero. */
if (0 == size)
ret_value = NULL;
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
} /* end else */
}
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MM_realloc() */
@ -436,9 +159,6 @@ H5MM_realloc(void *mem, size_t size)
*
* Return: Success: Pointer to a new string (NULL if s is NULL).
* Failure: NULL
*
* Programmer: Robb Matzke
* Jul 10 1997
*-------------------------------------------------------------------------
*/
char *
@ -448,18 +168,9 @@ H5MM_xstrdup(const char *s)
FUNC_ENTER_NOAPI(NULL)
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
if (s) {
if (NULL == (ret_value = (char *)H5MM_malloc(HDstrlen(s) + 1)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
HDstrcpy(ret_value, s);
}
#else
if (s)
if (NULL == (ret_value = HDstrdup(s)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "string duplication failed")
#endif
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MM_xstrdup() */
@ -475,9 +186,6 @@ done:
*
* Return: Success: Pointer to a new string
* Failure: NULL
*
* Programmer: Robb Matzke
* Jul 10 1997
*-------------------------------------------------------------------------
*/
char *
@ -489,14 +197,8 @@ H5MM_strdup(const char *s)
if (!s)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "NULL string not allowed")
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
if (NULL == (ret_value = (char *)H5MM_malloc(HDstrlen(s) + 1)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
HDstrcpy(ret_value, s);
#else
if (NULL == (ret_value = HDstrdup(s)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "string duplication failed")
#endif
done:
FUNC_LEAVE_NOAPI(ret_value)
@ -521,9 +223,6 @@ done:
char *
H5MM_strndup(const char *s, size_t n)
{
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
size_t len;
#endif
char *ret_value = NULL;
FUNC_ENTER_NOAPI(NULL)
@ -531,19 +230,8 @@ H5MM_strndup(const char *s, size_t n)
if (!s)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "NULL string not allowed")
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
for (len = 0; len < n && s[len] != '\0'; len++)
;
if (NULL == (ret_value = H5MM_malloc(len + 1)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
H5MM_memcpy(ret_value, s, len);
ret_value[len] = '\0';
#else
if (NULL == (ret_value = HDstrndup(s, n)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "string duplication failed")
#endif
done:
FUNC_LEAVE_NOAPI(ret_value)
@ -552,18 +240,13 @@ done:
/*-------------------------------------------------------------------------
* Function: H5MM_xfree
*
* Purpose: Just like free(3) except null pointers are allowed as
* arguments, and the return value (always NULL) can be
* assigned to the pointer whose memory was just freed:
* Purpose: Just like free(3) except the return value (always NULL) can
* be assigned to the pointer whose memory was just freed:
*
* thing = H5MM_xfree (thing);
* thing = H5MM_xfree(thing);
*
* Return: Success: NULL
* Failure: never fails
*
* Programmer: Robb Matzke
* Jul 10 1997
*
*-------------------------------------------------------------------------
*/
void *
@ -572,37 +255,7 @@ H5MM_xfree(void *mem)
/* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
FUNC_ENTER_NOAPI_NOINIT_NOERR
if (mem) {
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
if (H5MM__is_our_block(mem)) {
H5MM_block_t *block = H5MM_BLOCK_FROM_BUF(mem);
/* Run sanity checks on this block and its neighbors */
H5MM__sanity_check(mem);
H5MM__sanity_check_block(block->next);
H5MM__sanity_check_block(block->prev);
/* Update statistics */
H5MM_curr_alloc_bytes_s -= block->u.info.size;
H5MM_curr_alloc_blocks_count_s--;
/* Reset block info */
HDmemset(block->sig, 0, H5MM_SIG_SIZE);
block->next->prev = block->prev;
block->prev->next = block->next;
block->next = NULL;
block->prev = NULL;
block->u.info.in_use = FALSE;
/* Free the block (finally!) */
HDfree(block);
}
else
HDfree(mem);
#else /* H5_MEMORY_ALLOC_SANITY_CHECK */
HDfree(mem);
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
} /* end if */
HDfree(mem);
FUNC_LEAVE_NOAPI(NULL)
} /* end H5MM_xfree() */
@ -616,7 +269,6 @@ H5MM_xfree(void *mem)
*
* Return: Success: NULL
* Failure: never fails
*
*-------------------------------------------------------------------------
*/
void *
@ -639,10 +291,6 @@ H5MM_xfree_const(const void *mem)
*
* Return: Success: pointer to dest
* Failure: NULL
*
* Programmer: Dana Robinson
* Spring 2019
*
*-------------------------------------------------------------------------
*/
void *
@ -665,45 +313,3 @@ H5MM_memcpy(void *dest, const void *src, size_t n)
FUNC_LEAVE_NOAPI(ret)
} /* end H5MM_memcpy() */
/*-------------------------------------------------------------------------
* Function: H5MM_get_alloc_stats
*
* Purpose: Gets the memory allocation statistics for the library, if the
* H5_MEMORY_ALLOC_SANITY_CHECK macro is defined. If the macro is not
* defined, zeros are returned. These statistics are global for the
* entire library.
*
* Parameters:
* H5_alloc_stats_t *stats; OUT: Memory allocation statistics
*
* Return: Success: non-negative
* Failure: negative
*
* Programmer: Quincey Koziol
* Saturday, March 7, 2020
*
*-------------------------------------------------------------------------
*/
herr_t
H5MM_get_alloc_stats(H5_alloc_stats_t *stats)
{
FUNC_ENTER_NOAPI_NOERR
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
if (stats) {
stats->total_alloc_bytes = H5MM_total_alloc_bytes_s;
stats->curr_alloc_bytes = H5MM_curr_alloc_bytes_s;
stats->peak_alloc_bytes = H5MM_peak_alloc_bytes_s;
stats->max_block_size = H5MM_max_block_size_s;
stats->total_alloc_blocks_count = H5MM_total_alloc_blocks_count_s;
stats->curr_alloc_blocks_count = H5MM_curr_alloc_blocks_count_s;
stats->peak_alloc_blocks_count = H5MM_peak_alloc_blocks_count_s;
} /* end if */
#else /* H5_MEMORY_ALLOC_SANITY_CHECK */
if (stats)
HDmemset(stats, 0, sizeof(H5_alloc_stats_t));
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5MM_get_alloc_stats() */

View File

@ -13,8 +13,6 @@
/*-------------------------------------------------------------------------
*
* Created: H5MMprivate.h
* Jul 10 1997
* Robb Matzke
*
* Purpose: Private header for memory management.
*
@ -28,29 +26,19 @@
/* Private headers needed by this file */
#include "H5private.h"
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
/*#define H5MM_PRINT_MEMORY_STATS */
#define H5MM_free(Z) H5MM_xfree(Z)
#else /* H5_MEMORY_ALLOC_SANITY_CHECK */
#define H5MM_free(Z) HDfree(Z)
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
/*
* Library prototypes...
*/
H5_DLL void *H5MM_malloc(size_t size) H5_ATTR_MALLOC;
H5_DLL void *H5MM_calloc(size_t size) H5_ATTR_MALLOC;
H5_DLL void *H5MM_realloc(void *mem, size_t size);
H5_DLL char *H5MM_xstrdup(const char *s);
H5_DLL char *H5MM_strdup(const char *s);
H5_DLL char *H5MM_strndup(const char *s, size_t n);
H5_DLL void *H5MM_xfree(void *mem);
H5_DLL void *H5MM_xfree_const(const void *mem);
H5_DLL void *H5MM_memcpy(void *dest, const void *src, size_t n);
H5_DLL herr_t H5MM_get_alloc_stats(H5_alloc_stats_t *stats);
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
H5_DLL void H5MM_sanity_check_all(void);
H5_DLL void H5MM_final_sanity_check(void);
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
H5_DLL void *H5MM_malloc(size_t size) H5_ATTR_MALLOC;
H5_DLL void *H5MM_calloc(size_t size) H5_ATTR_MALLOC;
H5_DLL void *H5MM_realloc(void *mem, size_t size);
H5_DLL char *H5MM_xstrdup(const char *s);
H5_DLL char *H5MM_strdup(const char *s);
H5_DLL char *H5MM_strndup(const char *s, size_t n);
H5_DLL void *H5MM_xfree(void *mem);
H5_DLL void *H5MM_xfree_const(const void *mem);
H5_DLL void *H5MM_memcpy(void *dest, const void *src, size_t n);
#endif /* H5MMprivate_H */

View File

@ -13,8 +13,6 @@
/*-------------------------------------------------------------------------
*
* Created: H5MMpublic.h
* Jul 10 1997
* Robb Matzke
*
* Purpose: Public declarations for the H5MM (memory management)
* package.
@ -36,11 +34,4 @@ typedef void *(*H5MM_allocate_t)(size_t size, void *alloc_info);
typedef void (*H5MM_free_t)(void *mem, void *free_info);
//! <!-- [H5MM_free_t_snip] -->
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* H5MMpublic_H */

View File

@ -353,15 +353,6 @@ extern "C" {
* release builds. Static links to the MSVC CRT can also introduce
* new memory allocator state.
*
* Note that the HDF5 library enabled memory sanity checks by default
* in debug builds for many years. The heap canaries introduced to
* buffers by this mechanism would cause problems when filters
* attempted to reallocate these buffers. The sanity checks are no
* longer enabled by default in any configuration. When in doubt,
* memory sanity checking can be disabled explicitly by configuring
* with `--disable-memory-alloc-sanity-check` in the Autotools or
* setting `HDF5_MEMORY_ALLOC_SANITY_CHECK` to `OFF` in CMake.
*
* The library does provide H5allocate_memory() and H5free_memory()
* functions that will use the library's allocation and free functions,
* however using these functions will require linking your filter to

View File

@ -396,19 +396,6 @@ typedef struct H5O_token_t {
} H5O_token_t;
//! <!-- [H5O_token_t_snip] -->
/**
* Allocation statistics info struct
*/
typedef struct H5_alloc_stats_t {
unsigned long long total_alloc_bytes; /**< Running count of total # of bytes allocated */
size_t curr_alloc_bytes; /**< Current # of bytes allocated */
size_t peak_alloc_bytes; /**< Peak # of bytes allocated */
size_t max_block_size; /**< Largest block allocated */
size_t total_alloc_blocks_count; /**< Running count of total # of blocks allocated */
size_t curr_alloc_blocks_count; /**< Current # of blocks allocated */
size_t peak_alloc_blocks_count; /**< Peak # of blocks allocated */
} H5_alloc_stats_t;
/**
* Library shutdown callback, used by H5atclose().
*/
@ -589,27 +576,6 @@ H5_DLL herr_t H5set_free_list_limits(int reg_global_lim, int reg_list_lim, int a
* \since 1.10.7
*/
H5_DLL herr_t H5get_free_list_sizes(size_t *reg_size, size_t *arr_size, size_t *blk_size, size_t *fac_size);
/**
* \ingroup H5
* \brief Gets the memory allocation statistics for the library
*
* \param[out] stats Memory allocation statistics
* \return \herr_t
*
* \details H5get_alloc_stats() gets the memory allocation statistics for the
* library, if the \c --enable-memory-alloc-sanity-check option was
* given when building the library. Applications can check whether
* this option was enabled detecting if the
* \c H5_MEMORY_ALLOC_SANITY_CHECK macro is defined. This option is
* enabled by default for debug builds of the library and disabled by
* default for non-debug builds. If the option is not enabled, all the
* values returned with be 0. These statistics are global for the
* entire library, but do not include allocations from chunked dataset
* I/O filters or non-native VOL connectors.
*
* \since 1.10.7
*/
H5_DLL herr_t H5get_alloc_stats(H5_alloc_stats_t *stats);
/**
* \ingroup H5
* \brief Returns the HDF library release number

View File

@ -1543,18 +1543,6 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap)
case 'H':
switch (type[1]) {
case 'a': /* H5_alloc_stats_t */
{
H5_alloc_stats_t stats = HDva_arg(ap, H5_alloc_stats_t);
H5RS_asprintf_cat(rs, "{%llu, %zu, %zu, %zu, %zu, %zu, %zu}",
stats.total_alloc_bytes, stats.curr_alloc_bytes,
stats.peak_alloc_bytes, stats.max_block_size,
stats.total_alloc_blocks_count, stats.curr_alloc_blocks_count,
stats.peak_alloc_blocks_count);
} /* end block */
break;
case 'c': /* H5_atclose_func_t */
{
H5_atclose_func_t cfunc = (H5_atclose_func_t)HDva_arg(ap, H5_atclose_func_t);

View File

@ -90,7 +90,6 @@ Dimension scales w/ new references: @DIMENSION_SCALES_WITH_NEW_REF@
Packages w/ extra debug output: @INTERNAL_DEBUG_OUTPUT@
API tracing: @TRACE_API@
Using memory checker: @USINGMEMCHECKER@
Memory allocation sanity checks: @MEMORYALLOCSANITYCHECK@
Function stack tracing: @CODESTACK@
Use file locking: @DESIRED_FILE_LOCKING@
Strict file format checks: @STRICT_FORMAT_CHECKS@

View File

@ -5825,16 +5825,6 @@ test_misc34(void)
mem = H5MM_xfree(mem);
CHECK_PTR_NULL(mem, "H5MM_xfree");
/* H5MM_malloc(): Ensure that size 0 returns NULL */
mem = H5MM_malloc(sz);
CHECK_PTR_NULL(mem, "H5MM_malloc");
mem = H5MM_xfree(mem);
/* H5MM_calloc(): Ensure that size 0 returns NULL */
mem = H5MM_calloc(sz);
CHECK_PTR_NULL(mem, "H5MM_calloc");
mem = H5MM_xfree(mem);
/* H5MM_realloc(): Check behavior:
*
* H5MM_realloc(NULL, size) <==> H5MM_malloc(size)
@ -5877,16 +5867,15 @@ test_misc35(void)
hsize_t coord[MISC35_NPOINTS][MISC35_SPACE_RANK] = /* Coordinates for point selection */
{{0, 10, 5}, {1, 2, 7}, {2, 4, 9}, {0, 6, 11}, {1, 8, 13},
{2, 12, 0}, {0, 14, 2}, {1, 0, 4}, {2, 1, 6}, {0, 3, 8}};
size_t reg_size_start; /* Initial amount of regular memory allocated */
size_t arr_size_start; /* Initial amount of array memory allocated */
size_t blk_size_start; /* Initial amount of block memory allocated */
size_t fac_size_start; /* Initial amount of factory memory allocated */
size_t reg_size_final; /* Final amount of regular memory allocated */
size_t arr_size_final; /* Final amount of array memory allocated */
size_t blk_size_final; /* Final amount of block memory allocated */
size_t fac_size_final; /* Final amount of factory memory allocated */
H5_alloc_stats_t alloc_stats; /* Memory stats */
herr_t ret; /* Return value */
size_t reg_size_start; /* Initial amount of regular memory allocated */
size_t arr_size_start; /* Initial amount of array memory allocated */
size_t blk_size_start; /* Initial amount of block memory allocated */
size_t fac_size_start; /* Initial amount of factory memory allocated */
size_t reg_size_final; /* Final amount of regular memory allocated */
size_t arr_size_final; /* Final amount of array memory allocated */
size_t blk_size_final; /* Final amount of block memory allocated */
size_t fac_size_final; /* Final amount of factory memory allocated */
herr_t ret; /* Return value */
/* Output message about test being performed */
MESSAGE(5, ("Free-list API calls"));
@ -5914,13 +5903,13 @@ test_misc35(void)
CHECK(arr_size_start, 0, "H5get_free_list_sizes");
CHECK(blk_size_start, 0, "H5get_free_list_sizes");
CHECK(fac_size_start, 0, "H5get_free_list_sizes");
#else /* H5_MEMORY_ALLOC_SANITY_CHECK */
#else
/* All the values should be == 0 */
VERIFY(reg_size_start, 0, "H5get_free_list_sizes");
VERIFY(arr_size_start, 0, "H5get_free_list_sizes");
VERIFY(blk_size_start, 0, "H5get_free_list_sizes");
VERIFY(fac_size_start, 0, "H5get_free_list_sizes");
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
#endif
/* Garbage collect the free lists */
ret = H5garbage_collect();
@ -5940,30 +5929,6 @@ test_misc35(void)
if (fac_size_final > fac_size_start)
ERROR("fac_size_final > fac_size_start");
/* Retrieve memory allocation statistics */
ret = H5get_alloc_stats(&alloc_stats);
CHECK(ret, FAIL, "H5get_alloc_stats");
#if defined H5_MEMORY_ALLOC_SANITY_CHECK
/* All the values should be >0 */
CHECK(alloc_stats.total_alloc_bytes, 0, "H5get_alloc_stats");
CHECK(alloc_stats.curr_alloc_bytes, 0, "H5get_alloc_stats");
CHECK(alloc_stats.peak_alloc_bytes, 0, "H5get_alloc_stats");
CHECK(alloc_stats.max_block_size, 0, "H5get_alloc_stats");
CHECK(alloc_stats.total_alloc_blocks_count, 0, "H5get_alloc_stats");
CHECK(alloc_stats.curr_alloc_blocks_count, 0, "H5get_alloc_stats");
CHECK(alloc_stats.peak_alloc_blocks_count, 0, "H5get_alloc_stats");
#else /* H5_MEMORY_ALLOC_SANITY_CHECK */
/* All the values should be == 0 */
VERIFY(alloc_stats.total_alloc_bytes, 0, "H5get_alloc_stats");
VERIFY(alloc_stats.curr_alloc_bytes, 0, "H5get_alloc_stats");
VERIFY(alloc_stats.peak_alloc_bytes, 0, "H5get_alloc_stats");
VERIFY(alloc_stats.max_block_size, 0, "H5get_alloc_stats");
VERIFY(alloc_stats.total_alloc_blocks_count, 0, "H5get_alloc_stats");
VERIFY(alloc_stats.curr_alloc_blocks_count, 0, "H5get_alloc_stats");
VERIFY(alloc_stats.peak_alloc_blocks_count, 0, "H5get_alloc_stats");
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
} /* end test_misc35() */
/* Context to pass to 'atclose' callbacks */