Segmentation fault (core dumped) when executing swift package on ubuntu 20.04 (5.5 arm)

Hi guys,

I've been trying to run this simple swift package on a raspberry pi 4 running Ubuntu 20.04.
The compiling works without problems, but when running the executable I always run into Segmentation fault (core dumped).

When looking deeper into this with lldb, I get:

Process 3067 stopped
* thread #1, name = 'TestWebService', stop reason = signal SIGSEGV: invalid address (fault address: 0x5f03c02a1f03f0)
    frame #0: 0x0000aaaaaad02f4c TestWebService`SyntaxTreeVisitor.formHandlerIndexPathForCurrentNode() [inlined] generic specialization <Swift.Int> of Swift.Array._getCount() -> Swift.Int at <compiler-generated>:0 [opt]
Target 0: (TestWebService) stopped.
Stacktrace
* thread #1, name = 'TestWebService', stop reason = signal SIGSEGV: invalid address (fault address: 0x5f03c02a1f03f0)
  * frame #0: 0x0000aaaaaad02f4c TestWebService`SyntaxTreeVisitor.formHandlerIndexPathForCurrentNode() [inlined] generic specialization <Swift.Int> of Swift.Array._getCount() -> Swift.Int at <compiler-generated>:0 [opt]
    frame #1: 0x0000aaaaaad02f4c TestWebService`SyntaxTreeVisitor.formHandlerIndexPathForCurrentNode() [inlined] generic specialization <Swift.Int> of Swift.Array.count.getter : Swift.Int at <compiler-generated>:0 [opt]
    frame #2: 0x0000aaaaaad02f4c TestWebService`SyntaxTreeVisitor.formHandlerIndexPathForCurrentNode() [inlined] generic specialization <Swift.Int> of protocol witness for Swift.Collection.count.getter : Swift.Int in conformance Swift.Array<τ_0_0> : Swift.Collection in Swift at <compiler-generated>:0 [opt]
    frame #3: 0x0000aaaaaad02f4c TestWebService`SyntaxTreeVisitor.formHandlerIndexPathForCurrentNode() [inlined] generic specialization <Swift.Array<Swift.Int>, Swift.String> of Swift.Collection.map<τ_0_0>((τ_0_0.Element) throws -> τ_1_0) throws -> Swift.Array<τ_1_0> at <compiler-generated>:0 [opt]
    frame #4: 0x0000aaaaaad02f4c TestWebService`SyntaxTreeVisitor.formHandlerIndexPathForCurrentNode(self=0x0000fffff7de6290) at SyntaxTreeVisitor.swift:124:14 [opt]
    frame #5: 0x0000aaaaaad02c54 TestWebService`SyntaxTreeVisitor.visit<H>(handler=, self=0x0000fffff7de6290) at SyntaxTreeVisitor.swift:94:61 [opt]
    frame #6: 0x0000aaaaaac2aaf4 TestWebService`HandlerVisitorHelperImpl.callAsFunction<H>(value=<unavailable>, self=<unavailable>) at Component.swift:101:17 [opt]
    frame #7: 0x0000fffff7c63d24 libswiftCore.so`Swift.withUnsafePointer<τ_0_0, τ_0_1>(to: τ_0_0, _: (Swift.UnsafePointer<τ_0_0>) throws -> τ_0_1) throws -> τ_0_1 + 20
    frame #8: 0x0000aaaaaad3dbcc TestWebService`closure #1 in AssociatedTypeRequirementsVisitor.callAsFunction(casted=Casting.CastedProtocolValue @ 0x00000000191241b0, visitorWitnessTable=<unavailable>, self=<unavailable>) at AssociatedTypeRequirementsVisitor.swift:28:20 [opt]
    frame #9: 0x0000aaaaaaf5f380 TestWebService`partial apply for closure #1 in withCasted<Result>(_:as:body:) [inlined] closure #1 ($0=<unavailable>, body=<unavailable>, conformanceRecord=<unavailable>) throws -> τ_0_0 in Casting.withCasted<τ_0_0>(_: Any, as: Any.Type, body: (Casting.CastedProtocolValue) throws -> τ_0_0) throws -> Swift.Optional<τ_0_0> at withCasted.swift:19:56 [opt]
    frame #10: 0x0000aaaaaaf5f378 TestWebService`partial apply for closure #1 in withCasted<A>(_:as:body:) at <compiler-generated>:0 [opt]
    frame #11: 0x0000aaaaab43be68 TestWebService`partial apply for closure #1 in static Pointable.withUnsafeRawPointer<Self>(to:body:) [inlined] closure #1 ($0=<unavailable>, body=<unavailable>) throws -> τ_1_0 in static ValuePointers.Pointable.withUnsafeRawPointer<τ_0_0>(to: Any, body: (Swift.UnsafeRawPointer) throws -> τ_1_0) throws -> τ_1_0 at withUnsafeValuePointer.swift:23:64 [opt]
    frame #12: 0x0000aaaaab43be64 TestWebService`partial apply for closure #1 in static Pointable.withUnsafeRawPointer<A>(to:body:) at <compiler-generated>:0 [opt]
    frame #13: 0x0000fffff7c63d24 libswiftCore.so`Swift.withUnsafePointer<τ_0_0, τ_0_1>(to: τ_0_0, _: (Swift.UnsafePointer<τ_0_0>) throws -> τ_0_1) throws -> τ_0_1 + 20
    frame #14: 0x0000aaaaab43bc68 TestWebService`static Pointable.withUnsafeRawPointer<Self>(value=<unavailable>, body=0x0000aaaaaaf5f364 TestWebService`partial apply forwarder for closure #1 (Swift.UnsafeRawPointer) throws -> A in Casting.withCasted<A>(_: Any, as: Any.Type, body: (Casting.CastedProtocolValue) throws -> A) throws -> Swift.Optional<A> at <compiler-generated>) at withUnsafeValuePointer.swift:23:20 [opt]
    frame #15: 0x0000aaaaab43bb3c TestWebService`withUnsafeValuePointer<Result>(value=(payload_data_0 = 0x0000006f6c6c6148, payload_data_1 = 0xe500000000000000, payload_data_2 = 0x0000ffffffffebe0, metadata = 0x0000aaaaab963f18), body=<unavailable>) at withUnsafeValuePointer.swift:8:48 [opt]
    frame #16: 0x0000aaaaaaf5f2e0 TestWebService`withCasted<Result>(value=(payload_data_0 = 0x0000006f6c6c6148, payload_data_1 = 0xe500000000000000, payload_data_2 = 0x0000ffffffffebe0, metadata = 0x0000aaaaab963f18), protocolType=<unavailable>, body=0x0000aaaaaad3dbec) at withCasted.swift:19:16 [opt]
    frame #17: 0x0000aaaaaad3daac TestWebService`AssociatedTypeRequirementsVisitor.callAsFunction(value=(payload_data_0 = 0x0000006f6c6c6148, payload_data_1 = 0xe500000000000000, payload_data_2 = 0x0000ffffffffebe0, metadata = 0x0000aaaaab963f18), self=<unavailable>) at AssociatedTypeRequirementsVisitor.swift:25:16 [opt]
    frame #18: 0x0000aaaaaac2a694 TestWebService`Component.accept(visitor=0x0000aaaaaba90eb0, self=<unavailable>) at Component.swift:62:69 [opt]
    frame #19: 0x0000aaaaaac29324 TestWebService`closure #1 in closure #1 in Group.accept(self=<unavailable>, visitor=<unavailable>) at Group.swift:39:29 [opt]
    frame #20: 0x0000aaaaaad02b0c TestWebService`SyntaxTreeVisitor.enterComponentContext(block=0x0000aaaaaac2a430 TestWebService`partial apply forwarder for closure #1 () -> () in closure #1 () -> () in Apodini.Group.accept(Apodini.SyntaxTreeVisitor) -> () at <compiler-generated>, self=0x0000aaaaaba90eb0) at SyntaxTreeVisitor.swift:68:13 [opt]
    frame #21: 0x0000aaaaaac2926c TestWebService`partial apply for closure #1 in Group.accept(_:) [inlined] closure #1 (visitor=<unavailable>, self=<unavailable>) -> () in Apodini.Group.accept(Apodini.SyntaxTreeVisitor) -> () at Group.swift:33:21 [opt]
    frame #22: 0x0000aaaaaac29250 TestWebService`partial apply for closure #1 in Group.accept(_:) at <compiler-generated>:0 [opt]
    frame #23: 0x0000aaaaaad02948 TestWebService`SyntaxTreeVisitor.enterContent(block=0x0000aaaaaac29238 TestWebService`partial apply forwarder for closure #1 () -> () in Apodini.Group.accept(Apodini.SyntaxTreeVisitor) -> () at <compiler-generated>, self=<unavailable>) at SyntaxTreeVisitor.swift:53:13 [opt]
    frame #24: 0x0000aaaaaac29228 TestWebService`Group.accept(visitor=0x0000aaaaaba90eb0, self=<unavailable>) at Group.swift:32:17 [opt]
    frame #25: 0x0000aaaaaad07274 TestWebService`WebService.visit(visitor=0x0000aaaaaba90eb0, self=TestWebService.TestWebService @ 0xffffffffffffffff) at WebService.swift:100:15 [opt]
    frame #26: 0x0000aaaaaad06fd0 TestWebService`WebService.register(modelBuilder=0x0000aaaaaba83b00, self=<unavailable>) at WebService.swift:87:14 [opt]
    frame #27: 0x0000aaaaaad06ef0 TestWebService`static WebService.main(app=<unavailable>) at WebService.swift:71:20 [opt]
    frame #28: 0x0000aaaaaad06c98 TestWebService`static WebService.main(waitForCompletion=true, self=<unavailable>) at WebService.swift:44:9 [opt]
    frame #29: 0x0000aaaaaad06bd8 TestWebService`static WebService.main(self=0x0000aaaaab9d3a78) at WebService.swift:34:13 [opt]
    frame #30: 0x0000aaaaab43b79c TestWebService`main at main.swift:15:20 [opt]
    frame #31: 0x0000fffff6d0a090 libc.so.6`__libc_start_main + 232
    frame #32: 0x0000aaaaaac0de38 TestWebService`_start + 52

The code of SyntaxTreeVisitor can be found here.
The relevant code snippet is:

 private func formHandlerIndexPathForCurrentNode() -> HandlerIndexPath {
        let rawValue = currentNodeIndexPath
            .map { String($0 - 1) }
            .joined(separator: ".")
        return HandlerIndexPath(rawValue: rawValue)
 }

where currentNodeIndexPath is an Array<Int>.

If you want to try and reproduce it:

  1. Clone the swift package
  2. cd ApodiniDemoWebService
  3. swift build -c release
  4. Run the executable under something like /.build/release/TestWebService

I cannot quite understand what's wrong with the code. The same project compiles and runs correctly on amd. Any help would be greatly appreciated!

Cheers!

Where did you get a Swift 5.5 toolchain for arm? AFAIK, nobody provides such a build, did you build it yourself? Or are you using the new official trunk snapshot builds for ARM? That branch is more early work towards the next Swift 5.6 release.

Can you reproduce with the unofficial stable 5.4.1 builds for AArch64? If not, this may be a regression in whatever unstable branch you're using.

Thanks for the quick reply!

Yes, I used the new official development trunk builds for Swift 5.5.

After your reply, I tried it with the unofficial build for ARM for Swift 5.4.1 and I am still able to reproduce it, although the source of the error seems to be slightly different.

Process 27995 stopped
* thread #1, name = 'TestWebService', stop reason = signal SIGSEGV: invalid address (fault address: 0x1000000000000)
    frame #0: 0x0000aaaaaad0a3cc TestWebService`SyntaxTreeVisitor.formHandlerIndexPathForCurrentNode() [inlined] generic specialization <Swift.Int> of Swift.Array._getElement(_: Swift.Int, wasNativeTypeChecked: Swift.Bool, matchingSubscriptCheck: Swift._DependenceToken) -> τ_0_0 at <compiler-generated>:0 [opt]
Target 0: (TestWebService) stopped.
Stacktrace
* thread #1, name = 'TestWebService', stop reason = signal SIGSEGV: invalid address (fault address: 0x1000000000000)
  * frame #0: 0x0000aaaaaad0a3cc TestWebService`SyntaxTreeVisitor.formHandlerIndexPathForCurrentNode() [inlined] generic specialization <Swift.Int> of Swift.Array._getElement(_: Swift.Int, wasNativeTypeChecked: Swift.Bool, matchingSubscriptCheck: Swift._DependenceToken) -> τ_0_0 at <compiler-generated>:0 [opt]
    frame #1: 0x0000aaaaaad0a3cc TestWebService`SyntaxTreeVisitor.formHandlerIndexPathForCurrentNode() [inlined] generic specialization <Swift.Int> of Swift.Array.subscript.read : (Swift.Int) -> τ_0_0 at <compiler-generated>:0 [opt]
    frame #2: 0x0000aaaaaad0a3cc TestWebService`SyntaxTreeVisitor.formHandlerIndexPathForCurrentNode(self=<unavailable>) at SyntaxTreeVisitor.swift:124 [opt]
    frame #3: 0x0000aaaaaad0a0b8 TestWebService`SyntaxTreeVisitor.visit<H>(handler=, self=0x0000ffffffffe560) at SyntaxTreeVisitor.swift:94:61 [opt]
    frame #4: 0x0000aaaaaac232d8 TestWebService`HandlerVisitorHelperImpl.callAsFunction<H>(value=<unavailable>, self=<unavailable>) at Component.swift:101:17 [opt]
    frame #5: 0x0000fffff7cbf174 libswiftCore.so`Swift.withUnsafePointer<τ_0_0, τ_0_1>(to: τ_0_0, _: (Swift.UnsafePointer<τ_0_0>) throws -> τ_0_1) throws -> τ_0_1 + 20
    frame #6: 0x0000aaaaaad45c70 TestWebService`closure #1 in AssociatedTypeRequirementsVisitor.callAsFunction(casted=Casting.CastedProtocolValue @ 0x000000003afaa620, visitorWitnessTable=<unavailable>, self=<unavailable>) at AssociatedTypeRequirementsVisitor.swift:28:20 [opt]
    frame #7: 0x0000aaaaaaf670bc TestWebService`partial apply for closure #1 in withCasted<Result>(_:as:body:) [inlined] closure #1 ($0=<unavailable>, body=<unavailable>, conformanceRecord=<unavailable>) throws -> τ_0_0 in Casting.withCasted<τ_0_0>(_: Any, as: Any.Type, body: (Casting.CastedProtocolValue) throws -> τ_0_0) throws -> Swift.Optional<τ_0_0> at withCasted.swift:19:56 [opt]
    frame #8: 0x0000aaaaaaf670b4 TestWebService`partial apply for closure #1 in withCasted<A>(_:as:body:) at <compiler-generated>:0 [opt]
    frame #9: 0x0000aaaaab4696fc TestWebService`partial apply for closure #1 in static Pointable.withUnsafeRawPointer<Self>(to:body:) [inlined] closure #1 ($0=<unavailable>, body=<unavailable>) throws -> τ_1_0 in static ValuePointers.Pointable.withUnsafeRawPointer<τ_0_0>(to: Any, body: (Swift.UnsafeRawPointer) throws -> τ_1_0) throws -> τ_1_0 at withUnsafeValuePointer.swift:23:64 [opt]
    frame #10: 0x0000aaaaab4696f8 TestWebService`partial apply for closure #1 in static Pointable.withUnsafeRawPointer<A>(to:body:) at <compiler-generated>:0 [opt]
    frame #11: 0x0000fffff7cbf174 libswiftCore.so`Swift.withUnsafePointer<τ_0_0, τ_0_1>(to: τ_0_0, _: (Swift.UnsafePointer<τ_0_0>) throws -> τ_0_1) throws -> τ_0_1 + 20
    frame #12: 0x0000aaaaab4694fc TestWebService`static Pointable.withUnsafeRawPointer<Self>(value=<unavailable>, body=0x0000aaaaaaf670a0 TestWebService`partial apply forwarder for closure #1 (Swift.UnsafeRawPointer) throws -> A in Casting.withCasted<A>(_: Any, as: Any.Type, body: (Casting.CastedProtocolValue) throws -> A) throws -> Swift.Optional<A> at <compiler-generated>) at withUnsafeValuePointer.swift:23:20 [opt]
    frame #13: 0x0000aaaaab4693d0 TestWebService`withUnsafeValuePointer<Result>(value=(payload_data_0 = 0x0000006f6c6c6148, payload_data_1 = 0xe500000000000000, payload_data_2 = 0x0000ffffffffeb60, metadata = 0x0000aaaaab8ffeb0), body=<unavailable>) at withUnsafeValuePointer.swift:8:48 [opt]
    frame #14: 0x0000aaaaaaf6701c TestWebService`withCasted<Result>(value=(payload_data_0 = 0x0000006f6c6c6148, payload_data_1 = 0xe500000000000000, payload_data_2 = 0x0000ffffffffeb60, metadata = 0x0000aaaaab8ffeb0), protocolType=<unavailable>, body=0x0000aaaaaad45c90) at withCasted.swift:19:16 [opt]
    frame #15: 0x0000aaaaaad45b50 TestWebService`AssociatedTypeRequirementsVisitor.callAsFunction(value=(payload_data_0 = 0x0000006f6c6c6148, payload_data_1 = 0xe500000000000000, payload_data_2 = 0x0000ffffffffeb60, metadata = 0x0000aaaaab8ffeb0), self=<unavailable>) at AssociatedTypeRequirementsVisitor.swift:25:16 [opt]
    frame #16: 0x0000aaaaaac22e78 TestWebService`Component.accept(visitor=0x0000aaaaaba93e70, self=<unavailable>) at Component.swift:62:69 [opt]
    frame #17: 0x0000aaaaaac21b3c TestWebService`closure #1 in closure #1 in Group.accept(self=<unavailable>, visitor=<unavailable>) at Group.swift:39:29 [opt]
    frame #18: 0x0000aaaaaad09f70 TestWebService`SyntaxTreeVisitor.enterComponentContext(block=0x0000aaaaaac22c14 TestWebService`partial apply forwarder for closure #1 () -> () in closure #1 () -> () in Apodini.Group.accept(Apodini.SyntaxTreeVisitor) -> () at <compiler-generated>, self=0x0000aaaaaba93e70) at SyntaxTreeVisitor.swift:68:13 [opt]
    frame #19: 0x0000aaaaaac21a84 TestWebService`partial apply for closure #1 in Group.accept(_:) [inlined] closure #1 (visitor=<unavailable>, self=<unavailable>) -> () in Apodini.Group.accept(Apodini.SyntaxTreeVisitor) -> () at Group.swift:33:21 [opt]
    frame #20: 0x0000aaaaaac21a68 TestWebService`partial apply for closure #1 in Group.accept(_:) at <compiler-generated>:0 [opt]
    frame #21: 0x0000aaaaaad09dac TestWebService`SyntaxTreeVisitor.enterContent(block=0x0000aaaaaac21a50 TestWebService`partial apply forwarder for closure #1 () -> () in Apodini.Group.accept(Apodini.SyntaxTreeVisitor) -> () at <compiler-generated>, self=<unavailable>) at SyntaxTreeVisitor.swift:53:13 [opt]
    frame #22: 0x0000aaaaaac21a40 TestWebService`Group.accept(visitor=0x0000aaaaaba93e70, self=<unavailable>) at Group.swift:32:17 [opt]
    frame #23: 0x0000aaaaaad0ebac TestWebService`WebService.visit(visitor=0x0000aaaaaba93e70, self=TestWebService.TestWebService @ 0xffffffffffffffff) at WebService.swift:100:15 [opt]
    frame #24: 0x0000aaaaaad0e908 TestWebService`WebService.register(modelBuilder=0x0000aaaaaba86ca0, self=<unavailable>) at WebService.swift:87:14 [opt]
    frame #25: 0x0000aaaaaad0e828 TestWebService`static WebService.main(app=<unavailable>) at WebService.swift:71:20 [opt]
    frame #26: 0x0000aaaaaad0e590 TestWebService`static WebService.main(waitForCompletion=true, self=<unavailable>) at WebService.swift:44:9 [opt]
    frame #27: 0x0000aaaaaad0e4d0 TestWebService`static WebService.main(self=0x0000aaaaab9736f8) at WebService.swift:34:13 [opt]
    frame #28: 0x0000aaaaab469030 TestWebService`main at main.swift:15:20 [opt]
    frame #29: 0x0000fffff6dd7090 libc.so.6`__libc_start_main + 232
    frame #30: 0x0000aaaaaac113b4 TestWebService`_start + 52

Yes, I used the new official development trunk builds for Swift 5.5.

Swift 5.5 was branched a couple months ago, whereas trunk has a lot of new work towards the next 5.6 release. It still reports as 5.5-dev but it has diverged from the 5.5 branch.

Since you are able to reproduce with Swift 5.4.1, this could be an AArch64 bug in the Swift toolchain. Could you try reproducing with the official Swift 5.4 toolchain for Apple Silicon, ie macOS arm64? That toolchain probably gets a lot more attention from Swift devs than the lightly used linux aarch64 toolchain, and will rule out if this is an architecture issue.

Yes, I can give it definitely a try. Can you point me to the download by any chance? I wasn't able to find them on swift.org

I think you just need to install Xcode on macOS and you should be able to use it? I don't use macOS, so can't help you.

Thanks, I was able to try and test it on a M1 machine and there it just runs normally. So I assume, there is an issue with the Swift Arm toolchain.

No, that's why I asked you to try it on the M1, as that is also an ARM chip and an ARM codegen bug would show up there too. This suggests that this is some linux portability issue, most likely because one of your numerous dependencies assumes that it is building on linux x86_64 and not on linux AArch64.

When SPM checks out those dependencies in .build/checkouts, I'd run an audit on that code for all linux-specific code, ie grep -riE "linux|glibc" .build/checkouts. See if you can find any code that assumes x86_64, particularly in any C files that packages include sometimes.

I'd look there first and if you can't find anything, then start looking underneath at the linux AArch64 toolchain.