diff options
-rw-r--r-- | CMakeLists.txt | 8 | ||||
-rwxr-xr-x | bin/trace | 1 | ||||
-rw-r--r-- | config/cmake/ConfigureChecks.cmake | 1 | ||||
-rw-r--r-- | config/cmake/H5pubconf.h.in | 6 | ||||
-rw-r--r-- | config/cmake/HDF5DeveloperBuild.cmake | 7 | ||||
-rw-r--r-- | config/cmake/libhdf5.settings.cmake.in | 1 | ||||
-rw-r--r-- | configure.ac | 46 | ||||
-rw-r--r-- | release_docs/INSTALL_CMake.txt | 1 | ||||
-rw-r--r-- | release_docs/RELEASE.txt | 33 | ||||
-rw-r--r-- | src/H5.c | 53 | ||||
-rw-r--r-- | src/H5MM.c | 408 | ||||
-rw-r--r-- | src/H5MMprivate.h | 30 | ||||
-rw-r--r-- | src/H5MMpublic.h | 9 | ||||
-rw-r--r-- | src/H5Zdevelop.h | 9 | ||||
-rw-r--r-- | src/H5public.h | 34 | ||||
-rw-r--r-- | src/H5trace.c | 12 | ||||
-rw-r--r-- | src/libhdf5.settings.in | 1 | ||||
-rw-r--r-- | test/tmisc.c | 57 |
18 files changed, 63 insertions, 654 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 15caa32..1148f2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -561,14 +561,6 @@ if (HDF5_ENABLE_USING_MEMCHECKER) 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 #----------------------------------------------------------------------------- option (HDF5_ENABLE_PREADWRITE "Use pread/pwrite in sec2/log/core VFDs in place of read/write (when available)" ON) @@ -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 diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake index 3de4483..d4da06f 100644 --- a/config/cmake/ConfigureChecks.cmake +++ b/config/cmake/ConfigureChecks.cmake @@ -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) diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in index 1f2e1b5..70813ac 100644 --- a/config/cmake/H5pubconf.h.in +++ b/config/cmake/H5pubconf.h.in @@ -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@ diff --git a/config/cmake/HDF5DeveloperBuild.cmake b/config/cmake/HDF5DeveloperBuild.cmake index 53c03de..40efb0e 100644 --- a/config/cmake/HDF5DeveloperBuild.cmake +++ b/config/cmake/HDF5DeveloperBuild.cmake @@ -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 () diff --git a/config/cmake/libhdf5.settings.cmake.in b/config/cmake/libhdf5.settings.cmake.in index 48016d8..49caf83 100644 --- a/config/cmake/libhdf5.settings.cmake.in +++ b/config/cmake/libhdf5.settings.cmake.in @@ -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@ diff --git a/configure.ac b/configure.ac index c52be91..fed9ca7 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/release_docs/INSTALL_CMake.txt b/release_docs/INSTALL_CMake.txt index ad030fa..94b14d9 100644 --- a/release_docs/INSTALL_CMake.txt +++ b/release_docs/INSTALL_CMake.txt @@ -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 diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 5945e22..e435cae 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -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 @@ -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; @@ -716,46 +711,6 @@ done: } /* 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 * * Purpose: Set runtime debugging flags according to the string S. The @@ -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 @@ -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() */ diff --git a/src/H5MMprivate.h b/src/H5MMprivate.h index 02c2bb8..130a83e 100644 --- a/src/H5MMprivate.h +++ b/src/H5MMprivate.h @@ -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 */ diff --git a/src/H5MMpublic.h b/src/H5MMpublic.h index 36a8293..778c6e3 100644 --- a/src/H5MMpublic.h +++ b/src/H5MMpublic.h @@ -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 */ diff --git a/src/H5Zdevelop.h b/src/H5Zdevelop.h index a757163..346eb0e 100644 --- a/src/H5Zdevelop.h +++ b/src/H5Zdevelop.h @@ -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 diff --git a/src/H5public.h b/src/H5public.h index 745cd18..345191c 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -397,19 +397,6 @@ typedef struct 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(). */ typedef void (*H5_atclose_func_t)(void *ctx); @@ -591,27 +578,6 @@ H5_DLL herr_t H5set_free_list_limits(int reg_global_lim, int reg_list_lim, int a 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 * * \param[out] majnum The major version number of the library diff --git a/src/H5trace.c b/src/H5trace.c index 49500ea..03eaf11 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -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); diff --git a/src/libhdf5.settings.in b/src/libhdf5.settings.in index 9f5a58a..dbdbc74 100644 --- a/src/libhdf5.settings.in +++ b/src/libhdf5.settings.in @@ -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@ diff --git a/test/tmisc.c b/test/tmisc.c index 263e81e..5cad368 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -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 */ |