`FileManager`, Docker, and ARM: Segmentation Fault

Dear Swift Community,

FileManager.attributesOfItem(atPath:) crashes when built using swift build -c release --static-swift-stdlib -Xswiftc -static-executable --enable-test-discovery. This only happens when a Swift package is built on a Docker container emulating an AArch64 CPU, then copied over to a Linux machine using an AArch64 CPU.

To reproduce:

  1. You’ll need a Mac and a Linux machine running Ubuntu that uses an AArch64 CPU.
  2. Install Docker on your Mac.
  3. Use the script below to reproduce the error.

Dockerfile


# AArch64 version of Ubuntu.
FROM ubuntu:latest@sha256:42c332a4493b201f8a5e3d4019e464aa2f5c6e6ef8fedccd0b6d3a7ac0912670

WORKDIR /build

RUN export DEBIAN_FRONTEND=noninteractive && \
            apt update -q && \
            apt install -yq curl sudo && \
            curl -s https://packagecloud.io/install/repositories/swift-arm/release/script.deb.sh | sudo bash && \
            apt install -yq swiftlang && \
            apt update -yq
COPY . .

RUN swift build -c release --static-swift-stdlib -Xswiftc -static-executable --enable-test-discovery

Sources/HelloWorld/main.swift

import Foundation
let attr = try FileManager.default.attributesOfItem(atPath: CommandLine.arguments[1])
print((attr[.size] as? Int) ?? 0)

Script

YourMac $ mkdir HelloWorld && cd HelloWorld

YourMac $ swift package init --type executable

# Create `Dockerfile` in current directory with contents defined above.

# Add Swift code above to Sources/HelloWorld/main.swift

YourMac $ docker build -t hello-world:latest .

YourMac $ mkdir build

YourMac $ docker cp $(docker create hello-world):build build

# Copy build/.build/release/HelloWorld to Linux machine. Use the following as an example.

YourMac $ sftp user@YourLinuxMachine

sftp> put build/.build/release/HelloWorld
sftp> exit

YourMac $ ssh user@YourLinuxMachine 

YourLinuxMachine $ echo "Hello, World" > test.txt

# Install lldb (usually part of llvm).

# Run lldb, 
YourLinuxMachine $ lldb HelloWorld -- text.txt
# Run program.
(lldb) r 

# Programs runs, then crashes.

# Print stack trace.
(lldb) bt 

# Stack trace is printed.

Stack trace

(lldb) r
Process 17162 launched: '/home/ubuntu/HelloWorld' (aarch64)
Process 17162 stopped
* thread #1, name = 'HelloWorld', stop reason = signal SIGSEGV: invalid address (fault address: 0xe4)
    frame #0: 0x0000fffff7f542ec
->  0xfffff7f542ec: ldrh   w0, [x3, x0]
    0xfffff7f542f0: tbz    w0, #0xd, 0xfffff7f54308
    0xfffff7f542f4: nop
    0xfffff7f542f8: ldrb   w4, [x19, #0x1]!
Target 0: (HelloWorld) stopped.
(lldb) bt
* thread #1, name = 'HelloWorld', stop reason = signal SIGSEGV: invalid address (fault address: 0xe4)
  * frame #0: 0x0000fffff7f542ec
    frame #1: 0x0000fffff7fd7a40
    frame #2: 0x0000fffff7fd7e40
    frame #3: 0x0000000000c79f38 HelloWorld`__getpwuid_r + 304
(lldb)

Jeff