Fixed HDFFV-10684

Description:
    The test for HDFFV-10588 has revealed a bug in H5Ewalk.
    H5Ewalk did not stop midway even when the call back function returns
    H5_ITER_STOP. This is because a condition is missing from the for
    loops in H5E__walk causing the callback functions unable to stop until
    all the errors in the stack are iterated. Quincey advised on the final
    fix.  In this fix, "status" is switched to "ret_value" and HGOTO_ERROR
    to HERROR, and the for loops won't continue when "ret_value" is not 0.
Platforms tested:
    Linux/64 (jelly)
    Linux/64 (platypus)
    Darwin (osx1010test)
This commit is contained in:
Binh-Minh Ribler
2019-01-20 16:49:46 -06:00
parent 43bd93c4f5
commit d584b233a5
2 changed files with 19 additions and 21 deletions

View File

@@ -1484,7 +1484,7 @@ done:
*
* Purpose: Prints the error stack in some default way. This is just a
* convenience function for H5Ewalk() with a function that
* prints error messages. Users are encouraged to write there
* prints error messages. Users are encouraged to write their
* own more specific error handlers.
*
* Return: SUCCEED/FAIL
@@ -1567,7 +1567,7 @@ H5Ewalk2(hid_t err_stack, H5E_direction_t direction, H5E_walk2_t stack_func, voi
op.vers = 2;
op.u.func2 = stack_func;
if(H5E__walk(estack, direction, &op, client_data) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTLIST, FAIL, "can't walk error stack")
HERROR(H5E_ERROR, H5E_CANTLIST, "can't walk error stack");
done:
FUNC_LEAVE_API(ret_value)

View File

@@ -422,7 +422,7 @@ done:
* Purpose: Private function to print the error stack in some default
* way. This is just a convenience function for H5Ewalk() and
* H5Ewalk2() with a function that prints error messages.
* Users are encouraged to write there own more specific error
* Users are encouraged to write their own more specific error
* handlers.
*
* Return: SUCCEED/FAIL
@@ -511,10 +511,9 @@ H5E__walk(const H5E_t *estack, H5E_direction_t direction, const H5E_walk_op_t *o
void *client_data)
{
int i; /* Local index variable */
herr_t status; /* Status from callback function */
herr_t ret_value = SUCCEED; /* Return value */
herr_t ret_value = H5_ITER_CONT; /* Return value */
FUNC_ENTER_PACKAGE
FUNC_ENTER_PACKAGE_NOERR
/* Sanity check */
HDassert(estack);
@@ -530,9 +529,9 @@ H5E__walk(const H5E_t *estack, H5E_direction_t direction, const H5E_walk_op_t *o
if(op->u.func1) {
H5E_error1_t old_err;
status = SUCCEED;
ret_value = SUCCEED;
if(H5E_WALK_UPWARD == direction) {
for(i = 0; i < (int)estack->nused && status >= 0; i++) {
for(i = 0; i < (int)estack->nused && ret_value == H5_ITER_CONT; i++) {
/* Point to each error record on the stack and pass it to callback function.*/
old_err.maj_num = estack->slot[i].maj_num;
old_err.min_num = estack->slot[i].min_num;
@@ -541,12 +540,12 @@ H5E__walk(const H5E_t *estack, H5E_direction_t direction, const H5E_walk_op_t *o
old_err.desc = estack->slot[i].desc;
old_err.line = estack->slot[i].line;
status = (op->u.func1)(i, &old_err, client_data);
ret_value = (op->u.func1)(i, &old_err, client_data);
} /* end for */
} /* end if */
else {
H5_CHECK_OVERFLOW(estack->nused - 1, size_t, int);
for(i = (int)(estack->nused - 1); i >= 0 && status >= 0; i--) {
for(i = (int)(estack->nused - 1); i >= 0 && ret_value == H5_ITER_CONT; i--) {
/* Point to each error record on the stack and pass it to callback function.*/
old_err.maj_num = estack->slot[i].maj_num;
old_err.min_num = estack->slot[i].min_num;
@@ -555,12 +554,12 @@ H5E__walk(const H5E_t *estack, H5E_direction_t direction, const H5E_walk_op_t *o
old_err.desc = estack->slot[i].desc;
old_err.line = estack->slot[i].line;
status = (op->u.func1)((int)(estack->nused - (size_t)(i + 1)), &old_err, client_data);
ret_value = (op->u.func1)((int)(estack->nused - (size_t)(i + 1)), &old_err, client_data);
} /* end for */
} /* end else */
if(status < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTLIST, FAIL, "can't walk error stack")
if(ret_value < 0)
HERROR(H5E_ERROR, H5E_CANTLIST, "can't walk error stack");
} /* end if */
#else /* H5_NO_DEPRECATED_SYMBOLS */
HDassert(0 && "version 1 error stack walk without deprecated symbols!");
@@ -569,23 +568,22 @@ H5E__walk(const H5E_t *estack, H5E_direction_t direction, const H5E_walk_op_t *o
else {
HDassert(op->vers == 2);
if(op->u.func2) {
status = SUCCEED;
ret_value = SUCCEED;
if(H5E_WALK_UPWARD == direction) {
for(i = 0; i < (int)estack->nused && status >= 0; i++)
status = (op->u.func2)((unsigned)i, estack->slot + i, client_data);
for(i = 0; i < (int)estack->nused && ret_value == H5_ITER_CONT; i++)
ret_value = (op->u.func2)((unsigned)i, estack->slot + i, client_data);
} /* end if */
else {
H5_CHECK_OVERFLOW(estack->nused - 1, size_t, int);
for(i = (int)(estack->nused - 1); i >= 0 && status >= 0; i--)
status = (op->u.func2)((unsigned)(estack->nused - (size_t)(i + 1)), estack->slot + i, client_data);
for(i = (int)(estack->nused - 1); i >= 0 && ret_value == H5_ITER_CONT; i--)
ret_value = (op->u.func2)((unsigned)(estack->nused - (size_t)(i + 1)), estack->slot + i, client_data);
} /* end else */
if(status < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTLIST, FAIL, "can't walk error stack")
if(ret_value < 0)
HERROR(H5E_ERROR, H5E_CANTLIST, "can't walk error stack");
} /* end if */
} /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5E__walk() */