Weird linker bug with Swift 4.2


(Pierpaolo Frasa) #1

We have a server-side application currently running on Swift 4.1.2. When trying to upgrade to Swift 4.2, we succeeded in making the necessary changes for it to compile and pass the tests on macOS. Unfortunately, it turns out that there is a very weird behaviour in our docker container (that I can reproduce on a VM, so it must be unrelated to anything specific to our container) causing the tests to not be able to run.

I tried creating a smaller repository to recreate the issue, but failed, and I cannot share the source. However here is what I found out happens:

When running swift test, the executable .build/x86_64-unknown-linux/debug/ProjectName.xctest is run. This immediately fails with:

error while loading shared libraries: libmemplugin.so: cannot open shared object file: No such file or directory

After some digging, I find out that this library comes from omr-agentcore which is in turn used by SwiftMetrics. I run find and it tells me that the required library file is in the same place as the binary, i.e. in .build/x86_64-unknown-linux/debug.

So I rebuild with Swift 4.1.2 and compare the situations. With Swift 4.1.2, the libraries end up in the same location. However (and at this point I'm really moving outside of my area of knowledge), looking at the two binaries (with readelf) reveals that in 4.1.2 the runpath is set like this:
Library runpath: [/home/vagrant/swift41/usr/lib/swift/linux:$ORIGIN],
whereas with Swift 4.2, I end up with:
Library runpath: [/home/vagrant/swift41/usr/lib/swift/linux:\$ORIGIN]

Notice the added backslash before the $. I suspect that this is the reason why the lookup fails (it seems that $ORIGIN is a special variable in ELF files that refers to the path of the current file, so this makes sense).

Unfortunately, by just creating a mini-project with SwiftMetrics, I can't reproduce the issue—the runpath seems to be generated fine.


In the meantime, I can "fix" my issue by explicitly setting the LD_LIBRARY_PATH to the build folder that contains the .so files in my Dockerfile. But that took me quite a while to figure out.

(I would create a bug on bugs.swift.org, but I feel that I don't understand what's happening here well enough yet to create a concise bug description.)


(Ankit Aggarwal) #2

Hi, this sounds like a bug for the package manager. Do you mind filing a JIRA? You can just reference this post in the bug.


(Ankit Aggarwal) #3

Also, It would be great if you can post an example package that reproduces this issue.


(Pierpaolo Frasa) #4

Unfortunately, I can't reliably reproduce this in other repositories. Here is the bug report.