From 23c7adeca8de60ecd79742cdd16e26802d47d16c Mon Sep 17 00:00:00 2001 From: Peter Cao Date: Fri, 19 Aug 2011 12:00:14 -0500 Subject: [svn-r21265] h5repack: added macro to handle failure in H5Dread/write when memory allocation failed inside the library --- release_docs/RELEASE.txt | 2 ++ tools/h5repack/h5repack_copy.c | 48 ++++++++++++++++++++++++++++++++---------- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 02285ae..8b4028d 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -285,6 +285,8 @@ New Features unlimited dims to contiguous. (PC -- 2011/07/15) - h5diff: "--delta" option considers two NaN of the same type are different, which is wrong based on http://www.hdfgroup.org/HDF5/doc/RM/Tools.html#Tools-Diff. (PC -- 2011/07/15) + - h5repack: added macro to handle failure in H5Dread/write when memory allocation failed + inside the library. (PC -- 2011/08/19) High-Level APIs: diff --git a/tools/h5repack/h5repack_copy.c b/tools/h5repack/h5repack_copy.c index 0e9d1dd..c40b7c2 100644 --- a/tools/h5repack/h5repack_copy.c +++ b/tools/h5repack/h5repack_copy.c @@ -31,8 +31,27 @@ * macros *------------------------------------------------------------------------- */ -#define USERBLOCK_XFER_SIZE 512 /* size of buffer/# of bytes to xfer at a time when copying userblock */ +/* size of buffer/# of bytes to xfer at a time when copying userblock */ +#define USERBLOCK_XFER_SIZE 512 + +/* check H5Dread()/H5Dwrite() error, e.g. memory allocation error inside the library. */ +#define CHECK_H5DRW_ERROR(_fun, _did, _mtid, _msid, _fsid, _pid, _buf) { \ + H5E_BEGIN_TRY { \ + if(_fun(_did, _mtid, _msid, _fsid, _pid, _buf) < 0) { \ + int _err_num = 0; \ + char *_msg = NULL; \ + H5Ewalk2(H5E_DEFAULT, H5E_WALK_DOWNWARD, walk_error_callback, &_err_num); \ + _msg = H5Eget_major(_err_num); \ + if (_msg) { \ + error_msg("%s %s -- %s\n", #_fun, "failed", _msg); \ + free(_msg); \ + } \ + goto error; \ + } \ + } H5E_END_TRY; \ +} + /*------------------------------------------------------------------------- * local functions *------------------------------------------------------------------------- @@ -43,6 +62,16 @@ static int copy_user_block(const char *infile, const char *outfile, hsize_t si #if defined (H5REPACK_DEBUG_USER_BLOCK) static void print_user_block(const char *filename, hid_t fid); #endif +static herr_t walk_error_callback(unsigned n, const H5E_error2_t *err_desc, void *udata); + +/* get the major number from the error stack. */ +static herr_t walk_error_callback(UNUSED unsigned n, const H5E_error2_t *err_desc, void *udata) +{ + if (err_desc) + *((int *)udata) = err_desc->maj_num; + + return 0; +} /*------------------------------------------------------------------------- * Function: copy_objects @@ -847,11 +876,10 @@ int do_copy_objects(hid_t fidin, buf = HDmalloc(need); if(buf != NULL) { - if(H5Dread(dset_in, wtype_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) - goto error; - if(H5Dwrite(dset_out, wtype_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) - goto error; - + /* read/write: use the macro to check error, e.g. memory allocation error inside the library. */ + CHECK_H5DRW_ERROR(H5Dread, dset_in, wtype_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf); + CHECK_H5DRW_ERROR(H5Dwrite, dset_out, wtype_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf); + /* Check if we have VL data in the dataset's * datatype that must be reclaimed */ if(TRUE == H5Tdetect_class(wtype_id, H5T_VLEN)) @@ -930,11 +958,9 @@ int do_copy_objects(hid_t fidin, hs_nelmts = 1; } /* rank */ - /* read/write */ - if (H5Dread(dset_in, wtype_id, sm_space, f_space_id, H5P_DEFAULT, sm_buf) < 0) - goto error; - if (H5Dwrite(dset_out, wtype_id, sm_space, f_space_id, H5P_DEFAULT, sm_buf) < 0) - goto error; + /* read/write: use the macro to check error, e.g. memory allocation error inside the library. */ + CHECK_H5DRW_ERROR(H5Dread, dset_in, wtype_id, sm_space, f_space_id, H5P_DEFAULT, sm_buf); + CHECK_H5DRW_ERROR(H5Dwrite, dset_out, wtype_id, sm_space, f_space_id, H5P_DEFAULT, sm_buf); /* reclaim any VL memory, if necessary */ if(vl_data) -- cgit v0.12