4

I have a binary which can load .so shared objects to extend functionality. These extensions are coded in C++ but I want to use some pre-coded python functions so I make use of Python C API. So far so good.

Calls to Python functions work nicely, but if, in Python, I import spidev module I get the following error:

import spidev
ImportError: /usr/local/lib/python2.7/dist-packages/spidev.so: undefined symbol: _Py_ZeroStruct
Segmentation fault

If I import standard python modules (sys, os, argparse...) there's no problem.

What could be the problem?

N.B.: I know that I could use spidev directly from C++ but I wanted to reuse existing python code as much as possible.

UPDATE:

As @BrianCain and @qarma pointed out, it can be a problem related with dependencies to libpython so I include ldd outputs:

$ ldd myextension.so 
    /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0xb6f89000)
    libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xb6f5f000)
    libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0xb6f54000)
    libutil.so.1 => /lib/arm-linux-gnueabihf/libutil.so.1 (0xb6f49000)
    libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0xb6ed8000)
    libpython2.7.so.1.0 => /usr/lib/libpython2.7.so.1.0 (0xb6c47000)
    libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0xb6c1f000)
    libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6af0000)
    /lib/ld-linux-armhf.so.3 (0xb6fa2000)
    libz.so.1 => /lib/arm-linux-gnueabihf/libz.so.1 (0xb6ad2000)

$ ldd /usr/local/lib/python2.7/dist-packages/spidev.so
    /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0xb6ed3000)
    libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xb6ea9000)
    libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6d7a000)
    /lib/ld-linux-armhf.so.3 (0xb6eed000)

UPDATE2:

Output of spidev installation.

$ sudo pip install spidev
Downloading/unpacking spidev
  Downloading spidev-2.0.tar.gz
  Running setup.py egg_info for package spidev

Installing collected packages: spidev
  Running setup.py install for spidev
    building 'spidev' extension
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/src/linux/include -I/usr/include/python2.7 -c spidev_module.c -o build/temp.linux-armv6l-2.7/spidev_module.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro build/temp.linux-armv6l-2.7/spidev_module.o -o build/lib.linux-armv6l-2.7/spidev.so

Successfully installed spidev
Cleaning up...

$ ldd /usr/local/lib/python2.7/dist-packages/spidev.so
    /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0xb6f97000)
    libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xb6f6d000)
    libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6e3e000)
    /lib/ld-linux-armhf.so.3 (0xb6fb1000)

Still not depending on libpython...

Cristian Ciupitu
  • 20,270
  • 7
  • 50
  • 76
Diego Herranz
  • 2,857
  • 2
  • 19
  • 34
  • 3
    Chances are that the `libpython` that `spidev.so` was built against is not the `libpython` being used by the currently executing Python VM. – Brian Cain Apr 29 '14 at 13:31
  • please include your log of `pip install` or `python setup.py install`. Works for me on Linux x86-64 native Python-2.7.6, distutils-2.7.6, gcc-4.8.2 – Dima Tisnek Apr 30 '14 at 13:59
  • Added `pip install` log. Thanks! – Diego Herranz Apr 30 '14 at 15:26
  • Try to run the second `gcc` line with added `-lpython2.7`, and install the updated `spidev.so` on the system. – user4815162342 May 05 '14 at 12:47
  • I downloaded spidev from Pypi an built like this: `CFLAGS="-lpython2.7" python setup.py build` but the spidev.so generated still doesn't depend on `libpython`. – Diego Herranz May 05 '14 at 13:24
  • I did `pip install spidev`, and the ldd output includes libpython2.7.so.1.0. Works fine for me. – snapshoe May 11 '14 at 02:04

1 Answers1

0

I suspect your spidev.so is built against wrong version of Python or built badly.

Please run ldd on both your Python and this lib. If there's a mismatch, tough luck! If not, dig deeper.

Here's how it should work:

(test)[dima@bmg py-spidev]$ python setup.py build
(test)[dima@bmg py-spidev]$ ldd build/lib.linux-x86_64-2.7/spidev.so 
        linux-vdso.so.1 (0x00007fffbadfe000)
        libpython2.7.so.1.0 => /usr/lib/libpython2.7.so.1.0 (0x00007f42c9659000)
        libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f42c943c000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007f42c9094000)
        libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f42c8e8f000)
        libutil.so.1 => /usr/lib/libutil.so.1 (0x00007f42c8c8c000)
        libm.so.6 => /usr/lib/libm.so.6 (0x00007f42c898b000)
        /usr/lib64/ld-linux-x86-64.so.2 (0x00007f42c9c50000)
(test)[dima@bmg py-spidev]$ python setup.py install
(test)[dima@bmg py-spidev]$ python
>>> import spidev
>>> dir(spidev)
['SpiDev', '__doc__', '__file__', '__name__', '__package__']

Note that it should linked against some libpython2.x.so.y.z

Perhaps your target python (if cross-compiling) is missing python-config?

Dima Tisnek
  • 11,241
  • 4
  • 68
  • 120
  • I include `ldd` outputs in original question. It seems that `spidev.so` does not depend on `libpython`. Is that right? Thanks! – Diego Herranz Apr 30 '14 at 12:54
  • 1
    Your spidev.so is badly compiled! it should be linked against specific version of python runtime, e.g. `libpython2.7.so.1.0` – Dima Tisnek Apr 30 '14 at 13:50