Skip to content

Compiler panics when linking C static library composed with ar+ranlib #148217

@DIvanov503

Description

@DIvanov503

Code

Project structure:

project/
├── Cargo.toml
├── build.rs
└── src/
    ├── foo.c  <── empty
    └── lib.rs <── empty

Cargo.toml:

[package]
name = "project"
edition = "2024"
build = "build.rs"

[build-dependencies]
ar = "0.9.0"
cc = "1.0"

build.rs:

use ar::Builder;
use std::{env, fs::{self, File}, path::Path, process::Command};

fn main() {
    let build_path = env::var("OUT_DIR").expect("OUT_DIR not set by Cargo");
    let lib_path = Path::new(&build_path).join("lib");
    let l_path = lib_path.join("libl.a");

    if !lib_path.exists() {
        fs::create_dir_all(&lib_path).expect("Failed to create 'lib' directory");
    }

    let mut builder = Builder::new(File::create(&l_path).unwrap());

    let max_name_length = 15; // set this to 14 to hide the bug

    cc::Build::new()
        .file("src/foo.c")
        .compile_intermediates()
        .iter()
        .map(|object| { // only needed to trim the object filename for hiding the bug
            let object_path = Path::new(&object);
            let file_name = object_path.file_stem().expect("could not take file stem");
            let base_name = file_name.display().to_string();
            let trimmed_name = base_name.get(base_name.len().saturating_sub(max_name_length)..).unwrap_or(&base_name);
            let new_path = object_path.parent().expect("could not take parent").join(format!("{}.o", trimmed_name));

            fs::rename(object_path, &new_path).expect("Failed to rename object file");

            new_path
        })
        .for_each(|object| builder.append_path(object).expect("could not add object to archive"));

    Command::new("ranlib")
        .arg(&l_path)
        .status()
        .expect("Failed to run ranlib");

    println!("cargo:rustc-link-search={}", lib_path.display());
    println!("cargo:rustc-link-lib=static={}", "l");
}

Meta

rustc --version --verbose:

rustc 1.90.0 (1159e78c4 2025-09-14)
binary: rustc
commit-hash: 1159e78c4747b02ef996e55082b704c09b970588
commit-date: 2025-09-14
host: x86_64-unknown-linux-gnu
release: 1.90.0
LLVM version: 20.1.8

Error output

error: the compiler unexpectedly panicked. this is a bug.
Backtrace

thread 'rustc' panicked at compiler/rustc_codegen_ssa/src/back/archive.rs:481:29:
range end index 1576 out of range for slice of length 1556
stack backtrace:
   0:     0x7f7c4ea00f83 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::hdcfcb6d4c8489523
   1:     0x7f7c4f202d77 - core::fmt::write::h8a494366950f23bb
   2:     0x7f7c505d14d1 - std::io::Write::write_fmt::h6556609fca33d0b1
   3:     0x7f7c4ea00de2 - std::sys::backtrace::BacktraceLock::print::hb2a626a81e06b2dc
   4:     0x7f7c4ea04887 - std::panicking::default_hook::{{closure}}::h4f78485264f12d10
   5:     0x7f7c4ea043eb - std::panicking::default_hook::h2c66fc99e962531d
   6:     0x7f7c4da627e3 - std[9479b33d5e275715]::panicking::update_hook::<alloc[252dd2b3abdfe4a]::boxed::Box<rustc_driver_impl[773a1ede480c2143]::install_ice_hook::{closure#1}>>::{closure#0}
   7:     0x7f7c4ea050ce - std::panicking::rust_panic_with_hook::h33ac55f64bbd807d
   8:     0x7f7c4ea04dca - std::panicking::begin_panic_handler::{{closure}}::h30e7cb89678a57fe
   9:     0x7f7c4ea01459 - std::sys::backtrace::__rust_end_short_backtrace::hed60f27456c16ced
  10:     0x7f7c4ea04aad - __rustc[de2ca18b4c54d5b8]::rust_begin_unwind
  11:     0x7f7c4b0d01a0 - core::panicking::panic_fmt::h62f63d096dd276af
  12:     0x7f7c4d428157 - core::slice::index::slice_end_index_len_fail::do_panic::runtime::he43cf2c157f763ee
  13:     0x7f7c4c9bc5aa - core::slice::index::slice_end_index_len_fail::hb04774ae50b54dc9
  14:     0x7f7c503266a0 - <rustc_codegen_ssa[8cc6941b80b7847a]::back::archive::ArArchiveBuilder>::build_inner
  15:     0x7f7c50323c2c - <rustc_codegen_ssa[8cc6941b80b7847a]::back::archive::ArArchiveBuilder as rustc_codegen_ssa[8cc6941b80b7847a]::back::archive::ArchiveBuilder>::build
  16:     0x7f7c50329236 - rustc_codegen_ssa[8cc6941b80b7847a]::back::link::link_binary
  17:     0x7f7c504c7628 - <rustc_interface[c9c4c8df4db17049]::queries::Linker>::link
  18:     0x7f7c504c131b - rustc_interface[c9c4c8df4db17049]::interface::run_compiler::<(), rustc_driver_impl[773a1ede480c2143]::run_compiler::{closure#0}>::{closure#1}
  19:     0x7f7c503751c1 - std[9479b33d5e275715]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[c9c4c8df4db17049]::util::run_in_thread_with_globals<rustc_interface[c9c4c8df4db17049]::util::run_in_thread_pool_with_globals<rustc_interface[c9c4c8df4db17049]::interface::run_compiler<(), rustc_driver_impl[773a1ede480c2143]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
  20:     0x7f7c50374ea2 - <<std[9479b33d5e275715]::thread::Builder>::spawn_unchecked_<rustc_interface[c9c4c8df4db17049]::util::run_in_thread_with_globals<rustc_interface[c9c4c8df4db17049]::util::run_in_thread_pool_with_globals<rustc_interface[c9c4c8df4db17049]::interface::run_compiler<(), rustc_driver_impl[773a1ede480c2143]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core[42326c15e70145c1]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  21:     0x7f7c5037a7c5 - std::sys::pal::unix::thread::Thread::new::thread_start::hb6e99e73da4d28f8
  22:     0x7f7c49c6bac3 - start_thread
                               at ./nptl/pthread_create.c:442:8
  23:     0x7f7c49cfd8c0 - __GI___clone3
                               at ./misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:81:0
  24:                0x0 - <unknown>

build.rs compiles foo.c into a static library by following the following steps:

  1. generate the object .o file (compile_intermediates())
  2. pack it into .a archive (ar::Builder)
  3. add index with ranlib

An additional step for trimming the object filename was added to show that if the full simple name is less than 15, the panic does not manifest (set max_name_length).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-codegenArea: Code generationC-bugCategory: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions