Exception when running Lava Lamp module in Ubuntu 22.04.1 LTS (Pi 4B)
Closed this issue · 3 comments
Hello!
I've now got the Lumicube running after building with Maven using a new flashed Ubuntu Server 22.04.1 LTS image. I had some trouble with install.py
(for another issue when I have time!) and so had to run locally instead, meaning I had to install a bunch of dependencies manually. I'm hoping that this is the cause of the issue.
The issue exists only with the Lava Lamp example. I can see the following exception in the log coming from Python:
Traceback (most recent call last):
File "main", line 15, in paint_cube
File "main", line 6, in lava_colour
File "/tmp/foundry-script-context-8120301071552718362/foundry_api/standard_library.py", line 371, in noise4
self._ensure_ffi_connected()
File "/tmp/foundry-script-context-8120301071552718362/foundry_api/standard_library.py", line 360, in _ensure_ffi_connected
self._connect_ffi()
File "/tmp/foundry-script-context-8120301071552718362/foundry_api/standard_library.py", line 341, in _connect_ffi
lib = ffi.dlopen(_script_context + '/noise/open-simplex-noise-' + variant + '.so')
File "/home/ubuntu/.local/lib/python3.10/site-packages/cffi/api.py", line 150, in dlopen
lib, function_cache = _make_ffi_library(self, name, flags)
File "/home/ubuntu/.local/lib/python3.10/site-packages/cffi/api.py", line 832, in _make_ffi_library
backendlib = _load_backend_lib(backend, libname, flags)
File "/home/ubuntu/.local/lib/python3.10/site-packages/cffi/api.py", line 827, in _load_backend_lib
raise OSError(msg)
OSError: cannot load library '/tmp/foundry-script-context-8120301071552718362/noise/open-simplex-noise-x64.so': /tmp/foundry-script-context-8120301071552718362/noise/open-simplex-noise-x64.so: cannot open shared object file: No such file or directory. Additionally, ctypes.util.find_library() did not manage to locate a library called '/tmp/foundry-script-context-8120301071552718362/noise/open-simplex-noise-x64.so'
However I can see that the file does exist and is a 64 bit dynamically linked shared object file compiled for x86-64, but ldd
is having problems showing the contents (maybe this is because it's statically linked and the file
output saying "dynamically linked" is incorrect?):
ubuntu@ubuntu:~/repositories/lumicube-daemon$ file /tmp/foundry-script-context-8120301071552718362/noise/open-simplex-noise-*.so
/tmp/foundry-script-context-8120301071552718362/noise/open-simplex-noise-arm.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=0ccf640c06db594955478859d4ef416aa908bc49, not stripped
/tmp/foundry-script-context-8120301071552718362/noise/open-simplex-noise-x64.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=e39ad4b807f46196fc01cc5636700ac54bb9d98e, not stripped
ubuntu@ubuntu:~/repositories/lumicube-daemon$ ldd /tmp/foundry-script-context-8120301071552718362/noise/open-simplex-noise-*.so
/tmp/foundry-script-context-8120301071552718362/noise/open-simplex-noise-arm.so:
not a dynamic executable
/tmp/foundry-script-context-8120301071552718362/noise/open-simplex-noise-x64.so:
not a dynamic executable
Either way, I definitely can't load it:
ubuntu@ubuntu:~/repositories/lumicube-daemon$ python3
Python 3.10.6 (main, Aug 10 2022, 11:40:04) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from os.path import exists
>>> exists('/tmp/foundry-script-context-8120301071552718362/noise/open-simplex-noise-x64.so')
True
>>> from cffi import FFI
>>> ffi = FFI()
>>> ffi.dlopen('/tmp/foundry-script-context-8120301071552718362/noise/open-simplex-noise-x64.so')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/ubuntu/.local/lib/python3.10/site-packages/cffi/api.py", line 150, in dlopen
lib, function_cache = _make_ffi_library(self, name, flags)
File "/home/ubuntu/.local/lib/python3.10/site-packages/cffi/api.py", line 832, in _make_ffi_library
backendlib = _load_backend_lib(backend, libname, flags)
File "/home/ubuntu/.local/lib/python3.10/site-packages/cffi/api.py", line 827, in _load_backend_lib
raise OSError(msg)
OSError: cannot load library '/tmp/foundry-script-context-8120301071552718362/noise/open-simplex-noise-x64.so': /tmp/foundry-script-context-8120301071552718362/noise/open-simplex-noise-x64.so: cannot open shared object file: No such file or directory. Additionally, ctypes.util.find_library() did not manage to locate a library called '/tmp/foundry-script-context-8120301071552718362/noise/open-simplex-noise-x64.so'
I've attached the readelf
output if that's useful:
ubuntu@ubuntu:~/repositories/lumicube-daemon$ readelf -l /tmp/foundry-script-context-8120301071552718362/noise/open-simplex-noise-x64.so
Elf file type is DYN (Shared object file)
Entry point 0x1070
There are 9 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000638 0x0000000000000638 R 0x1000
LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000
0x0000000000005cb1 0x0000000000005cb1 R E 0x1000
LOAD 0x0000000000007000 0x0000000000007000 0x0000000000007000
0x000000000000046c 0x000000000000046c R 0x1000
LOAD 0x0000000000007e10 0x0000000000008e10 0x0000000000008e10
0x0000000000000228 0x0000000000000230 RW 0x1000
DYNAMIC 0x0000000000007e20 0x0000000000008e20 0x0000000000008e20
0x00000000000001c0 0x00000000000001c0 RW 0x8
NOTE 0x0000000000000238 0x0000000000000238 0x0000000000000238
0x0000000000000024 0x0000000000000024 R 0x4
GNU_EH_FRAME 0x00000000000071f0 0x00000000000071f0 0x00000000000071f0
0x0000000000000064 0x0000000000000064 R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x0000000000007e10 0x0000000000008e10 0x0000000000008e10
0x00000000000001f0 0x00000000000001f0 R 0x1
Section to Segment mapping:
Segment Sections...
00 .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt
01 .init .plt .plt.got .text .fini
02 .rodata .eh_frame_hdr .eh_frame
03 .init_array .fini_array .dynamic .got .got.plt .data .bss
04 .dynamic
05 .note.gnu.build-id
06 .eh_frame_hdr
07
08 .init_array .fini_array .dynamic .got
Any help would be appreciated!
Looks like https://github.com/smcameron/open-simplex-noise-in-c is being used - would it be simpler to use a Python implementation? E.g. https://pypi.org/project/opensimplex/ is MIT licensed so should be fine to include.
Hi @mfoo - we were originally using https://pypi.org/project/opensimplex/ - but it's so slow on the Raspberry Pi, it causes animations to look quite jerky! I presume you're running a 64-bit Ubuntu distribution on your Raspberry Pi (which we don't officially support, just the 32-bit Raspberry Pi OS desktop version). That said you should be able to get our software on Ubuntu (at least it's Debian based, so not too dissimilar). Basically you're going to need to build an aarch64 version of the .so file (as the x64 library you found is for amd64) and get Python to try linking to your own version.
To build the library for aarch64. first apt install docker qemu qemu-user-static binfmt-support
and then run the following script:
cat > Dockerfile <<\EOF
FROM debian:buster-20210111
RUN apt update && apt install -y git build-essential
RUN git clone https://github.com/smcameron/open-simplex-noise-in-c /root/OpenSimplex
WORKDIR /root/OpenSimplex
RUN gcc -O2 -fPIC -c -o open-simplex-noise.o open-simplex-noise.c
RUN gcc -O2 -shared -o open-simplex-noise.so open-simplex-noise.o
EOF
docker image rm debian:buster-20210111 # Work around Docker not supporting several platform-specific versions of the same image.
docker build --platform linux/arm64/v8 -t build-simplex-aarch64 .
docker run --rm --entrypoint cat build-simplex-aarch64 /root/OpenSimplex/open-simplex-noise.so > open-simplex-noise-aarch64.so
chmod +x open-simplex-noise-aarch64.so
This script successfully generated a file when I just ran it, but I haven't actually tested that it's possible to link to. You can package the resulting .so next to the other versions in the daemon. Finally _platform_variant
in standard_library.py needs to be modified to detect and return 'aarch64'
so the correct .so is linked. Hope that's some help!
Worked first time, thanks!
I'll have a think about this, maybe there's some improvement we can make here that doesn't involve including multiple .so
binaries in the repo!