Hello all!
For context, this is all running either in a CentOS 7.4 container or a Rocky 9.2 container, both hosted by Rocky 9.2.
We primarily compile Swift code as dynamic libraries with executable test targets with CMake. This has largely worked well. But we have an issue with a 3rd party application that has an unrelated libFoundation.so in the LD_LIBRARY_PATH
. When this application is in the same environment as the Swift libraries, the Swift libraries try to load Swift symbols from the 3rd party libFoundation and can't find them. The solution we've come to is statically linking Foundation with the Swift code.
The trouble is, while I've been able to get the dynamic libraries compiling and not dynamically linking Foundation, the programs segfault when they run.
I can confirm with ldd
that the binaries link the expected libraries:
$ ldd lib/libStaticLinking.so
linux-vdso.so.1 (0x00007ffcc99e9000)
[...]/libpng16.so (0x00007fb059e5a000)
[...]/freetype2/objs/.libs/libfreetype.so (0x00007fb059ba0000)
libm.so.6 => /lib64/libm.so.6 (0x00007fb059ab5000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fb059800000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fb059a9a000)
libc.so.6 => /lib64/libc.so.6 (0x00007fb059400000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb05a65d000)
libz.so.1 => /lib64/libz.so.1 (0x00007fb059a7e000)
libbz2.so.1 => /lib64/libbz2.so.1 (0x00007fb059a6b000)
$ ldd tests/StaticLinkingTests
linux-vdso.so.1 (0x00007ffcc11f7000)
[...]/lib/libpng16.so (0x00007f678922c000)
[...]/freetype2/objs/.libs/libfreetype.so (0x00007f6788f72000)
libStaticLinking.so => /home/users/jonathanp/StaticLinkingTest/build/install/libStaticLinking.so (0x00007f67889a2000)
libswiftSwiftOnoneSupport.so => [...]/libswiftSwiftOnoneSupport.so (0x00007f678895e000)
libswiftCore.so => [...]/libswiftCore.so (0x00007f6788296000)
libswift_Concurrency.so => [...]/libswift_Concurrency.so (0x00007f67881fe000)
libswift_StringProcessing.so => [...]/libswift_StringProcessing.so (0x00007f6788122000)
libswift_RegexParser.so =>[...]/libswift_RegexParser.so (0x00007f678800e000)
libswiftGlibc.so => [...]/libswiftGlibc.so (0x00007f6787ffa000)
libBlocksRuntime.so => [...]/libBlocksRuntime.so (0x00007f6787ff6000)
libdispatch.so => [...]/libdispatch.so (0x00007f6787f94000)
libswiftDispatch.so => [...]/libswiftDispatch.so (0x00007f6787f67000)
libFoundation.so => [...]/libFoundation.so (0x00007f678792c000)
libFoundationEssentials.so => [...]/libFoundationEssentials.so (0x00007f678736c000)
libFoundationInternationalization.so => [...]/libFoundationInternationalization.so (0x00007f6787180000)
libXCTest.so =>[...]/libXCTest.so (0x00007f6787127000)
libm.so.6 => /lib64/libm.so.6 (0x00007f678703a000)
libc.so.6 => /lib64/libc.so.6 (0x00007f6786e00000)
libz.so.1 => /lib64/libz.so.1 (0x00007f6787020000)
libbz2.so.1 => /lib64/libbz2.so.1 (0x00007f678700d000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f6786a00000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f6786de5000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6789466000)
lib_FoundationICU.so => [...]/lib_FoundationICU.so (0x00007f6784544000)
libswiftSynchronization.so => [...]/libswiftSynchronization.so (0x00007f6786dd2000)
This is an example backtrace from LLDB:
Test Suite 'All tests' started at 2025-04-29 14:33:33.316
Test Suite 'install.xctest' started at 2025-04-29 14:33:33.317
Test Suite 'StaticLinkingTests' started at 2025-04-29 14:33:33.317
Test Case 'StaticLinkingTests.testLibrary' started at 2025-04-29 14:33:33.317
Process 1064117 stopped
* thread #1, name = 'StaticLinkingTe', stop reason = signal SIGSEGV: address not mapped to object (fault address: 0x0)
frame #0: 0x00007ffff72d83c9 libswiftCore.so`swift::TargetMetadata<swift::InProcess>::getGenericArgs() const + 9
libswiftCore.so`swift::TargetMetadata<swift::InProcess>::getGenericArgs:
-> 0x7ffff72d83c9 <+9>: movq (%rdi), %rcx
0x7ffff72d83cc <+12>: xorl %eax, %eax
0x7ffff72d83ce <+14>: cmpq $0x800, %rcx ; imm = 0x800
0x7ffff72d83d5 <+21>: cmovael %eax, %ecx
Target 0: (StaticLinkingTests) stopped.
The test targets are never run in an environment with the problematic 3rd party application, so what I'm trying to set up is:
- Swift dynamic library, statically linking Foundation.
- Swift executable, dynamically linking the Swift dynamic library, Foundation, and XCTest.
I've set up a repro project here: GitHub - JonathanPenner3D/StaticLinkingTest
I'd love any pointers or help with getting this working, or alternatively another solution to avoiding the name clash between the two libFoundation libraries. We don't compile the 3rd party application from source so we can't do something like have it use rpath
instead of LD_LIBRARY_PATH
for finding its libFoundation.
Out of an abundance of caution with my security-conscious employer I've replaced any non-generic file paths with [...]