Skip to content

Bug in hdf5open.c::get_quantize_info() #2674

@uweschulzweida

Description

@uweschulzweida

I get the following error messages since netCDF-c version 4.9.0:

   ...
  #000: H5A.c line 545 in H5Aopen_by_name(): can't open attribute
  #001: H5VLcallback.c line 1128 in H5VL_attr_open(): attribute open failed
  #002: H5VLcallback.c line 1095 in H5VL__attr_open(): attribute open failed
  #003: H5VLnative_attr.c line 132 in H5VL__native_attr_open(): can't open attribute
  #004: H5Aint.c line 559 in H5A__open_by_name(): unable to load attribute info from object header
  #005: H5Oattribute.c line 508 in H5O__attr_open_by_name(): can't locate attribute: '_QuantizeBitGroomNumberOfSignificantDigits'
   …
  #005: H5Oattribute.c line 508 in H5O__attr_open_by_name(): can't locate attribute: ‚_QuantizeGranularBitRoundNumberOfSignificantDigits'
  ...
  #005: H5Oattribute.c line 508 in H5O__attr_open_by_name(): can't locate attribute: '_QuantizeBitRoundNumberOfSignificantBits'

I think in routine hdf5open.c::get_quantize_info() the corresponding calls to H5Aexists() are missing.
I have added the following lines:

attr_exists = H5Aexists(datasetid, NC_QUANTIZE_BITGROOM_ATT_NAME);
attr_exists = H5Aexists(datasetid, NC_QUANTIZE_GRANULARBR_ATT_NAME);
attr_exists = H5Aexists(datasetid, NC_QUANTIZE_BITROUND_ATT_NAME);

With these calls I don't get any error messages anymore.

The problem occurs when opening NetCDF4 files in a multi-threaded environment when calling the routine nc_inq_var().
In the following C++ example, 2 files are opened in parallel and both threads are locked with a unique_lock:

#include "netcdf.h"
#include <cstdio>
#include <cstdlib>
#include <thread>
#include <mutex>

static std::mutex openMutex;

static void nce(int istat)
{
  if (istat != NC_NOERR)
    {
      fprintf(stderr, "%s\n", nc_strerror(istat));
      exit(-1);
    }
}

static int open_file(const char *filename)
{
  std::unique_lock<std::mutex> lockedMutex(openMutex);

  int ncid;
  nce(nc_open(filename, NC_NOWRITE, &ncid));

  int ndims, nvars, ngatts, unlimdimid;
  nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid);
  for (int varid = 0; varid < nvars; ++varid)
    {
      nc_type xtype;
      int nvdims, nvatts, dimids[9];
      nc_inq_var(ncid, varid, NULL, &xtype, &nvdims, dimids, &nvatts);
    }

  return ncid;
}

static void close_file(int ncid)
{
  nce(nc_close(ncid));
}

static void read_file(const char *filename)
{
  int ncid = open_file(filename);
  close_file(ncid);
}

int main(void)
{
  std::thread t1(read_file, "ifile1.nc");
  std::thread t2(read_file, "ifile2.nc");

  t1.join();
  t2.join();

  return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions