From 65a13a3b73dd403acb0ba15a0666579b906a6fee Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Mon, 14 Mar 2022 08:04:54 -0500 Subject: 1.8 Fix release check version logic #1438 (#1495) --- config/cmake/scripts/HDF5config.cmake | 6 +- release_docs/RELEASE.txt | 18 ++++- src/H5.c | 93 +++++++++++++++++++++----- test/CMakeTests.cmake | 2 +- test/testcheck_version.sh.in | 122 +++++++++++++++++----------------- 5 files changed, 158 insertions(+), 83 deletions(-) diff --git a/config/cmake/scripts/HDF5config.cmake b/config/cmake/scripts/HDF5config.cmake index 5a44cde..21fbbfa 100755 --- a/config/cmake/scripts/HDF5config.cmake +++ b/config/cmake/scripts/HDF5config.cmake @@ -68,7 +68,7 @@ endif () # build generator must be defined if (NOT DEFINED BUILD_GENERATOR) - message (FATAL_ERROR "BUILD_GENERATOR must be defined - Unix, VS2019, VS201964, VS2017, or VS201764, VS2015, VS201564") + message (FATAL_ERROR "BUILD_GENERATOR must be defined - Unix, VS2019, VS201964, VS2017, VS201764, VS2015, VS201564") endif () ################################################################### @@ -105,7 +105,7 @@ endif () ######### Following describes compiler ############ if (NOT DEFINED HPC) if (NOT DEFINED BUILD_GENERATOR) - message (FATAL_ERROR "BUILD_GENERATOR must be defined - Unix, VS2019, VS201964, VS2017, or VS201764, VS2015, VS201564") + message (FATAL_ERROR "BUILD_GENERATOR must be defined - Unix, VS2019, VS201964, VS2017, VS201764, VS2015, VS201564") endif () if (WIN32 AND NOT MINGW) set (SITE_OS_NAME "Windows") @@ -163,7 +163,7 @@ if (NOT DEFINED HPC) set (SITE_COMPILER_NAME "vs2012") set (SITE_COMPILER_VERSION "11") else () - message (FATAL_ERROR "Invalid BUILD_GENERATOR must be - Unix, VS2017, or VS201764, VS2015, VS201564, VS2013, VS201364") + message (FATAL_ERROR "Invalid BUILD_GENERATOR must be - Unix, VS2019, VS201964, VS2017, VS201764, VS2015, VS201564") endif () ## Set the following to unique id your computer ## set (CTEST_SITE "WIN7${BUILD_GENERATOR}.XXXX") diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index d28f162..08ea134 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -313,7 +313,23 @@ Bug Fixes since HDF5-1.8.22 Library ------- - - None + - Issue #1436 identified a problem with the H5_VERS_RELEASE check in the + H5check_version function. + + Investigating the original fix, #812, we discovered some inconsistencies + with a new block added to check H5_VERS_RELEASE for incompatibilities. + This new block was not using the new warning text dealing with the + H5_VERS_RELEASE check and would cause the warning to be duplicated. + + By removing the H5_VERS_RELEASE argument in the first check for + H5_VERS_MAJOR and H5_VERS_MINOR, the second check would only check + the H5_VERS_RELEASE for incompatible release versions. This adheres + to the statement that except for the develop branch, all release versions + in a major.minor maintenance branch should be compatible. The prerequisite + is that an application will not use any APIs not present in all release versions. + + (ADB - 2022/03/11, #1438) + Performance diff --git a/src/H5.c b/src/H5.c index cdc0ecd..d2f8fdc 100644 --- a/src/H5.c +++ b/src/H5.c @@ -57,6 +57,10 @@ static int H5_mpi_delete_cb(MPI_Comm comm, int keyval, void *attr_val, int *flag /* Library Private Variables */ /*****************************/ +/* Library incompatible release versions */ +const unsigned VERS_RELEASE_EXCEPTIONS[] = {0}; +const unsigned VERS_RELEASE_EXCEPTIONS_SIZE = 0; + /* statically initialize block for pthread_once call used in initializing */ /* the first global mutex */ #ifdef H5_HAVE_THREADSAFE @@ -635,17 +639,20 @@ done: } /* end H5get_libversion() */ /*------------------------------------------------------------------------- - * Function: H5check_version + * Function: H5check_version * - * Purpose: Verifies that the arguments match the version numbers - * compiled into the library. This function is intended to be - * called from user to verify that the versions of header files - * compiled into the application match the version of the hdf5 - * library. + * Purpose: Verifies that the arguments match the version numbers + * compiled into the library. This function is intended to be + * called from user to verify that the versions of header files + * compiled into the application match the version of the hdf5 + * library. + * Within major.minor.release version, the expectation + * is that all release versions are compatible, exceptions to + * this rule must be added to the VERS_RELEASE_EXCEPTIONS list. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: abort() + * Failure: abort() * *------------------------------------------------------------------------- */ @@ -658,6 +665,15 @@ done: "linked with a different version of static or shared HDF5 library.\n" \ "You should recompile the application or check your shared library related\n" \ "settings such as 'LD_LIBRARY_PATH'.\n" +#define RELEASE_MISMATCH_WARNING \ + "Warning! ***HDF5 library release mismatched error***\n" \ + "The HDF5 header files used to compile this application are not compatible with\n" \ + "the version used by the HDF5 library to which this application is linked.\n" \ + "Data corruption or segmentation faults may occur if the application continues.\n" \ + "This can happen when an application was compiled by one version of HDF5 but\n" \ + "linked with an incompatible version of static or shared HDF5 library.\n" \ + "You should recompile the application or check your shared library related\n" \ + "settings such as 'LD_LIBRARY_PATH'.\n" herr_t H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) @@ -667,6 +683,7 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) static int checked = 0; /* If we've already checked the version info */ static unsigned int disable_version_check = 0; /* Set if the version check should be disabled */ static const char * version_mismatch_warning = VERSION_MISMATCH_WARNING; + static const char * release_mismatch_warning = RELEASE_MISMATCH_WARNING; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT_NOERR_NOFS @@ -686,7 +703,8 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) disable_version_check = (unsigned int)HDstrtol(s, NULL, 0); } - if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum || H5_VERS_RELEASE != relnum) { + /* H5_VERS_MAJOR and H5_VERS_MINOR must match */ + if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum) { switch (disable_version_check) { case 0: HDfprintf(stderr, "%s%s", version_mismatch_warning, @@ -721,7 +739,51 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) break; } /* end switch */ - } /* end if */ + } /* end if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum) */ + + /* H5_VERS_RELEASE should be compatible, we will only add checks for exceptions */ + if (H5_VERS_RELEASE != relnum) { + for (unsigned i = 0; i < VERS_RELEASE_EXCEPTIONS_SIZE; i++) { + /* Check for incompatible headers or incompatible library */ + if (VERS_RELEASE_EXCEPTIONS[i] == relnum || VERS_RELEASE_EXCEPTIONS[i] == H5_VERS_RELEASE) { + switch (disable_version_check) { + case 0: + HDfprintf( + stderr, "%s%s", release_mismatch_warning, + "You can, at your own risk, disable this warning by setting the environment\n" + "variable 'HDF5_DISABLE_VERSION_CHECK' to a value of '1'.\n" + "Setting it to 2 or higher will suppress the warning messages totally.\n"); + /* Mention the versions we are referring to */ + HDfprintf(stderr, "Headers are %u.%u.%u, library is %u.%u.%u\n", majnum, minnum, + relnum, (unsigned)H5_VERS_MAJOR, (unsigned)H5_VERS_MINOR, + (unsigned)H5_VERS_RELEASE); + + /* Bail out now. */ + HDfputs("Bye...\n", stderr); + HDabort(); + case 1: + /* continue with a warning */ + /* Note that the warning message is embedded in the format string.*/ + HDfprintf(stderr, + "%s'HDF5_DISABLE_VERSION_CHECK' " + "environment variable is set to %d, application will\n" + "continue at your own risk.\n", + release_mismatch_warning, disable_version_check); + /* Mention the versions we are referring to */ + HDfprintf(stderr, "Headers are %u.%u.%u, library is %u.%u.%u\n", majnum, minnum, + relnum, (unsigned)H5_VERS_MAJOR, (unsigned)H5_VERS_MINOR, + (unsigned)H5_VERS_RELEASE); + break; + default: + /* 2 or higher: continue silently */ + break; + } /* end switch */ + + } /* end if */ + + } /* end for */ + + } /* end if (H5_VERS_RELEASE != relnum) */ /* Indicate that the version check has been performed */ checked = 1; @@ -732,13 +794,10 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) * Check only the first sizeof(lib_str) char. Assume the information * will fit within this size or enough significance. */ - HDsnprintf(lib_str, sizeof(lib_str), "HDF5 library version: %d.%d.%d", H5_VERS_MAJOR, H5_VERS_MINOR, - H5_VERS_RELEASE); - if (*substr) { - HDstrncat(lib_str, "-", (size_t)1); - HDstrncat(lib_str, substr, (sizeof(lib_str) - HDstrlen(lib_str)) - 1); - } /* end if */ - if (HDstrcmp(lib_str, H5_lib_vers_info_g)) { + HDsnprintf(lib_str, sizeof(lib_str), "HDF5 library version: %d.%d.%d%s%s", H5_VERS_MAJOR, + H5_VERS_MINOR, H5_VERS_RELEASE, (*substr ? "-" : ""), substr); + + if (HDstrcmp(lib_str, H5_lib_vers_info_g) != 0) { HDfputs("Warning! Library version information error.\n" "The HDF5 library version information are not " "consistent in its source code.\nThis is NOT a fatal error " diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake index 78722a6..21bd20d 100644 --- a/test/CMakeTests.cmake +++ b/test/CMakeTests.cmake @@ -376,10 +376,10 @@ set_tests_properties (H5TEST-tcheck_version-minor PROPERTIES WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST WILL_FAIL "true" ) +# release + 1 should pass on non-develop branches add_test (NAME H5TEST-tcheck_version-release COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ "-tr") set_tests_properties (H5TEST-tcheck_version-release PROPERTIES WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST - WILL_FAIL "true" ) ############################################################################## diff --git a/test/testcheck_version.sh.in b/test/testcheck_version.sh.in index 667a137..273702e 100644 --- a/test/testcheck_version.sh.in +++ b/test/testcheck_version.sh.in @@ -15,7 +15,7 @@ # Tests for the H5check_version function. # # Programmer: Albert Cheng -# Sep 28, 2009 +# Sep 28, 2009 srcdir=@srcdir@ @@ -24,7 +24,7 @@ srcdir=@srcdir@ Shared_Lib=@enable_shared@ Static_Lib=@enable_static@ Static_exec=@STATIC_EXEC@ -h5haveexitcode=yes # default is yes +h5haveexitcode=yes # default is yes CMP='cmp -s' DIFF='diff -c' @@ -36,7 +36,7 @@ RM='rm -f' PURPOSE() { echo "Tests for the H5check_version function." echo "Note that abort messages may appear due to the expected termination" - echo "of the program when it is tested with mis-matched version numnbers." + echo "of the program when it is tested with mis-matched version numbers." } # Print a line-line message left justified in a field of 70 characters. @@ -71,7 +71,7 @@ WarnMesg(){ test -n "$H5_HAVE_EMBEDDED_LIBINFO" && cat $h5libsettings echo "Bye..." } - + # Print warning message2 of version mismatch. WarnMesg2(){ @@ -88,13 +88,13 @@ WarnMesg2(){ echo "Headers are $xxh5versmajor.$xxh5versminor.$xxh5versrelease, library is $h5versmajor.$h5versminor.$h5versrelease" test -n "$H5_HAVE_EMBEDDED_LIBINFO" && cat $h5libsettings } - + # Run a test and print PASS or *FAIL*. If a test fails then increment # the `nerrors' global variable and (if $verbose is set) display the # difference between the actual output and the expected output. The # expected output generated according to the parameter values and compared -# against actual output. +# against actual output. # The expected and actual output files are removed unless $HDF5_NOCLEANUP # has a non-zero value. # $1: the set value of $HDF5_DISABLE_VERSION_CHECK. (unset means not to set @@ -103,10 +103,10 @@ WarnMesg2(){ # mismatch). # # Expected results: -# Value of $HDF5_DISABLE_VERSION_CHECK -# unset "" -1 0 1 2 3 -# Matched OK OK OK OK OK OK OK -# Mismatched W/A W/A W/A W/A W2/OK OK W2/OK +# Value of $HDF5_DISABLE_VERSION_CHECK +# unset "" -1 0 1 2 3 +# Matched OK OK OK OK OK OK OK +# Mismatched W/A W/A W/A W/A W2/OK OK W2/OK # Result codes: # OK: No warning, exit 0. # W/A: Warning, abort and exit non-0. @@ -130,42 +130,42 @@ TESTING() { xxh5versrelease=$h5versrelease if [ "$h5DisableVersion" = unset ]; then - envcmd="" # noop + envcmd="" # noop else - envcmd="env HDF5_DISABLE_VERSION_CHECK=$h5DisableVersion" + envcmd="env HDF5_DISABLE_VERSION_CHECK=$h5DisableVersion" fi if [ "$wrongversionnumbers" = none ]; then - # OK: No warning, exit 0 - cp /dev/null $expect - expect_code=0 + # OK: No warning, exit 0 + cp /dev/null $expect + expect_code=0 else - arguments=-t"$wrongversionnumbers" - # calculate mismatched version numbers by listing. - case $wrongversionnumbers in - "M") xxh5versmajor=`expr $h5versmajor + 1` - ;; - "m") xxh5versminor=`expr $h5versminor + 1` - ;; - "r") xxh5versrelease=`expr $h5versrelease + 1` - ;; - esac - case "$h5DisableVersion" in - 1) - # W2/OK: Different Warning, exit 0. - WarnMesg2 > $expect - expect_code=0 - ;; - [2-9]|[1-9][0-9]*) - # OK: No warning, exit 0 - cp /dev/null $expect - expect_code=0 - ;; - *) # W/A: Warning, abort and exit non-0. - WarnMesg > $expect - expect_code=6 # Signal Abort exit code (128+6) - ;; - esac + arguments=-t"$wrongversionnumbers" + # calculate mismatched version numbers by listing. + case $wrongversionnumbers in + "M") xxh5versmajor=`expr $h5versmajor + 1` + ;; + "m") xxh5versminor=`expr $h5versminor + 1` + ;; + "r") xxh5versrelease=`expr $h5versrelease + 1` + ;; + esac + case "$h5DisableVersion" in + 1) + # W2/OK: Different Warning, exit 0. + WarnMesg2 > $expect + expect_code=0 + ;; + [2-9]|[1-9][0-9]*) + # OK: No warning, exit 0 + cp /dev/null $expect + expect_code=0 + ;; + *) # W/A: Warning, abort and exit non-0. + WarnMesg > $expect + expect_code=6 # Signal Abort exit code (128+6) + ;; + esac fi # Run test. @@ -175,25 +175,25 @@ TESTING() { ) >$actual 2>$actual_err ret_code=$? cat $actual_err >> $actual - + if [ $h5haveexitcode = 'yes' -a \( $expect_code -ne $ret_code \) ]; then - echo "*FAILED*" - echo " Expected exit code ($expect_code) differs from actual code ($ret_code)" - nerrors="`expr $nerrors + 1`" + echo "*FAILED*" + echo " Expected exit code ($expect_code) differs from actual code ($ret_code)" + nerrors="`expr $nerrors + 1`" elif $CMP $expect $actual; then - echo " PASSED" + echo " PASSED" else - echo "*FAILED*" - echo " Expected result differs from actual result" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' + echo "*FAILED*" + echo " Expected result differs from actual result" + nerrors="`expr $nerrors + 1`" + test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' fi - # Clean up output file. + # Clean up output file. # Also clean the core file generated by H5check_version's abort. if test -z "$HDF5_NOCLEANUP"; then - $RM $expect $actual $actual_err - $RM core + $RM $expect $actual $actual_err + $RM core fi } @@ -201,17 +201,17 @@ TESTING() { # Echo parameters for debugging if verbose mode is on. DEBUGPRINT() { if [ -n "$debugmode" ]; then - echo $* + echo $* fi } # MAIN Body nerrors=0 -verbose=yes # default on -debugmode= # default off +verbose=yes # default on +debugmode= # default off H5_HAVE_EMBEDDED_LIBINFO=`grep '#define H5_HAVE_EMBEDDED_LIBINFO ' ../src/H5pubconf.h` -h5libsettings=../src/libhdf5.settings +h5libsettings=../src/libhdf5.settings PURPOSE @@ -232,7 +232,7 @@ esac # RUNSERIAL is used. Check if it can return exit code from executalbe correctly. if [ -n "$RUNSERIAL_NOEXITCODE" ]; then - echo "***Warning*** Serial Exit Code is not passed back to shell corretly." + echo "***Warning*** Serial Exit Code is not passed back to shell correctly." echo "***Warning*** Exit code checking is skipped." h5haveexitcode=no fi @@ -240,13 +240,13 @@ fi # Three Categories of tests: # Normal: where the version numbers all matched (wrong_version == none). # Mismatched version numbers (could be Major or minor version -# or release numbers or a combination of all three.) +# or release numbers or a combination of all three.) # Test all the above with different values of the environment variable, # HDF5_DISABLE_VERSION_CHECK, as unset, "", -1, 0, 1, 2, 3 for val_disable_version_check in unset "" -1 0 1 2 3; do - for wrong_version in none M m r; do - TESTING "$val_disable_version_check" "$wrong_version" + for wrong_version in none M m; do + TESTING "$val_disable_version_check" "$wrong_version" done done -- cgit v0.12