Search code examples
c++clinuxg++openbabel

C++ program compiles on two different machines. Shared library works properly on one. On the other, class-methods return NULL


I'm trying to write some programs using the openbabel libraries, one of which is a simple program to extract data from an sdf file. But one of the functions I have FormatFromExt is not working. The function call returns NULL no matter what input parameters I pass it.

OpenBabel::OBFormat *inputFormat = conv.FormatFromExt(argv[1]);
// This method fails, returns NULL ^^
if (!inputFormat || !conv.SetInFormat(inputFormat)) {
  char buf[256];
  sprintf(buf, "Could not find input format for file: %s", inputFormat);
  cerr << buf << endl;
  exit(0);
}

Other methods for this class, OBConversion, also return NULL such as SetInfFormat, FindFormat and Read.

I've verified that argv[1] indeed holds the input file's path and that the file has a valid extension for the openbabel libraries. I'm also including all necessary header files. On one machine, this code works perfectly. On the other the methods fail. The program compiles perfectly on both. What would cause something like this to happen?

The openbabel libraries I'm using are shared object files.


Solution

  • Okay, so this appears to be a misconfiguration. Basically, it seems to be looking for .so files, and doesn't find any on the remote machine.

    So let's look at the two traces, starting from where they diverge. It's not hard to find, since it's basically at the end of the failed trace. First, let's look at the one that works:

    openat(AT_FDCWD, "/usr/local/lib/openbabel/2.3.2", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 5
    brk(0x1199000)                          = 0x1199000
    getdents(5, /* 112 entries */, 32768)   = 4200
    getdents(5, /* 0 entries */, 32768)     = 0
    close(5)                                = 0
    futex(0x7f7fbacf90b0, FUTEX_WAKE_PRIVATE, 2147483647) = 0
    open("/usr/local/lib/openbabel/2.3.2/castepformat.so", O_RDONLY|O_CLOEXEC) = 5
    read(5, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340.\0\0\0\0\0\0"..., 832) = 832
    fstat(5, {st_mode=S_IFREG|0644, st_size=521866, ...}) = 0
    mmap(NULL, 2126352, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 5, 0) = 0x7f7fba3db000
    mprotect(0x7f7fba3e2000, 2093056, PROT_NONE) = 0
    mmap(0x7f7fba5e1000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 5, 0x6000) = 0x7f7fba5e1000
    close(5)                                = 0
    mprotect(0x7f7fba5e1000, 4096, PROT_READ) = 0
    open("/usr/local/lib/openbabel/2.3.2/xedformat.so", O_RDONLY|O_CLOEXEC) = 5
    read(5, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260'\0\0\0\0\0\0"..., 832) = 832
    fstat(5, {st_mode=S_IFREG|0644, st_size=432606, ...}) = 0
    mmap(NULL, 2118032, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 5, 0) = 0x7f7fba1d5000
    mprotect(0x7f7fba1da000, 2093056, PROT_NONE) = 0
    mmap(0x7f7fba3d9000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 5, 0x4000) = 0x7f7fba3d9000
    close(5)                                = 0
    mprotect(0x7f7fba3d9000, 4096, PROT_READ) = 0
    open("/usr/local/lib/openbabel/2.3.2/PQSformat.so", O_RDONLY|O_CLOEXEC) = 5
    

    It opens the directory /usr/local/lib/openbabel/2.3.2, then reads all the entries in it. There are 4200 bytes worth of entries. It then sequentially loads in a bunch of .so files (shared libraries). These are presumably what it found in /usr/local/lib/openbabel/2.3.2.

    Okay, now lets look at the one that failed:

    open("/tools/cluster/6.2/openbabel/2.3.2/lib/openbabel", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 5
    fcntl(5, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)
    brk(0x1dd6000)                          = 0x1dd6000
    getdents(5, /* 3 entries */, 32768)     = 80
    getdents(5, /* 0 entries */, 32768)     = 0
    brk(0x1dce000)                          = 0x1dce000
    close(5)                                = 0
    write(2, "Could not find input format for "..., 76Could not find input format for file: files/Compound_014725001_014750000.sdf) = 76
    

    It opens instead /tools/cluster/6.2/openbabel/2.3.2/lib/openbabel. It then reads only 80 bytes worth of entries, presumably because that directory is empty or near empty. It then immediately prints the error message.

    So appears that the configuration is pointing to the wrong directory, or that the directory never got populated with all the .so files. Note that it found Compound_014725001_014750000.sdf fine in both cases. If you look a few lines above from where I start to quote, you can see the syscalls for that open.