Handling DLL version mismatches

Hi all,
I like HDF5 a lot, and I've been developing on LabVIEW bindings for HDF5
(h5labview) for some time now. However, I was recently caused some
headaches by the way version mismatch is handled by HFD5.

To summarise, when using certain constants (e.g. H5F_ACC_RDWR) the function
H5check_version (H5.c) gets called automatically, which compares the
version of the library loaded into memory to the version the code was
compiled against. If they differ at all, debug info is dumped to stderr and
abort() is called.

This might make sense on Linux, but is very annoying on Windows for the
following reasons:
- stderr usually goes nowhere for GUI applications, the debug message is
lost and no explanation is provided

- abort() kills the entire parent process. In the case of a managed
environment like LabVIEW, the entire runtime engine gets killed- including
the editor, and whatever other *independent* programs are running in it
simultaneously. This is especially bad because LabVIEW is often used to
control hardware, and the termination is *part-way through execution*
(usually when H5Fopen is first called), potentially causing undefined
hardware states. This eventuality is potentially unique to LabVIEW, but is
obviously a concern for me.

- The DLL has its own environment variables defined at load time,
so HDF5_DISABLE_VERSION_CHECK cannot be set locally. It can only be set
with a registry modification, making it global and potentially affecting
other installed programs.

- It goes against the "DLL philosophy" (if such a thing existed) that
libraries should be modular, shareable and upgradeable. This makes the "DLL
Hell" problem so much worse because ALL different versions of hdf5dll.dll
(now hdf5.dll) have the same name yet are mutually incompatible by design!
No two applications can share a DLL (unless they can somehow magically
guarantee version number) and the DLL can't be upgraded, which defeats the
whole point of dynamic linking!

From the user's perspective, they download some code, and as soon as they

run it the runtime is promptly killed and they have no idea why.

I understand that it is desirable to protect users from inadvertently using
incompatible versions of the library, but it seems crazy to me that one
change in the release number should break everything - particularly if you
know it's compatible because you've tested it! As an application writer I
should be allowed to implement my own check on the version and decide a
course of action, not have one forced on me (an unexplained abort() at
that!).

I propose either or both of the following:
- #ifdefs be used in H5check_version so abort is not called on Windows, and
that Win32API's MessageBox be used to present debug information instead of
stderr
- allow the version check to be disabled with an explicit command, so that
the application writer can take responsibility for compatibility problems

Actually I did think of a hack to achieve the second point just now, but
I'd rather not have to use it.

Thoughts?

Cheers,
Martijn

Hi Martijn,

I understand that it is desirable to protect users from inadvertently using
incompatible versions of the library, but it seems crazy to me that one
change in the release number should break everything - particularly if you
know it's compatible because you've tested it! As an application writer I
should be allowed to implement my own check on the version and decide a
course of action, not have one forced on me (an unexplained abort() at
that!).

With h5py we had a similar issue; PyTables and h5py both ship with a
copy of the HDF5 dll and depending on which one was imported first
certain functions would break. I don't recall getting an abort(), it
was more that the Python loader complained about unresolved symbols.

The solution was to rename the DLL we distributed with h5py, so that
the Python process actually had two independent versions of HDF5
loaded. If you distribute HDF5 with your application, this is one
possible solution, although I'm the first to agree it's a hack. Keep
in mind it has to be done within cmake (renaming the output file isn't
enough).

By the way, thanks for h5labview. We use it in our lab (University of
Colorado dust accelerator) and it's working great.

Andrew

Hi Andrew, All,
I was really, really hoping to avoid packaging the DLLs, but now I'm aware
of the behaviour I can point users to specific releases. Since HDF5
releases are biannual, it's not a huge problem, I was simply blind-sided by
it, and the explanatory message getting flushed didn't help. It seems that
everyone ends up compiling and redistributing their own DLLs anyway; but at
least with LabVIEW I don't envisage any other libraries requiring alternate
versions! Glad to hear the library is getting some use elsewhere.

For posterity, here's the terrible hack to add to initialisation that
prevents abort() being called:

unsigned maj, min, rel;
H5get_libversion( &maj,&min,&rel );
// custom version check here

if ((maj!=H5_VERS_MAJOR)||(min!=H5_VERS_MINOR)) MessageBox(NULL,"HDF5

version mismatch! Please install v"H5_PACKAGE_VERSION,"Error",MB_OK);

H5check_version( maj,min,rel );

Since H5check_version uses a static variable to prevent re-checking on
every call, only the first call to H5check_version matters. Making this
call forces the first check to succeed by feeding it back its own version
number. Although later H5CHECK checks would fail, they don't get evaluated
so it's not a problem!

I acknowledge that this probably goes against the point of H5CHECK in the
first place, but explicitly requiring a hack like this implies the author
knows they're taking responsibility for the compatibility checking - e.g.
checking major and minor version numbers above.

Not sure if it'll be useful to anyone else since full redistribution seems
the usual way, but there it is in case.

Cheers,
Martijn

ยทยทยท

On 7 June 2013 02:06, Andrew Collette <andrew.collette@gmail.com> wrote:

Hi Martijn,

> I understand that it is desirable to protect users from inadvertently
using
> incompatible versions of the library, but it seems crazy to me that one
> change in the release number should break everything - particularly if
you
> know it's compatible because you've tested it! As an application writer I
> should be allowed to implement my own check on the version and decide a
> course of action, not have one forced on me (an unexplained abort() at
> that!).

With h5py we had a similar issue; PyTables and h5py both ship with a
copy of the HDF5 dll and depending on which one was imported first
certain functions would break. I don't recall getting an abort(), it
was more that the Python loader complained about unresolved symbols.

The solution was to rename the DLL we distributed with h5py, so that
the Python process actually had two independent versions of HDF5
loaded. If you distribute HDF5 with your application, this is one
possible solution, although I'm the first to agree it's a hack. Keep
in mind it has to be done within cmake (renaming the output file isn't
enough).

By the way, thanks for h5labview. We use it in our lab (University of
Colorado dust accelerator) and it's working great.

Andrew

_______________________________________________
Hdf-forum is for HDF software users discussion.
Hdf-forum@lists.hdfgroup.org
http://lists.hdfgroup.org/mailman/listinfo/hdf-forum_lists.hdfgroup.org