From d697acbfb588b0406403109398105e12562e2d3e Mon Sep 17 00:00:00 2001 From: Jonathan Kim Date: Fri, 18 Mar 2011 13:50:19 -0500 Subject: [svn-r20270] Purpose: Improve the previous fix for Bug 2216 - GMQS: h5diff - memory leak when compares vlen string in dataset or attributes Description: Improve the fix along with the previous checkin r20266. Add a new function to tool lib, h5tools_detect_vlen_data() which return TRUE if include any kind of vlen data all at once, either VLEN-data or VLEN-string and so on. Also updated h5ls and h5dump code accordingly. Tested: jam (linux32-LE), amani (linux64-LE), heiwa (linuxppc64-BE), tejeda (mac32-LE), linew (solaris-BE), Cmake - jam --- release_docs/RELEASE.txt | 2 ++ tools/h5dump/h5dump.c | 8 ++------ tools/h5ls/h5ls.c | 4 +--- tools/lib/h5diff_attr.c | 12 ++++-------- tools/lib/h5diff_dset.c | 5 +---- tools/lib/h5tools.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ tools/lib/h5tools.h | 1 + 7 files changed, 60 insertions(+), 21 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 47bfd33..6b1e0e7 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -506,6 +506,8 @@ Bug Fixes since HDF5-1.8.0 release Tools ----- + - Fixed memory leak for h5diff when access variable length string + data. Bug#2216 (JKM 2011/3/18) - Fixed and improved help page for -a option of h5ls. Bug#1904 (JKM 2011/3/11) - Fixed h5dump not to include attribute values in the output file when diff --git a/tools/h5dump/h5dump.c b/tools/h5dump/h5dump.c index 817f1cf..80cce55 100644 --- a/tools/h5dump/h5dump.c +++ b/tools/h5dump/h5dump.c @@ -2559,9 +2559,7 @@ dump_data(hid_t obj_id, int obj_data, struct subset_t *sset, int display_index) ndims = H5Sget_simple_extent_dims(space, size, NULL); /* Check if we have VL data in the dataset's datatype */ - if (h5tools_detect_vlen_str(p_type) == TRUE) - vl_data = TRUE; - if (H5Tdetect_class(p_type, H5T_VLEN) == TRUE) + if (h5tools_detect_vlen_data(p_type) == TRUE) vl_data = TRUE; for (i = 0; i < ndims; i++) @@ -5527,9 +5525,7 @@ xml_dump_data(hid_t obj_id, int obj_data, struct subset_t UNUSED * sset, int UNU p_type = h5tools_get_native_type(type); /* Check if we have VL data in the dataset's datatype */ - if (h5tools_detect_vlen_str(p_type) == TRUE) - vl_data = TRUE; - if (H5Tdetect_class(p_type, H5T_VLEN) == TRUE) + if (h5tools_detect_vlen_data(p_type) == TRUE) vl_data = TRUE; H5Tclose(type); diff --git a/tools/h5ls/h5ls.c b/tools/h5ls/h5ls.c index d288f4b..8fa037e 100644 --- a/tools/h5ls/h5ls.c +++ b/tools/h5ls/h5ls.c @@ -1457,10 +1457,8 @@ list_attr(hid_t obj, const char *attr_name, const H5A_info_t UNUSED *ainfo, unsigned int vl_data = 0; /* contains VL datatypes */ /* Check if we have VL data in the dataset's datatype */ - if (h5tools_detect_vlen_str(p_type) == TRUE) + if (h5tools_detect_vlen_data(p_type) == TRUE) vl_data = TRUE; - if (H5Tdetect_class(p_type, H5T_VLEN) == TRUE) - vl_data = TRUE; temp_need= nelmts * MAX(H5Tget_size(type), H5Tget_size(p_type)); assert(temp_need == (hsize_t)((size_t)temp_need)); diff --git a/tools/lib/h5diff_attr.c b/tools/lib/h5diff_attr.c index 1742028..01fa896 100644 --- a/tools/lib/h5diff_attr.c +++ b/tools/lib/h5diff_attr.c @@ -223,14 +223,12 @@ hsize_t diff_attr(hid_t loc1_id, /* Free buf1 and buf2, check both VLEN-data VLEN-string to reclaim any * VLEN memory first */ - if(TRUE == H5Tdetect_class(mtype1_id, H5T_VLEN) || - TRUE == h5tools_detect_vlen_str(mtype1_id)) + if(TRUE == h5tools_detect_vlen_data(mtype1_id)) H5Dvlen_reclaim(mtype1_id, space1_id, H5P_DEFAULT, buf1); HDfree(buf1); buf1 = NULL; - if(TRUE == H5Tdetect_class(mtype2_id, H5T_VLEN) || - TRUE == h5tools_detect_vlen_str(mtype2_id)) + if(TRUE == h5tools_detect_vlen_data(mtype2_id)) H5Dvlen_reclaim(mtype2_id, space2_id, H5P_DEFAULT, buf2); HDfree(buf2); buf2 = NULL; @@ -260,14 +258,12 @@ hsize_t diff_attr(hid_t loc1_id, error: H5E_BEGIN_TRY { if(buf1) { - if(TRUE == H5Tdetect_class(mtype1_id, H5T_VLEN) || - TRUE == h5tools_detect_vlen_str(mtype1_id)) + if(TRUE == h5tools_detect_vlen_data(mtype1_id)) H5Dvlen_reclaim(mtype1_id, space1_id, H5P_DEFAULT, buf1); HDfree(buf1); } /* end if */ if(buf2) { - if(TRUE == H5Tdetect_class(mtype2_id, H5T_VLEN) || - TRUE == h5tools_detect_vlen_str(mtype2_id)) + if(TRUE == h5tools_detect_vlen_data(mtype2_id)) H5Dvlen_reclaim(mtype2_id, space2_id, H5P_DEFAULT, buf2); HDfree(buf2); } /* end if */ diff --git a/tools/lib/h5diff_dset.c b/tools/lib/h5diff_dset.c index b21230b..b1193c6 100644 --- a/tools/lib/h5diff_dset.c +++ b/tools/lib/h5diff_dset.c @@ -330,11 +330,8 @@ hsize_t diff_datasetid( hid_t did1, /* Check if type is either VLEN-data or VLEN-string to reclaim any * VLEN memory buffer later */ - if(TRUE == H5Tdetect_class(m_tid1, H5T_VLEN) || - TRUE == h5tools_detect_vlen_str(m_tid1)) - { + if( TRUE == h5tools_detect_vlen_data(m_tid1) ) vl_data = TRUE; - } /*------------------------------------------------------------------------- * only attempt to compare if possible diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c index 1982bad..84a164b 100644 --- a/tools/lib/h5tools.c +++ b/tools/lib/h5tools.c @@ -622,6 +622,55 @@ h5tools_ncols(const char *s) } /*------------------------------------------------------------------------- + * Function: h5tools_detect_vlen_data + * + * Purpose: Recursive check for any variable length data in given type. + * + * Return: TRUE if type conatains any variable length data, else FALSE + * + * Programmer: Jonathan Kim March 18, 2011 + * + * Note: Adopted from h5tools_detect_vlen_str() which only check + * vlen-string data in type. + *------------------------------------------------------------------------- + */ +htri_t +h5tools_detect_vlen_data(hid_t tid) +{ + int i = 0; + int n = 0; + htri_t has_vlen_str = FALSE; + H5T_class_t tclass = -1; + + /* detect any vlen data in type */ + if (H5Tdetect_class(tid, H5T_VLEN) == TRUE || /* VLEN-data */ + H5Tis_variable_str(tid) == TRUE) /* VLEN-string*/ + return TRUE; + + tclass = H5Tget_class(tid); + if (tclass == H5T_ARRAY) { + hid_t btid = H5Tget_super(tid); + has_vlen_str = h5tools_detect_vlen_data(btid); + H5Tclose(btid); + return has_vlen_str; + } + else if (tclass == H5T_COMPOUND) { + n = H5Tget_nmembers(tid); + for (i = 0; i < n; i++) { + hid_t mtid = H5Tget_member_type(tid, i); + has_vlen_str = h5tools_detect_vlen_data(mtid); + if (has_vlen_str == TRUE) { + H5Tclose(mtid); + return TRUE; + } + H5Tclose(mtid); + } + } + return FALSE; +} + + +/*------------------------------------------------------------------------- * Function: h5tools_detect_vlen_str * * Purpose: Recursive check for variable length string of a datatype. diff --git a/tools/lib/h5tools.h b/tools/lib/h5tools.h index 6d054b8..376f05a 100644 --- a/tools/lib/h5tools.h +++ b/tools/lib/h5tools.h @@ -553,6 +553,7 @@ H5TOOLS_DLL hid_t h5tools_get_native_type(hid_t type); H5TOOLS_DLL hid_t h5tools_get_little_endian_type(hid_t type); H5TOOLS_DLL hid_t h5tools_get_big_endian_type(hid_t type); +H5TOOLS_DLL htri_t h5tools_detect_vlen_data(hid_t tid); H5TOOLS_DLL htri_t h5tools_detect_vlen_str(hid_t tid); H5TOOLS_DLL void h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t container, -- cgit v0.12