I've got a project which is primarily written in Rust that runs on both Linux and macOS, and I want to use a library that's written in Swift. I've written a Swift @_cdecl
function that I can call from Rust using extern "C"
.
On macOS, this works fine. However, when running on Linux, it segfaults inside libswiftCore.
Passing data from Rust to Swift works fine, the segfault occurs within the Swift runtime in ValueWitness::initializeWithCopy
, seemingly whenever any generic specialization is called.
The beginning of the backtrace from the crash:
* thread #2, name = 'tests::test_hig', stop reason = signal SIGSEGV: invalid address (fault address: 0xfffffffffffffff8)
* frame #0: 0x0000fffff7541a78 libswiftCore.so`swift::metadataimpl::ValueWitnesses<swift::metadataimpl::OpaqueExistentialBox<0u> >::initializeWithCopy(swift::OpaqueValue*, swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*) + 28
frame #1: 0x0000fffff74e7158 libswiftCore.so`outlined init with copy of Any + 44
frame #2: 0x0000fffff739e198 libswiftCore.so`generic specialization <Swift._Stdout> of Swift._debugPrint<τ_0_0 where τ_0_0: Swift.TextOutputStream>(_: Swift.Array<Any>, separator: Swift.String, terminator: Swift.String, to: inout τ_0_0) -> () + 128
frame #3: 0x0000aaaaaaae5640 splash_rs-53f1675cf4435848`highlight(codePtr=0xaaaaaab5d7ce, codeLen=3, htmlLenPtr=0xfffff4944fe0) at highlight_swift.swift:17:5
And exactly where the crash is:
* thread #2, name = 'tests::test_hig', stop reason = signal SIGSEGV: invalid address (fault address: 0xfffffffffffffff8)
frame #0: 0x0000fffff7541a78 libswiftCore.so`swift::metadataimpl::ValueWitnesses<swift::metadataimpl::OpaqueExistentialBox<0u> >::initializeWithCopy(swift::OpaqueValue*, swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*) + 28
libswiftCore.so`swift::metadataimpl::ValueWitnesses<swift::metadataimpl::OpaqueExistentialBox<0u> >::initializeWithCopy:
-> 0xfffff7541a78 <+28>: ldur x8, [x2, #-0x8]
0xfffff7541a7c <+32>: ldrb w9, [x8, #0x52]
0xfffff7541a80 <+36>: tbnz w9, #0x1, 0xfffff7541a94 ; <+56>
0xfffff7541a84 <+40>: ldr x8, [x8, #0x10]
My code can be found here: https://git.shadowfacts.net/shadowfacts/splash-rs, and this is readily reproducible on Ubuntu 20.04 (with both Rust and Swift installed) by running cargo test
.
So, my question is: Do I need to do anything to initialize the Swift runtime from my Rust program, before I call into Swift, or is this something that should work automatically?