wbolster / plyvel

Plyvel, a fast and feature-rich Python interface to LevelDB
https://plyvel.readthedocs.io/
Other
530 stars 75 forks source link

plyvel import leads to ImportError with missing symbol reference despite libleveldb being installed #57

Closed lehmann-4178656ch closed 7 years ago

lehmann-4178656ch commented 7 years ago

Hello,

I am trying to use plyvel 0.9 on a Ubuntu 16.04.2 LTS machine with Python 3.5.2-2ubuntu0~16.04.1. I expected it to work, but I get an ImportError.

I did the following:

  1. I installed leveldb with apt install libleveldb-dev which installed the following packages: libleveldb-dev:amd64 1.18-5 libleveldb1v5:amd64 1.18-5

  2. I installed plyvel with pip3 install plyvel:

    $ sudo pip3 install plyvel
    Collecting plyvel
    Installing collected packages: plyvel
    Successfully installed plyvel-0.9
    You are using pip version 8.1.1, however version 9.0.1 is available.
    You should consider upgrading via the 'pip install --upgrade pip' command.
  3. I tried to import plyvel:

    $ python3 -c 'import plyvel'
    Traceback (most recent call last):
    File "<string>", line 1, in <module>
    File "/usr/local/lib/python3.5/dist-packages/plyvel/__init__.py", line 6, in <module>
    from ._plyvel import (  # noqa
    ImportError: /usr/local/lib/python3.5/dist-packages/plyvel/_plyvel.cpython-35m-x86_64-linux-gnu.so: undefined symbol: _ZN7leveldb9DestroyDBERKSsRKNS_7OptionsE

The packages mentioned in https://plyvel.readthedocs.io/en/latest/installation.html#build-and-install-plyvel are installed and the shared objects of libleveldb can be found using locate:

$ locate leveldb
/usr/lib/x86_64-linux-gnu/libleveldb.a
/usr/lib/x86_64-linux-gnu/libleveldb.so
/usr/lib/x86_64-linux-gnu/libleveldb.so.1
/usr/lib/x86_64-linux-gnu/libleveldb.so.1.18

And the plyvel extension library appears to link against it correctly:

$ readelf -d /usr/local/lib/python3.5/dist-packages/plyvel/_plyvel.cpython-35m-x86_64-linux-gnu.so

Dynamic section at offset 0x27cc0 contains 27 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libleveldb.so.1]
...

However, curiously I found in the libleveldb.so.1.18 the searched symbol only with a slightly different variation:

$ objdump -T libleveldb.so.1.18 | grep leveldb9Destroy
0000000000016c40 g    DF .text  0000000000000a94  Base        _ZN7leveldb9DestroyDBERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_7OptionsE

This looks like the search thing, but with extra __cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS inside. Any help will be appreciated.

wbolster commented 7 years ago

hmmm, i am by no means an expert here, but can you try ldd on the _plyvel.so? copying from your report, it would be

ldd /usr/local/lib/python3.5/dist-packages/plyvel/_plyvel.cpython-35m-x86_64-linux-gnu.so
lehmann-4178656ch commented 7 years ago

Yes that is the correct path on the system:

$ sudo updatedb
$ locate _plyvel
/usr/local/lib/python3.5/dist-packages/plyvel/_plyvel.cpython-35m-x86_64-linux-gnu.so
$ ldd /usr/local/lib/python3.5/dist-packages/plyvel/_plyvel.cpython-35m-x86_64-linux-gnu.so
    linux-vdso.so.1 =>  (0x00007fff2152e000)
    libleveldb.so.1 => /usr/lib/x86_64-linux-gnu/libleveldb.so.1 (0x00007f82a7d0c000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f82a798a000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f82a7773000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f82a73a9000)
    libsnappy.so.1 => /usr/lib/x86_64-linux-gnu/libsnappy.so.1 (0x00007f82a71a1000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f82a6e97000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f82a6c7a000)
    /lib64/ld-linux-x86-64.so.2 (0x000055f8867be000)
$ ls -alh /usr/lib/x86_64-linux-gnu/ | grep level
-rw-r--r--  1 root root 798K Nov  19  2015 libleveldb.a
lrwxrwxrwx  1 root root   18 Nov  19  2015 libleveldb.so -> libleveldb.so.1.18
lrwxrwxrwx  1 root root   18 Nov  19  2015 libleveldb.so.1 -> libleveldb.so.1.18
-rw-r--r--  1 root root 359K Nov  19  2015 libleveldb.so.1.18

I'd guess from the output, that the libleveldb.so.1.18 is correctly found.

wbolster commented 7 years ago

is it compiled against the currently installed version (and dev headers?). perhaps pip is caching previously built incompatible wheels? (~/.cache/pip i think.)

wbolster commented 7 years ago

also maybe different compilers used? (just thinking out loud.)

wbolster commented 7 years ago

also look at #27

lehmann-4178656ch commented 7 years ago

The compilers are an interesting point, but I would guess that the Ubuntu 16.04 packages are built with the same which is available in the repository. Also the libraries look equivalent looking at the libleveldb.so

ldd /usr/lib/x86_64-linux-gnu/libleveldb.so.1.18 
    linux-vdso.so.1 =>  (0x00007ffe741be000)
    libsnappy.so.1 => /usr/lib/x86_64-linux-gnu/libsnappy.so.1 (0x00007f7e7d587000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f7e7d205000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f7e7cefb000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f7e7cce5000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f7e7cac8000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7e7c6fd000)
    /lib64/ld-linux-x86-64.so.2 (0x0000560f49155000)

To ensure no cache is used i now rebuild plyvel using

$ sudo pip3 install -U plyvel --no-cache-dir --no-deps --force-reinstall

this helped! Thanks alot, but it's strange that the cache directory ~/.cache/pip did not exist before this command but now it does. But that shouldn't be searched in plyvel but rather in the python-pip3 ubuntu package. Thanks again!

wbolster commented 7 years ago

so are you saying it works now? :)

wbolster commented 7 years ago

ping @lehmann-4178656ch, can this issue be closed? if so, maybe you can share what exactly solved the problem for you? thanks.

lehmann-4178656ch commented 7 years ago

Sorry for the delay, I was on a trip this weekend not near any computer. I don't know what exactly fixed it, as the pip-cache was not existing at first, maybe that was the problem but running

$ sudo pip3 install -U plyvel --no-cache-dir --no-deps --force-reinstall

fixed it.

wbolster commented 7 years ago

awesome. perhaps there was a stray cache for the root user?

also, was your first compilation attempt without the required packages installed? maybe that could explain it...

lehmann-4178656ch commented 7 years ago

The first attempts were made on a different machine, this is the so-to-speak staging system, thus the pitfall of not having packages installed was avoided. Stray cache could be a possibility, but all interaction was done through sudo and the last iteration created the cache inside my home-dir. It's a strange thing but it's now working.

wbolster commented 7 years ago

ok weird.

as a last note i feel obliged to say that sudo pip is really an anti-pattern that can completely break your system. ;)