bug in H5Gopen?

Here's a snippet of code that compiles with h5c++ from HDF5 release 1.8.6.

const char *name=abspath.substr(0, slash).c_str(); // = "/root"
std::cout << "H5Gopen2-: name='" << name << "'\n";
hid_t grp=H5Gopen2(file, name, H5P_DEFAULT);
std::cout << "H5Gopen2+: name='" << name << "'\n";

and here's example output from running it on a new HDF5 file.

H5Gopen2-: name='/root'
HDF5-DIAG: Error detected in HDF5 (1.8.6) thread 0:
  #000: H5G.c line 406 in H5Gopen2(): unable to open group
    major: Symbol table
    minor: Can't open object
  #001: H5G.c line 958 in H5G_open_name(): group not found
    major: Symbol table
    minor: Object not found
  #002: H5Gloc.c line 480 in H5G_loc_find(): can't find object
    major: Symbol table
    minor: Object not found
  #003: H5Gtraverse.c line 929 in H5G_traverse(): internal path traversal
failed
    major: Symbol table
    minor: Object not found
  #004: H5Gtraverse.c line 718 in H5G_traverse_real(): traversal operator
failed
    major: Symbol table
    minor: Callback failed
  #005: H5Gloc.c line 435 in H5G_loc_find_cb(): object 'root' doesn't exist
    major: Symbol table
    minor: Object not found
H5Gopen2+: name='failed'

Since the group "/root" does not exist, it is correct that there is an
error. However there were unexpected side effects; note that the name
string changed. This is seen with both H5Gopen1 and H5Gopen2 (make the
appropriate substitution in the example code above).

It looks to me that H5Gopen is modifying its "const char * name" input
parameter in case of error. Depending on the string, this produces
varying output garbage including "failed", "!", "1", and garbled portions
of the input string.

I'm guarding my code with temporary string buffers, but thought others may
be able to implement a proper fix.

Later,
Daniel

Hm, my impression here would be that it's faulty C++ code, because

"abspath.substr(0, slash)" create a temporary string object to which
the c_str() member function refers, so char*name is actually referring
to a memory which is deleted after the substr() function call. Can you
try if this gives the same result:

{
  string substr = abspath.substr(0, slash);
  const char*name = substr.c_str(); // = "/root"
  std::cout << "H5Gopen2-: name='" << name << "'\n";
  hid_t grp=H5Gopen2(file, name, H5P_DEFAULT);
  std::cout << "H5Gopen2+: name='" << name << "'\n";
}

This should keep the substring object alive and valid as long
as the char*name is used.

  Werner

···

On Wed, 25 May 2011 10:43:33 -0500, <dherring@tentpost.com> wrote:

Here's a snippet of code that compiles with h5c++ from HDF5 release 1.8.6.

const char *name=abspath.substr(0, slash).c_str(); // = "/root"
std::cout << "H5Gopen2-: name='" << name << "'\n";
hid_t grp=H5Gopen2(file, name, H5P_DEFAULT);
std::cout << "H5Gopen2+: name='" << name << "'\n";

and here's example output from running it on a new HDF5 file.

H5Gopen2-: name='/root'
HDF5-DIAG: Error detected in HDF5 (1.8.6) thread 0:
  #000: H5G.c line 406 in H5Gopen2(): unable to open group
    major: Symbol table
    minor: Can't open object
  #001: H5G.c line 958 in H5G_open_name(): group not found
    major: Symbol table
    minor: Object not found
  #002: H5Gloc.c line 480 in H5G_loc_find(): can't find object
    major: Symbol table
    minor: Object not found
  #003: H5Gtraverse.c line 929 in H5G_traverse(): internal path traversal
failed
    major: Symbol table
    minor: Object not found
  #004: H5Gtraverse.c line 718 in H5G_traverse_real(): traversal operator
failed
    major: Symbol table
    minor: Callback failed
  #005: H5Gloc.c line 435 in H5G_loc_find_cb(): object 'root' doesn't exist
    major: Symbol table
    minor: Object not found
H5Gopen2+: name='failed'

Since the group "/root" does not exist, it is correct that there is an
error. However there were unexpected side effects; note that the name
string changed. This is seen with both H5Gopen1 and H5Gopen2 (make the
appropriate substitution in the example code above).

It looks to me that H5Gopen is modifying its "const char * name" input
parameter in case of error. Depending on the string, this produces
varying output garbage including "failed", "!", "1", and garbled portions
of the input string.

I'm guarding my code with temporary string buffers, but thought others may
be able to implement a proper fix.

Later,
Daniel

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

--
___________________________________________________________________________
Dr. Werner Benger Visualization Research
Laboratory for Creative Arts and Technology (LCAT)
Center for Computation & Technology at Louisiana State University (CCT/LSU)
211 Johnston Hall, Baton Rouge, Louisiana 70803
Tel.: +1 225 578 4809 Fax.: +1 225 578-5362

Werner Benger wrote:

Hm, my impression here would be that it's faulty C++ code, because

"abspath.substr(0, slash)" create a temporary string object to which
the c_str() member function refers, so char*name is actually referring
to a memory which is deleted after the substr() function call. Can you
try if this gives the same result:

Thanks, that indeed fixed the problem. Bad user code where undefined
behavior almost appeared to work.

- Daniel