Essentially, the issue was operator error. Thanks to steeldriver for pointing me to the cause. Here is an explanation for anyone else who runs into this:
As steeldriver pointed out, python3 was not finding the correct shared object, but was loading one from another installation that I'd inadvertently added at some point.
In this case the error message points to the missing symbol: sqlite3_deserialize
(a function) that is needed by the shared object /usr/lib/python3.11/lib-dynload/_sqlite3.cpython-311-x86_64-linux-gnu.so
The fault does not lie with this shared object, but the fact that none of the shared objects it loads contains the symbol.
using the nm
command we can see all the symbols present in the library as well as symbols that it needs. The ones needed are marked as U
.
nm -gD /usr/lib/python3.11/lib-dynload/_sqlite3.cpython-311-x86_64-linux-gnu.so | less
If we search for deserialize we can see U sqlite3_deserialize
indicating that it needs this symbol.
Using ldd
we can command the linux loader to actually load the library, and all its dependent libraries and find which ones are actually loading:
ldd /usr/lib/python3.11/lib-dynload/_sqlite3.cpython-311-x86_64-linux-gnu.so
As steeldriver points out, it was loading /usr/local/lib/libsqlite3.so.0
which is not the correct version. Running nm
on the incorrect file shows that the required symbol is not present in this file, which is the cause of the issue.
The correct sqlite3 package in lunar is libsqlite3-0
(which is not necessarily obvious). If not sure, we can try to find the correct package from apt-cache search libsqlite3
or something similar and sift through the results.
We can see what files are installed by this package by first installing it, then running dpkg -L libsqlite3-0
. In the returned list if files we see /usr/lib/x86_64-linux-gnu/libsqlite3.so.0
which is the one that should be loaded.
So how do we ensure that the linux loader picks the correct shared object version? Ideally we should only have one version of sqlite3 so the best solution is to remove the non-standard one. Another potential solution is to point the loader to the correct path using the environment variable LD_LIBRARY_PATH
. Something like this may work export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH
(add to ~/.bashrc
for persistence). Note that putting it at the front will cause that directory to be searched first. If the problem still persists then just run ldd
again to verify what's being loaded.