diff options
author | Neil Fortner <nfortne2@hdfgroup.org> | 2010-09-15 15:33:03 (GMT) |
---|---|---|
committer | Neil Fortner <nfortne2@hdfgroup.org> | 2010-09-15 15:33:03 (GMT) |
commit | bf8d33a34b756a926f146a5507f7ecfcee3d3579 (patch) | |
tree | 441e2cb99d72612b0290a257112c537954428fb9 | |
parent | f0939c320dd3ad761aba4edfdbd63c4b2829f20c (diff) | |
download | hdf5-bf8d33a34b756a926f146a5507f7ecfcee3d3579.zip hdf5-bf8d33a34b756a926f146a5507f7ecfcee3d3579.tar.gz hdf5-bf8d33a34b756a926f146a5507f7ecfcee3d3579.tar.bz2 |
[svn-r19387] Purpose: Fix assertion failure caused by fractal heap header file pointer
Description:
The fractal heap header structure keeps a pointer to the file associated with
it. However, it is possible for that file pointer to be closed while the
header is still in cache (through the shared file pointer). Previously, the
header's file pointer was not updated and subsequently pointed to an invalid
file structure. Modified fractal heap code to update the file pointer every
time the header is accessed.
Tested: jam, linew, amani (h5committest)
-rw-r--r-- | release_docs/RELEASE.txt | 3 | ||||
-rw-r--r-- | src/H5HF.c | 3 | ||||
-rw-r--r-- | src/H5HFhdr.c | 3 | ||||
-rw-r--r-- | test/fheap.c | 142 |
4 files changed, 147 insertions, 4 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 0a84a88..2182c42 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -121,6 +121,9 @@ Bug Fixes since HDF5-1.8.5 Library ------- + - Fixed a bug that could occur when getting information for a new-style + group that was previously opened through a file handle that was later + closed. (NAF - 2010/09/15) - Added define check in H5public.h if stdint.h is supported by the C++ compiler. This define is only available on Windows with VS2010 and using CMake to build the library. (ADB - 2010/09/13 - Bug 1938) @@ -856,9 +856,6 @@ HDfprintf(stderr, "%s; After iterator reset fh->hdr->rc = %Zu\n", FUNC, fh->hdr- if(NULL == (hdr = H5HF_hdr_protect(fh->f, dxpl_id, heap_addr, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header") - /* Set the shared heap header's file context for this operation */ - hdr->f = fh->f; - /* Delete heap, starting with header (unprotects header) */ if(H5HF_hdr_delete(hdr, dxpl_id) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "unable to delete fractal heap") diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index e678d74..684c171 100644 --- a/src/H5HFhdr.c +++ b/src/H5HFhdr.c @@ -552,6 +552,9 @@ H5HF_hdr_protect(H5F_t *f, hid_t dxpl_id, haddr_t addr, H5AC_protect_t rw) /* Set the header's address */ hdr->heap_addr = addr; + /* Update header's file pointer */ + hdr->f = f; + /* Set the return value */ ret_value = hdr; diff --git a/test/fheap.c b/test/fheap.c index ade1ed4..4f1466e 100644 --- a/test/fheap.c +++ b/test/fheap.c @@ -2828,7 +2828,7 @@ test_size(hid_t fapl, H5HF_create_t *cparam) FAIL_STACK_ERROR /* Re-open the heap */ - if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR /* Check the heap's size */ @@ -2872,6 +2872,145 @@ error: return(1); } /* test_size() */ + +/*------------------------------------------------------------------------- + * Function: test_reopen_hdr + * + * Purpose: Test opening a header through one file handle, closing + * that file handle, then reopening through a different file + * handle that was open the whole time. The header should + * stay in cache between the two opens. + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Neil Fortner + * Tuesday, September 14, 2010 + * + *------------------------------------------------------------------------- + */ +static unsigned +test_reopen_hdr(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file1 = -1; /* File ID */ + hid_t file2 = -2; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[FHEAP_FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + hsize_t heap_size; /* Total size of heap on disk */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file1 = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file1))) + FAIL_STACK_ERROR + + /* Ignore metadata tags in the file's cache */ + if (H5AC_ignore_tags(f) < 0) + FAIL_STACK_ERROR + + /* Display testing message */ + TESTING("reopening header through different file") + + + /* Create absolute heap */ + if(NULL == (fh = H5HF_create(f, dxpl, cparam))) + FAIL_STACK_ERROR + + /* Get heap's address */ + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + TEST_ERROR + + /* Insert an object */ + if(add_obj(fh, dxpl, (size_t)0, (size_t)10, NULL, NULL) < 0) + TEST_ERROR + + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; + + /* Close the file */ + if(H5Fclose(file1) < 0) + FAIL_STACK_ERROR + + + /* Re-open the file */ + if((file1 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Re-open the file again */ + if((file2 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object (file1) */ + if(NULL == (f = (H5F_t *)H5I_object(file1))) + FAIL_STACK_ERROR + + /* Ignore metadata tags in the file's cache */ + if (H5AC_ignore_tags(f) < 0) + FAIL_STACK_ERROR + + /* Open the heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + + /* Close the heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; + + /* Close the file (file1) */ + if(H5Fclose(file1) < 0) + FAIL_STACK_ERROR + + + /* Get a pointer to the internal file object (file2) */ + if(NULL == (f = (H5F_t *)H5I_object(file2))) + FAIL_STACK_ERROR + + /* Reopen the heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + + /* Check the heap's size */ + heap_size = 0; + if(H5HF_size(fh, dxpl, &heap_size) < 0) + FAIL_STACK_ERROR + + /* Close the fractal heap */ + if(H5HF_close(fh, H5P_DATASET_XFER_DEFAULT) < 0) + FAIL_STACK_ERROR + + + /* Close the file (file2) */ + if(H5Fclose(file2) < 0) + FAIL_STACK_ERROR + + /* All tests passed */ + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file1); + H5Fclose(file2); + } H5E_END_TRY; + return(1); +} /* test_reopen_hdr() */ + #ifndef QAK2 /*------------------------------------------------------------------------- @@ -15808,6 +15947,7 @@ curr_test = FHEAP_TEST_NORMAL; nerrors += test_id_limits(fapl, &small_cparam); nerrors += test_filtered_create(fapl, &small_cparam); nerrors += test_size(fapl, &small_cparam); + nerrors += test_reopen_hdr(fapl, &small_cparam); #else /* QAK */ HDfprintf(stderr, "Uncomment tests!\n"); #endif /* QAK */ |