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 ).
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):
- grab a
swift-backtrace-static
binary from a Swift 6 nightly image. - 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
- using different versions of
swift-backtrace-static
from other Swift Docker images. - building the app binary with a debug configuration.
- trying other various compiler options noted in this post: AWS Lambda functions and the Linux Static SDK - works!
Many thanks in advance!