LD_LIBRARY_PATH in classic snap

I’d like to know what replaced the LD_LIBRARY_PATH in python classic snaps (like snapcraft).
Is it this patch?
patch $SNAPCRAFT_PART_INSTALL/usr/lib/python3.5/ctypes/__init__.py $SNAPCRAFT_STAGE/ctypes_init.diff
in https://github.com/snapcore/snapcraft/blob/master/snap/snapcraft.yaml#L53?
Also I noticed that python3 is no longer built. Is it pulled from the repo (it’s not a stage-pacakge)
My snap needs python3-gi, and that I cannot pull via pip

Classic snaps use RPath instead of LD_LIBRARY_PATH in order to not pollute any children process’ own library search paths.

Python3 is included in that snap by parts using the python plugin.

I maintain ubuntu-make and its snap.
It’s classic because I need to call apt.
It was working, but now it stopped with the last snapcraft updates.
the snap can be found in the store, and the yaml file is: https://github.com/ubuntu/ubuntu-make/blob/master/snap/snapcraft.yaml
Could you look at it to see if I’m doing something wrong?

Also, is there documentation on how we’re supposed to set RPATH?
I’m installing everything I need in the snap, like libreadline, but the snap fails:

ImportError: libreadline.so.6: cannot open shared object file: No such file or directory

So I suppose I need to add the lib paths to the snap…

That patch is for the snapcraft code base itself. cpython’s ctypes only searches for libraries to dlopen from the ldcache and needless to say, libraries inside the snap are not there, so we added some simple logic to cover this. It shouldn’t affect anything other than snapcraft itself.

The fact that python3 is no longer built is because since the arrival of the elf patching feature we are no longer required to do so.

I am sorry I cannot help with python-gi as I am not familiar with that package.

You could add LD_LIBRARY_PATH or patch the included python ctypes you have like we did. Just take into account that using LD_LIBRARY_PATH will taint anything you call out, that depends on how much you depend on calling out to binaries on the host and how the libraries you include may affect them.

So in theory I could simply copy the patch from snapcraft…changing the SNAP_NAME?
I’ll try and rebuild with that and removing all the env changes

Not completely verbatim, you’d need to change things like SNAP_NAME.
Also, we are only searching for things in $SNAP/usr/lib/<arch-triplet> as that is all we need.

Yes, I changed the snap_name
Unfortunately now it fails with a segmentation fault in the middle of executing.
EDIT: Does snapcraft not need libs like readline, libc, …?
ubuntu-make and snapcraft shold not be that different

I tried running with --gdb, and i get this:

Thread 6 “python3” received signal SIGSEGV, Segmentation fault.
[Switching to LWP 26584]
0x00007f6f1d10973c in ?? () from /snap/core/current/lib64/ld-linux-x86-64.so.2

Is it possible to use the ctypes patch to add more than one lib path?
To try and replicate:

export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$SNAP/lib:$SNAP/usr/lib:$SNAP/lib/$ARCH:$SNAP/usr/lib/$ARCH"
I’m trying to fix the segmentation fault…

I get a segmentation fault in 18.04, not in 16.04.
I tried snap run --gdb, and this is the result:

I can’t figure out how to properly replace the old wrapper, making the snap work on different releases.
Who can I ask for help with this?

@lucyllewy @sergiusens
I found something that could point to the issue…
I patched python3 as in the snapcraft snap (fixing the needed dirs)
but I still get this error in strace.
I guess the issue is that it’s looking for the girepository from the host system. Could this be an incompatibility?
If so, how can I fix it?

9638 open("/snap/ubuntu-make/x13/usr/lib/python3/dist-packages/gi/pycache/_error.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = 4
9638 open("/snap/ubuntu-make/x13/usr/lib/python3/dist-packages/gi/repository/pycache/init.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = 4
9638 open("/snap/ubuntu-make/x13/usr/lib/python3/dist-packages/gi/pycache/importer.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = 4
9638 open("/snap/ubuntu-make/x13/usr/lib/python3/dist-packages/gi/pycache/module.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = 4
9638 open("/snap/ubuntu-make/x13/usr/lib/python3/dist-packages/gi/pycache/types.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = 4
9638 open("/snap/ubuntu-make/x13/usr/lib/python3/dist-packages/gi/pycache/_constants.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = 4
9638 open("/snap/ubuntu-make/x13/usr/lib/python3/dist-packages/gi/pycache/docstring.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = 4
9638 open("/snap/ubuntu-make/x13/usr/lib/python3/dist-packages/gi/pycache/_propertyhelper.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = 4
9638 open("/snap/ubuntu-make/x13/usr/lib/python3/dist-packages/gi/pycache/_signalhelper.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = 4
9638 open("/snap/ubuntu-make/x13/usr/lib/python3/dist-packages/gi/overrides/pycache/init.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = 4
9638 open("/snap/ubuntu-make/x13/usr/lib/python3/dist-packages/gi/repository", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 4
9638 open("/usr/lib/x86_64-linux-gnu/girepository-1.0", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 4
9638 open("/usr/lib/x86_64-linux-gnu/girepository-1.0/GLib-2.0.typelib", O_RDONLY) = 5
9638 open("/usr/lib/girepository-1.0", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 4
9638 open("/usr/lib/x86_64-linux-gnu/girepository-1.0", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 4
9638 open("/usr/lib/x86_64-linux-gnu/girepository-1.0/GLib-2.0.typelib", O_RDONLY) = 5
9638 open("/usr/lib/girepository-1.0", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 4

That’s not the issue…
at the moment the only thing I can check are the last lines of the strace:

24746 open("/snap/ubuntu-make/x3/usr/lib/python3/dist-packages/pycache/gnupg.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
24746 open("/snap/ubuntu-make/x3/usr/lib/python3/dist-packages/gnupg.py", O_RDONLY|O_CLOEXEC) = 33
24746 open("/snap/ubuntu-make/x3/lib/python3.5/site-packages/umake/frameworks/pycache/web.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
24746 open("/snap/ubuntu-make/x3/lib/python3.5/site-packages/umake/frameworks/web.py", O_RDONLY|O_CLOEXEC) = 33
24746 open("/home/galileo/.local/share/umake/go/go-lang", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = -1 ENOENT (No such file or directory)
24766 open("/snap/ubuntu-make/x3/usr/lib/python3.5/pycache/netrc.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
24766 open("/snap/ubuntu-make/x3/usr/lib/python3.5/netrc.py", O_RDONLY|O_CLOEXEC) = 33
24766 open("/snap/ubuntu-make/x3/usr/lib/python3.5/pycache/shlex.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
24766 open("/snap/ubuntu-make/x3/usr/lib/python3.5/shlex.py", O_RDONLY|O_CLOEXEC) = 33
24766 open("/snap/ubuntu-make/x3/usr/lib/python3.5/encodings/pycache/idna.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
24766 open("/snap/ubuntu-make/x3/usr/lib/python3.5/encodings/idna.py", O_RDONLY|O_CLOEXEC) = 33
24766 open("/snap/ubuntu-make/x3/usr/lib/python3.5/pycache/stringprep.cpython-35.pyc", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
24766 open("/snap/ubuntu-make/x3/usr/lib/python3.5/stringprep.py", O_RDONLY|O_CLOEXEC) = 33
24766 open("/etc/host.conf", O_RDONLY|O_CLOEXEC) = 33
24766 open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 33
24766 — SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0xb0} —
24756 +++ killed by SIGSEGV (core dumped) +++
24766 +++ killed by SIGSEGV (core dumped) +++
24746 +++ killed by SIGSEGV (core dumped) +++

I took a look at your snap layout and found a couple of interesting things.
For the type of application you are working on, in https://github.com/ubuntu/ubuntu-make/blob/master/snap/umake-wrapper,

  • the use of LD_LIBRARY_PATH will cause segfaults when shelling out.
  • if using the python plugin, PYTHONHOME and PYTHONUSERBASE need not be set, for the same reason, if anything you shell out to happens to be a python application (like the case of bzr), you will run into problems (segfaults and missing python package issues).
  • $SNAP/usr/bin holds more that the python runtime, exporting that will certainly cause segfaults. If anything in code you own needs to re-exec itself, it would be best handled in the code.

I removed the LD_LIBRARY_PATH in a branch (https://github.com/ubuntu/ubuntu-make/tree/patch_snap)
Since I’m using python3-gi, do I need to set GI_TYPELIB_PATH?
I noticed that the snap is looking for those only in the host system without…

I am sorry to say that I do not know about the internals (or externals) of python-gi.

But do you know if the girepository package is something I should include in the snap?
Is there a reason for the system to not look for it in the snap in the first place?

If you can explain to me how girepository and/or python-gi work I could lend a helping hand.
The reason for it to not look into the snap in the first place is implementation specific to the libraries used. Maybe someone more familiar with the glib/gtk stack can help.

As far as I can tell libgirepository manages the actual bindings from other languages to gtk…
I don’t know more…
The only reason to look at the system ones is in case there’s no change in the bindings for newer versions of gtk I guess…
@didrocks might know more