Mac编写的Rust程序经Docker在Azure DevOps CI构建Ubuntu二进制文件后运行出现Segmentation fault的解决求助
It sounds like you’re hitting a common compatibility snag when building a Rust binary in one Linux environment and running it in another. Let’s break down the most likely causes and walk through fixes:
1. GLIBC Version Mismatch (Most Probable Root Cause)
Ubuntu 20.04 ships with GLIBC 2.31, but if your target virtual machine runs an older Linux distribution (like Ubuntu 18.04 with GLIBC 2.28, or a distro with an even older libc), your dynamically linked Rust binary will fail with a segmentation fault. Rust defaults to linking against the system’s GLIBC, which isn’t forward-compatible—newer libc versions can’t run on systems with older ones.
How to Fix This
Option A: Static Compile with Musl
Musl is a lightweight, statically-linked libc that completely avoids GLIBC dependencies. Adjust your Dockerfile like so:
FROM ubuntu:20.04 as cargo-build ENV TZ=Europe/Paris RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # Update packages and add musl tools for static compilation RUN apt-get -qq update && apt-get install -y -q \ build-essential \ openssl \ make \ cmake \ pkg-config \ libssl-dev \ libpq-dev \ curl \ musl-tools # Install Rust and add the musl target RUN curl https://sh.rustup.rs -sSf | sh -s -- -y ENV PATH="/root/.cargo/bin:${PATH}" RUN rustup target add x86_64-unknown-linux-musl WORKDIR /usr/src/app COPY Cargo.lock . # Always include this for reproducible builds! COPY Cargo.toml . COPY ./src src # Build a statically linked binary RUN cargo build --release --target x86_64-unknown-linux-musl
Your final binary will be at target/x86_64-unknown-linux-musl/release/[your-program-name]—this should run on any x86_64 Linux system without relying on the host’s libc.
Option B: Build with a Matching Base Image
If you can’t use Musl, switch your Docker base image to match the GLIBC version of your target VM. For example, if your VM runs Ubuntu 18.04, change FROM ubuntu:20.04 to FROM ubuntu:18.04. This ensures the binary links against a GLIBC version compatible with your deployment environment.
2. Missing Cargo.lock (Minor but Critical for Reproducibility)
You commented out COPY Cargo.lock . in your Dockerfile. Without this, Cargo will resolve dependencies from scratch during the build, which could lead to unexpected versions (even for simple programs). Always include Cargo.lock to guarantee consistent builds—this won’t fix the segmentation fault directly, but it eliminates hidden variables.
3. Verify Binary Dependencies
To confirm the root cause, check the dynamic dependencies of your built binary inside the Docker container:
ldd target/release/[your-program-name]
This lists all system libraries the binary links against. Compare these to the libraries available on your target VM (run ldd on the VM too). If any library is missing or has a mismatched version, that’s likely the culprit.
内容的提问来源于stack exchange,提问作者Modship

