DataSpaceIException exception thrown during initialisation (before main())
- Dominant language
- C
- Stars
- 988
- Forks
- 355
- Avg merge
- 4d 2h
- Merged PRs (30d)
- 12
Description
I have a problem with our [STIR library](https://github.com/UCL/STIR) that uses HDF5, where on our university cluster, `H5::DataSpaceIException` exception gets thrown before anything happens in our own code. Running in gdb gives
```
$ gdb src/utilities/list_projdata_info
(gdb) break main
Breakpoint 1 at 0x48b7c0
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /SAN/inm/tools/build_cluster/SIRF-SuperBuild/Release/builds/STIR/build/src/utilities/list_projdata_info
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
terminate called after throwing an instance of 'H5::DataSpaceIException'
Program received signal SIGABRT, Aborted.
0x00007ffff60f7387 in raise () from /lib64/libc.so.6
(gdb) info stack
#0 0x00007ffff60f7387 in raise () from /lib64/libc.so.6
#1 0x00007ffff60f8a78 in abort () from /lib64/libc.so.6
#2 0x00007ffff6705a95 in __gnu_cxx::__verbose_terminate_handler() () from /lib64/libstdc++.so.6
#3 0x00007ffff6703a06 in ?? () from /lib64/libstdc++.so.6
#4 0x00007ffff6703a33 in std::terminate() () from /lib64/libstdc++.so.6
#5 0x00007ffff6703c53 in __cxa_throw () from /lib64/libstdc++.so.6
#6 0x0000000000458892 in H5::DataSpace::getConstant() [clone .cold] ()
#7 0x00000000004905af in _GLOBAL__sub_I_H5DataSpace.cpp ()
#8 0x00000000010b1d0d in __libc_csu_init ()
#9 0x00007ffff60e34e5 in __libc_start_main () from /lib64/libc.so.6
#10 0x0000000000493750 in _start ()
```
I found https://stackoverflow.com/questions/51622933/library-conflict-when-linking-in-linux-but-not-osx where there are comments this could be due to the "static initialisation order fiasco".
Reviewing the code, I see
https://github.com/HDFGroup/hdf5/blob/5f9d12601c828c8d99e1c019f1192d68e8ee5471/c%2B%2B/src/H5DataSpace.cpp#L31
https://github.com/HDFGroup/hdf5/blob/5f9d12601c828c8d99e1c019f1192d68e8ee5471/c++/src/H5DataSpace.cpp#L42-L60
https://github.com/HDFGroup/hdf5/blob/5f9d12601c828c8d99e1c019f1192d68e8ee5471/c%2B%2B/src/H5DataSpace.cpp#L75
This seems to rely on the compiler initialising `ALL_ = 0` before initialising `ALL`, but I guess this is not guaranteed.
It seems safer (and simpler) to rely on a static local variable as in
```c++
DataSpace *
DataSpace::getConstant()
{
static DataSpace ALL_ (H5S_ALL);
return (&ALL_);
}
```
I'm not sure if this is entirely safe, as `DataSpace::ALL` is still initialised by the compiler at init time, but as long as `ALL` is only used *after* init, it could be fine. (The alternative seems to be to make `ALL` into a function, but that would break a lot of code).
Of course, this same paradigm for `ALL` is used in many HDF5 classes, so it'd need changing there as well.
PS: I have no idea about the `H5dontAtexit_called` code, so just left it out in my suggestion, but that might be a bad idea.
PS: it seems that `getConstant()` could just as well return a reference, avoiding some extra pointer stuff. Then this is getting close to using a singleton.
PS: I'm linking to `libhdf5_cpp.so`, not the static library.
PS: I'm not a C++ expert, and the literature on global variables is very large. Surely my suggestion could be improved, but it might be better than the current code.
Contributor guide
Assessment
This issue has not been assessed yet.