Unable to generate a backtrace using Swift 6 Static Linux SDK

I have been successfully kicking the tires on building/ running a Vapor app using the Swift 6 Static Linux SDK (multi architecture Docker image built on a Mac and deployed and running in Kubernetes on non-Mac hardware). Truly fantastic!

However, I have been unable to generate a backtrace.

I am hoping someone can help shine light on how to get this working (even if that means being patient for all of this really great stuff to be out of beta :smile:).

Here's the basic set up right now (log output is at the bottom).

Building

Here are a few relevant snippets from a script used to build the app:

SWIFT_SDK="aarch64-swift-linux-musl"
SWIFT_TOOLCHAIN_NAME="swift-6.0-DEVELOPMENT-SNAPSHOT-2024-07-02-a"
export TOOLCHAINS=$(plutil -extract CFBundleIdentifier raw $SWIFT_TOOLCHAIN_PATH/Info.plist)

swift build -c release --swift-sdk $SWIFT_SDK

Note: I am currently using the snapshot from 2024-07-02 because that appears to be the latest SDK snapshot that aligns with a Swift 6 toolchain.

Dockerfile

The Dockerfile below contains two main steps (only relevant parts are included here; not a complete Dockerfile):

  1. grab a swift-backtrace-static binary from a Swift 6 nightly image.
  2. create an image for running the Vapor app (with the swift-backtrace-static made available).
FROM swiftlang/swift:nightly-6.0-jammy AS build

WORKDIR /staging

# Copy static swift backtrace binary to the staging area.
RUN cp "/usr/libexec/swift/linux/swift-backtrace-static" ./


FROM ubuntu:jammy

# other stuff omitted...

WORKDIR /app

# The value is passed via command line... assume `aarch64-swift-linux-musl` for this post.
ARG SWIFT_SDK=unknown

# Copy the `swift-backtrace-static` binary to the "app" directory.
COPY --from=build --chown=vapor:vapor /staging /app

# Copy the app binary to the "app" directory.
COPY --chown=vapor:vapor /.build/${SWIFT_SDK}/release/App /app

# https://github.com/swiftlang/swift/blob/main/docs/Backtracing.rst
ENV SWIFT_BACKTRACE=enable=yes,sanitize=yes,threads=all,images=all,interactive=no,swift-backtrace=./swift-backtrace-static

# other stuff omitted

Forcing a crash

Assume the app is now running in a container... the app will force a crash with the hope of seeing a backtrace.

Vapor example

Here's a simple Vapor route that forces a crash using a preconditionFailure:

route.get("precondition-failure") { request async throws -> String in 
    request.logger.error("Forcing a preconditionFailure.")
    preconditionFailure("Whoops")
}

The logs show the following:

[ ERROR ] Forcing a preconditionFailure. [request-id: 58BA22DE-5CE2-4820-B4AF-CAFFC331BE6D]

💣 Program crashed: Signal 5: Backtracing from 0x8c6ff0...swift-backtrace: unable to fetch crash info.
 failed

From what I can tell, the "swift-backtrace: unable to fetch crash info." message appears to come from the backtrace library.

Therefore, I am pretty confident the runtime found the swift-backtrace-static binary set on the SWIFT_BACKTRACE environment variable in the Dockerfile.

Things I tried without success

Many thanks in advance!

1 Like

Out of interest does it work if you compile a 'normal' static binary (i.e. --static-swift-stdlib and not using a Swift SDK? That should work fine on ubuntu-jammy. You can also try with a newer toolchain in case it includes fixes

@0xTim Yes, a backtrace is captured using a "normal" static binary. Specifically, I tested this using the default Vapor template (with the addition of the "precondition-failure" route listed above to force a crash).

Regarding using a newer toolchain. It's my understanding that the Static Linux SDK version must match the toolchain version.

The toolchain must match the version of the Static Linux SDK that you install. The Static Linux SDK includes the corresponding Swift version in its filename to help identify the correct version of the SDK.

From what I can tell the latest Static Linux SDK was released on July 2 (so it's been awhile since there's a been a release).

However, I just tried using the latest Swift 6 toolchain released on Aug. 22 with the Static Linux SDK released on July 2. The project appears to build and run without issue, but a backtrace is still not generated.

Perhaps I am missing something??

I also just tried a swift binary that is not based on Vapor... just a simple "main" method that prints "hello" then aborts (same build set up; same container execution; just a simple "main" method). Just in case there was something going on with Vapor (didn't think so, but worth a shot to rule it out).

Yeah just double checking that it's definitely something to do with the Swift SDK. Hopefully one of the backtrace engineers will pick it up on here

1 Like

I wonder if this would happen if the Static SDK is built without backtracing enabled?