diff --git a/src/err.c b/src/err.c index 0aac372..69dd166 100644 --- a/src/err.c +++ b/src/err.c @@ -5,6 +5,7 @@ #include +#include #include "err.h" @@ -29,6 +30,7 @@ static char *messages[ERR_MAX_STACK_SIZE] = {0}; static struct error_stack_t stack = {files, funcs, lines, errors, messages, 0}; + void push_error_stack(const char *file, const char *func, int line, int err, const char *message) { if (stack.size >= ERR_MAX_STACK_SIZE) return; /* unfortunate */ int idx = stack.size; @@ -47,8 +49,35 @@ void push_error_stack(const char *file, const char *func, int line, int err, con } +herr_t h5e_walk_callback(unsigned int n, const struct H5E_error2_t *err, void *client_data) { + herr_t retval = 0; + /* only read the message for the innermost stack frame - the rest are just noise */ + if (n == 0) { + char message[ERR_MAX_MESSAGE_LENGTH] = {0}; + sprintf(message, "%.*s", ERR_MAX_MESSAGE_LENGTH - 1, err->desc); + push_error_stack(err->file_name, err->func_name, err->line, -1, message); + } else { + push_error_stack(err->file_name, err->func_name, err->line, -1, ""); + } + return retval; +} + + +int h5e_error_callback(hid_t stack_id, void *client_data) { + int retval = 0; + herr_t err = 0; + err = H5Ewalk2(stack_id, H5E_WALK_UPWARD, &h5e_walk_callback, client_data); + if (err < 0) { + ERROR_JUMP(err, done, "Error walking HDF5 Error stack"); + } +done: + return retval; +} + + void reset_error_stack() { stack.size = 0; + H5Eclear2(H5E_DEFAULT); /* almost certainly unnecessary */ } @@ -67,3 +96,14 @@ void dump_error_stack(FILE *out) { } } } + + +int init_h5_error_handling() { + int retval = 0; + hid_t err = 0; + if ((err = H5Eset_auto2(H5E_DEFAULT, &h5e_error_callback, NULL)) < 0) { + ERROR_JUMP(err, done, "Error configuring HDF5 error callback"); + } +done: + return retval; +} diff --git a/src/err.h b/src/err.h index cba6713..c30f6f2 100644 --- a/src/err.h +++ b/src/err.h @@ -48,4 +48,6 @@ void dump_error_stack(FILE *out); void reset_error_stack(); +int init_h5_error_handling(); + #endif /* NXS_XDS_ERR_H */ diff --git a/src/plugin.c b/src/plugin.c index 5d94ea9..0b9b97f 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -54,6 +54,11 @@ void plugin_open( int *error_flag) { int retval = 0; *error_flag = 0; + + if (init_h5_error_handling() < 0) { + ERROR_JUMP(-2, done, "Failed to configure HDF5 error handling"); + } + fill_info_array(info); file_id = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT); if (file_id < 0) { diff --git a/src/test.c b/src/test.c index daa3589..93d6d32 100644 --- a/src/test.c +++ b/src/test.c @@ -47,6 +47,9 @@ int main(int argc, char **argv) { int *data = NULL; reset_error_stack(); + if (init_h5_error_handling() < 0) { + ERROR_JUMP(-1, done, ""); + } if (parse_args(argc, argv, &test_file, &frame_idx) < 0) { ERROR_JUMP(-1, done, "Failure parsing arguments");