Linux crash in __swift_instantiateConcreteTypeFromMangledName using JSONDecoder

I’m decoding the following JSON string: [{“id”: 1, “name” : “bar”}]

final class TestItem: Codable, Sendable {
    let id: Int
    let name: String
}

let decoded = try JSONDecoder().decode([TestItem].self, from: data)

A function that wraps this code is embedded in a Swift package and invoked from C++, compiled using the default cxx interop flag with

Swift version 6.2.1 (swift-6.2.1-RELEASE)
Target: aarch64-unknown-linux-gnu

On macOS, the code runs fine.

On Linux, I get a runtime crash:

thread #44, name = 'XXXXXXX', stop reason = signal SIGSEGV: address not mapped to object (fault address: 0xfffffffffffffff8)
  * frame #0: 0x0000aaaaaab8d49c XXXXXXX`TestItem.init() at <compiler-generated>:0
    frame #3: 0x0000fffff7c9c16c libswiftCore.so`dispatch thunk of Decodable.init(from:) + 16
    frame #4: 0x0000fffff6e6c000 libFoundationEssentials.so`closure #1 in JSONDecoderImpl.unwrap(_:as:for:_:) + 124
    frame #5: 0x0000fffff6e67510 libFoundationEssentials.so`JSONDecoderImpl.unwrap(_:as:for:_:) + 1220
    frame #6: 0x0000fffff6e7be64 libFoundationEssentials.so`JSONDecoderImpl.UnkeyedContainer.decode(_:) + 624
    frame #7: 0x0000fffff6e7cfa0 libFoundationEssentials.so`protocol witness for UnkeyedDecodingContainer.decode(_:) in conformance JSONDecoderImpl.UnkeyedContainer + 12
    frame #8: 0x0000fffff7a35f94 libswiftCore.so`Array<τ_0_0>.init(from:) + 284
    frame #9: 0x0000fffff7b83ef8 libswiftCore.so`Array<τ_0_0>.init(from:) + 28
    frame #10: 0x0000fffff7a36084 libswiftCore.so`protocol witness for Decodable.init(from:) in conformance <τ_0_0> [τ_0_0] + 28
    frame #11: 0x0000fffff7a35e4c libswiftCore.so`protocol witness for Decodable.init(from:) in conformance <τ_0_0> [τ_0_0] + 20
    frame #12: 0x0000fffff7c9c16c libswiftCore.so`dispatch thunk of Decodable.init(from:) + 16
    frame #13: 0x0000fffff6e6c000 libFoundationEssentials.so`closure #1 in JSONDecoderImpl.unwrap(_:as:for:_:) + 124
    frame #14: 0x0000fffff6e67510 libFoundationEssentials.so`JSONDecoderImpl.unwrap(_:as:for:_:) + 1220
    frame #15: 0x0000fffff6e8060c libFoundationEssentials.so`partial apply for closure #1 in JSONDecoder.decode(_:from:) + 140
    frame #16: 0x0000fffff6e67cb0 libFoundationEssentials.so`closure #1 in JSONDecoder._decode(_:from:) + 740
    frame #17: 0x0000fffff6e853d0 libFoundationEssentials.so`partial apply for closure #1 in JSONDecoder._decode(_:from:) + 20
    frame #18: 0x0000fffff6e67f0c libFoundationEssentials.so`closure #1 in static JSONDecoder.withUTF8Representation(of:_:) + 100
    frame #19: 0x0000fffff6e85424 libFoundationEssentials.so`partial apply for closure #1 in static JSONDecoder.withUTF8Representation(of:_:) + 20
    frame #20: 0x0000fffff6e607d0 libFoundationEssentials.so`partial apply for closure #1 in Data.withBufferView(_:) + 32
    frame #21: 0x0000fffff6e10a6c libFoundationEssentials.so`__DataStorage.withUnsafeBytes(in:apply:) + 188
    frame #22: 0x0000fffff6e15a94 libFoundationEssentials.so`Data._Representation.withUnsafeBytes(_:) + 172
    frame #23: 0x0000fffff6e1054c libFoundationEssentials.so`Data.withUnsafeBytes(_:) + 12
    frame #24: 0x0000fffff6e607a4 libFoundationEssentials.so`Data.withBufferView(_:) + 36
    frame #25: 0x0000fffff6e67e84 libFoundationEssentials.so`static JSONDecoder.withUTF8Representation(of:_:) + 208
    frame #26: 0x0000fffff6e8970c libFoundationEssentials.so`JSONDecoder._decode(_:from:) + 60
    frame #27: 0x0000fffff6e8958c libFoundationEssentials.so`JSONDecoder.decode(_:from:) + 52
XXXXXXX`TestItem.init(from:):
    0xaaaaaab8d48c <+52>: bl     0xaaaaaab34d34 ; __swift_instantiateConcreteTypeFromMangledName at <compiler-generated>
    0xaaaaaab8d490 <+56>: mov    x8, x0
    0xaaaaaab8d494 <+60>: ldur   x0, [x29, #-0x60]
    0xaaaaaab8d498 <+64>: stur   x8, [x29, #-0x58]
->  0xaaaaaab8d49c <+68>: ldur   x8, [x8, #-0x8]
    0xaaaaaab8d4a0 <+72>: stur   x8, [x29, #-0x50]
    0xaaaaaab8d4a4 <+76>: ldr    x8, [x8, #0x40]
    0xaaaaaab8d4a8 <+80>: lsr    x8, x8, #0

The stack trace looks very similar to Runtime Crash at "__swift_instantiateConcreteTypeFromMangledName" · Issue #74303 · swiftlang/swift · GitHub also with JSONDecoder. One mentioned probable cause there (running Swift 6 compiled code on a Swift 5 runtime) is not applicable for my case, I compile with Swift 6.2 and run on Swift 6.2.

Another cause mentioned there is running out of stack space. My code is very simple, the struct is simple with no enums at all and my code also fails with ulimit -s unlimited so this also seems unlikely.

Somehow however it seems __swift_instantiateConcreteTypeFromMangledName returns NULL.

Using final class vs struct makes no difference.

Any things I can try to find the cause and debug this further?

Yes, the crash refers to 0xfffffffffffffff8 location which is exactly 0 - 8, which is what the offending command doing ldur x8, [x8, #-0x8] (where x8 was previously populated with the result of __swift_instantiateConcreteTypeFromMangledName).

No idea why though.


FWIW, it works correctly for me on godbolt.

Fixed it by switching to dynamic linking. I’m guessing some symbols got stripped by the linker, causing __swift_instantiateConcreteTypeFromMangledName to not find type information. Thanks for your reply!