Skip to content

The 'abi_mismatch' problem encountered when writing test code to detect the coexistence of 'stack-protector' and 'safe-stack' #149340

Closed

Description

@cezarbbb

I encountered some issues while writing test code for the "Stabilize stack-protector" proposal(see #146369). Specifically, when writing functions that allow both 'stack-protector' and 'safe-stack' functionality to coexist, I encountered an 'abi_mismatch' error from the referenced libraries. I tried using #[no_std] to avoid using some other libraries, but the same problem persisted.

My code is as follows:

//@ revisions: all strong none safestack safestack_strong safestack_all
//@ assembly-output: emit-asm
//@ignore-msvc safestack sanitizer not supported
//@ignore-musl safestack sanitizer not supported
//@ignore-nvptx64 stack protector is not supported
//@ignore-wasm32 safestack sanitizer not supported
//@ignore-aarch64
//@ [all] compile-flags: -Z stack-protector=all
//@ [strong] compile-flags: -Z stack-protector=strong
//@ [none] compile-flags: -Z stack-protector=none
//@ [safestack] compile-flags: -Z stack-protector=none -Z sanitizer=safestack
//@ [safestack_strong] compile-flags: -Z stack-protector=strong -Z sanitizer=safestack
//@ [safestack_all] compile-flags: -Z stack-protector=all -Z sanitizer=safestack
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled

#![no_std]
#![feature(link_llvm_intrinsics)]
#![feature(unsized_fn_params)]
#![crate_type = "lib"]

extern "C" { 
#[link_name = "llvm.memcpy.p0.p0.i64"] 
fn memcpy_intrinsic(dst: *mut u8, src: *const u8, size: u64, align: u32, is_volatile: bool);
}

//CHECK-LABEL: test1{{:|\[}}
#[no_mangle]
pub unsafe fn test1(src: *const u8, len: usize) -> u8 { 
let mut buf: [u8; 64] = [0; 64]; 

let copy_len = if len < 64 { len } else { 64 }; 
memcpy_intrinsic(buf.as_mut_ptr(), src, copy_len as u64, 1, false); 

buf[0] 

// none-NOT: __stack_chk_fail 
// strong: __stack_chk_fail 
// all: __stack_chk_fail 

// safestack: __safestack_unsafe_stack_ptr 
// safestack-NOT: __stack_chk_fail 

// safestack_strong: __safestack_unsafe_stack_ptr 
// safestack_strong: __stack_chk_fail 

// safestack_all: __safestack_unsafe_stack_ptr 
// safestack_all: __stack_chk_fail
}

The error is reported as follows:

------------------------------------------
2025-11-21T08:34:32.8540173Z	
2025-11-21T08:34:32.8540531Z	error in revision `safestack_strong`: compilation failed!
2025-11-21T08:34:32.8540835Z	status: exit status: 1
2025-11-21T08:34:32.8544229Z	command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage1/bin/rustc" "/checkout/tests/assembly-llvm/stack-protector/stack-protector-safe-stack.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage1" "--target=x86_64-unknown-linux-gnu" "--cfg" "safestack_strong" "--check-cfg" "cfg(test,FALSE,all,strong,none,safestack,safestack_strong,safestack_all)" "-O" "-Cdebug-assertions=no" "-Zcodegen-source-order" "--emit" "asm" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/assembly-llvm/stack-protector/stack-protector-safe-stack.safestack_strong/stack-protector-safe-stack.s" "-A" "internal_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Z" "stack-protector=strong" "-Z" "sanitizer=safestack" "-C" "opt-level=2" "-Z" "merge-functions=disabled"
2025-11-21T08:34:32.8547790Z	stdout: none
2025-11-21T08:34:32.8547999Z	--- stderr -------------------------------
2025-11-21T08:34:32.8548407Z	error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `stack_protector_safe_stack`
2025-11-21T08:34:32.8549212Z	##[error]  --> /checkout/tests/assembly-llvm/stack-protector/stack-protector-safe-stack.rs:16:1
2025-11-21T08:34:32.8549956Z	   |
2025-11-21T08:34:32.8550121Z	16 | #![no_std]
2025-11-21T08:34:32.8550393Z	   | ^
2025-11-21T08:34:32.8550575Z	   |
2025-11-21T08:34:32.8551064Z	   = help: the `-Zsanitizer` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
2025-11-21T08:34:32.8551741Z	   = note: `-Zsanitizer=safestack` in this crate is incompatible with unset `-Zsanitizer` in dependency `core`
2025-11-21T08:34:32.8552283Z	   = help: unset `-Zsanitizer` in this crate or set `-Zsanitizer=safestack` in `core`
2025-11-21T08:34:32.8552860Z	   = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer` to silence this error
2025-11-21T08:34:32.8553237Z	
2025-11-21T08:34:32.8553479Z	error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `stack_protector_safe_stack`
2025-11-21T08:34:32.8554273Z	##[error]  --> /checkout/tests/assembly-llvm/stack-protector/stack-protector-safe-stack.rs:16:1
2025-11-21T08:34:32.8555023Z	   |
2025-11-21T08:34:32.8555183Z	16 | #![no_std]
2025-11-21T08:34:32.8555359Z	   | ^
2025-11-21T08:34:32.8555535Z	   |
2025-11-21T08:34:32.8556033Z	   = help: the `-Zsanitizer` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
2025-11-21T08:34:32.8556742Z	   = note: `-Zsanitizer=safestack` in this crate is incompatible with unset `-Zsanitizer` in dependency `compiler_builtins`
2025-11-21T08:34:32.8557332Z	   = help: unset `-Zsanitizer` in this crate or set `-Zsanitizer=safestack` in `compiler_builtins`
2025-11-21T08:34:32.8557925Z	   = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer` to silence this error
2025-11-21T08:34:32.8558295Z	
2025-11-21T08:34:32.8558437Z	error: aborting due to 2 previous errors
2025-11-21T08:34:32.8558706Z	------------------------------------------

For a more detailed explanation of the error, please refer to my previously submitted pull request:#147115

PS: I reviewed the previous test code involving safe-stack as follows:

// This tests that the safestack attribute is applied when enabling the safe-stack sanitizer.
//
//@ needs-sanitizer-safestack
//@ compile-flags: -Zsanitizer=safestack -Copt-level=0

#![crate_type = "lib"]

// CHECK: ; Function Attrs:{{.*}}safestack
pub fn tagged() {}

// CHECK: attributes #0 = {{.*}}safestack

This empty function does not cause errors, but I have to do some corresponding operations to trigger the corresponding rules of stack-protector to take effect when checking 'safe-stack' and 'stack-protector'.

Activity

  1. added
    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.
    C-bugCategory: This is a bug.
    on Nov 26, 2025
  2. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Nov 26, 2025
  3. removed
    I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
    on Nov 26, 2025
  4. bjorn3 commented on Nov 26, 2025

    @bjorn3
    Member

    no_std will still use libcore. You could use a minicore based test. That way minicore gets compiled with stack protectors enbled too.

  5. added a commit that references this issue on Nov 27, 2025
  6. cezarbbb commented on Nov 27, 2025

    @cezarbbb
    ContributorAuthor

    no_std will still use libcore. You could use a minicore based test. That way minicore gets compiled with stack protectors enbled too.

    Thanks! I'll have a try

  7. added a commit that references this issue on Nov 27, 2025
  8. added
    C-discussionCategory: Discussion or questions that doesn't represent real issues.
    and removed
    C-bugCategory: This is a bug.
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    A-test-infra-minicoreArea: `minicore` test auxiliary and `//@ add-core-stubs`
    on Nov 27, 2025
  9. cezarbbb commented on Nov 28, 2025

    @cezarbbb
    ContributorAuthor

    @bjorn3 Sorry to bother you again. I rewrote a test using minicore, but encountered the following error.

    My modified code is as follows:

    //@ add-core-stubs
    //@ revisions: all strong none safestack safestack_strong safestack_all
    //@ assembly-output: emit-asm
    //@ only-x86_64-unknown-linux-gnu
    //@ [all] compile-flags: -Z stack-protector=all
    //@ [strong] compile-flags: -Z stack-protector=strong
    //@ [none] compile-flags: -Z stack-protector=none
    //@ [safestack] compile-flags: -Z stack-protector=none -Z sanitizer=safestack
    //@ [safestack_strong] compile-flags: -Z stack-protector=strong -Z sanitizer=safestack
    //@ [safestack_all] compile-flags: -Z stack-protector=all -Z sanitizer=safestack
    //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled --target x86_64-unknown-linux-gnu
    //@ needs-llvm-components: x86
    
    #![feature(unsized_fn_params)]
    #![crate_type = "lib"]
    #![feature(no_core)]
    #![no_core]
    #![no_std]
    
    extern crate minicore;
    use minicore::*;
    
    extern "C" {
        fn test4spss(p: *mut u8);
    }
    
    // CHECK-LABEL: test1{{:|\[}}
    #[no_mangle]
    pub unsafe fn test1(x: *mut u8) -> u8 {
        let mut buf: [u8; 64] = [0; 64];
    
        let p = &mut buf as *mut [u8; 64] as *mut u8;
    
        *p = 42;
    
        test4spss(p);
    
        *x = *p;
    
        *p
    
        // none-NOT: __stack_chk_fail
        // strong: __stack_chk_fail
        // all: __stack_chk_fail
    
        // safestack: __safestack_unsafe_stack_ptr
        // safestack-NOT: __stack_chk_fail
    
        // safestack_strong: __safestack_unsafe_stack_ptr
        // safestack_strong: __stack_chk_fail
    
        // safestack_all: __safestack_unsafe_stack_ptr
        // safestack_all: __stack_chk_fail
    }

    The error message is as follows:

    thread '<unnamed>' (211226) panicked at src/tools/compiletest/src/lib.rs:877:9:
    2025-11-28T07:33:38.1099707Z	directives check failed:
    2025-11-28T07:33:38.1101014Z	ERROR: unknown compiletest directive `add-core-stubs` at /checkout/tests/assembly-llvm/stack-protector/stack-protector-safe-stack.rs:1
    2025-11-28T07:33:38.1101588Z	stack backtrace:
    2025-11-28T07:33:38.1199744Z	   0: __rustc::rust_begin_unwind
    2025-11-28T07:33:38.1200170Z	             at /rustc/3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f/library/std/src/panicking.rs:698:5
    2025-11-28T07:33:38.1200583Z	   1: core::panicking::panic_fmt
    2025-11-28T07:33:38.1200946Z	             at /rustc/3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f/library/core/src/panicking.rs:80:14
    2025-11-28T07:33:38.1203429Z	   2: compiletest::make_test
    2025-11-28T07:33:38.1204488Z	   3: <rayon::iter::map::MapFolder<rayon::iter::reduce::ReduceFolder<compiletest::collect_tests_from_dir::{closure#2}, core::result::Result<compiletest::TestCollector, std::io::error::Error>>, compiletest::collect_tests_from_dir::{closure#0}> as rayon::iter::plumbing::Folder<core::result::Result<std::fs::DirEntry, std::io::error::Error>>>::consume
    2025-11-28T07:33:38.1212272Z	   4: <&rayon::iter::par_bridge::IterParallelProducer<std::fs::ReadDir> as rayon::iter::plumbing::UnindexedProducer>::fold_with::<rayon::iter::map::MapFolder<rayon::iter::reduce::ReduceFolder<compiletest::collect_tests_from_dir::{closure#2}, core::result::Result<compiletest::TestCollector, std::io::error::Error>>, compiletest::collect_tests_from_dir::{closure#0}>>
    2025-11-28T07:33:38.1216180Z	   5: rayon::iter::plumbing::bridge_unindexed_producer_consumer::<&rayon::iter::par_bridge::IterParallelProducer<std::fs::ReadDir>, rayon::iter::map::MapConsumer<rayon::iter::reduce::ReduceConsumer<compiletest::collect_tests_from_dir::{closure#2}, compiletest::collect_tests_from_dir::{closure#1}>, compiletest::collect_tests_from_dir::{closure#0}>>
    2025-11-28T07:33:38.1221977Z	   6: rayon_core::join::join_context::<rayon::iter::plumbing::bridge_unindexed_producer_consumer<&rayon::iter::par_bridge::IterParallelProducer<std::fs::ReadDir>, rayon::iter::map::MapConsumer<rayon::iter::reduce::ReduceConsumer<compiletest::collect_tests_from_dir::{closure#2}, compiletest::collect_tests_from_dir::{closure#1}>, compiletest::collect_tests_from_dir::{closure#0}>>::{closure#0}, rayon::iter::plumbing::bridge_unindexed_producer_consumer<&rayon::iter::par_bridge::IterParallelProducer<std::fs::ReadDir>, rayon::iter::map::MapConsumer<rayon::iter::reduce::ReduceConsumer<compiletest::collect_tests_from_dir::{closure#2}, compiletest::collect_tests_from_dir::{closure#1}>, compiletest::collect_tests_from_dir::{closure#0}>>::{closure#1}, core::result::Result<compiletest::TestCollector, std::io::error::Error>, core::result::Result<compiletest::TestCollector, std::io::error::Error>>::{closure#0}
    2025-11-28T07:33:38.1226105Z	   7: rayon::iter::plumbing::bridge_unindexed_producer_consumer::<&rayon::iter::par_bridge::IterParallelProducer<std::fs::ReadDir>, rayon::iter::map::MapConsumer<rayon::iter::reduce::ReduceConsumer<compiletest::collect_tests_from_dir::{closure#2}, compiletest::collect_tests_from_dir::{closure#1}>, compiletest::collect_tests_from_dir::{closure#0}>>
    2025-11-28T07:33:38.1229997Z	   8: rayon_core::join::join_context::<rayon::iter::plumbing::bridge_unindexed_producer_consumer<&rayon::iter::par_bridge::IterParallelProducer<std::fs::ReadDir>, rayon::iter::map::MapConsumer<rayon::iter::reduce::ReduceConsumer<compiletest::collect_tests_from_dir::{closure#2}, compiletest::collect_tests_from_dir::{closure#1}>, compiletest::collect_tests_from_dir::{closure#0}>>::{closure#0}, rayon::iter::plumbing::bridge_unindexed_producer_consumer<&rayon::iter::par_bridge::IterParallelProducer<std::fs::ReadDir>, rayon::iter::map::MapConsumer<rayon::iter::reduce::ReduceConsumer<compiletest::collect_tests_from_dir::{closure#2}, compiletest::collect_tests_from_dir::{closure#1}>, compiletest::collect_tests_from_dir::{closure#0}>>::{closure#1}, core::result::Result<compiletest::TestCollector, std::io::error::Error>, core::result::Result<compiletest::TestCollector, std::io::error::Error>>::{closure#0}
    2025-11-28T07:33:38.1233595Z	   9: rayon::iter::plumbing::bridge_unindexed_producer_consumer::<&rayon::iter::par_bridge::IterParallelProducer<std::fs::ReadDir>, rayon::iter::map::MapConsumer<rayon::iter::reduce::ReduceConsumer<compiletest::collect_tests_from_dir::{closure#2}, compiletest::collect_tests_from_dir::{closure#1}>, compiletest::collect_tests_from_dir::{closure#0}>>
    2025-11-28T07:33:38.1236974Z	  10: rayon_core::join::join_context::<rayon::iter::plumbing::bridge_unindexed_producer_consumer<&rayon::iter::par_bridge::IterParallelProducer<std::fs::ReadDir>, rayon::iter::map::MapConsumer<rayon::iter::reduce::ReduceConsumer<compiletest::collect_tests_from_dir::{closure#2}, compiletest::collect_tests_from_dir::{closure#1}>, compiletest::collect_tests_from_dir::{closure#0}>>::{closure#0}, rayon::iter::plumbing::bridge_unindexed_producer_consumer<&rayon::iter::par_bridge::IterParallelProducer<std::fs::ReadDir>, rayon::iter::map::MapConsumer<rayon::iter::reduce::ReduceConsumer<compiletest::collect_tests_from_dir::{closure#2}, compiletest::collect_tests_from_dir::{closure#1}>, compiletest::collect_tests_from_dir::{closure#0}>>::{closure#1}, core::result::Result<compiletest::TestCollector, std::io::error::Error>, core::result::Result<compiletest::TestCollector, std::io::error::Error>>::{closure#0}
    2025-11-28T07:33:38.1240419Z	  11: rayon::iter::plumbing::bridge_unindexed_producer_consumer::<&rayon::iter::par_bridge::IterParallelProducer<std::fs::ReadDir>, rayon::iter::map::MapConsumer<rayon::iter::reduce::ReduceConsumer<compiletest::collect_tests_from_dir::{closure#2}, compiletest::collect_tests_from_dir::{closure#1}>, compiletest::collect_tests_from_dir::{closure#0}>>
    2025-11-28T07:33:38.1242322Z	  12: <rayon::iter::par_bridge::IterBridge<std::fs::ReadDir> as rayon::iter::ParallelIterator>::drive_unindexed::<rayon::iter::map::MapConsumer<rayon::iter::reduce::ReduceConsumer<compiletest::collect_tests_from_dir::{closure#2}, compiletest::collect_tests_from_dir::{closure#1}>, compiletest::collect_tests_from_dir::{closure#0}>>
    2025-11-28T07:33:38.1244189Z	  13: <rayon::iter::map::Map<rayon::iter::par_bridge::IterBridge<std::fs::ReadDir>, compiletest::collect_tests_from_dir::{closure#0}> as rayon::iter::ParallelIterator>::drive_unindexed::<rayon::iter::reduce::ReduceConsumer<compiletest::collect_tests_from_dir::{closure#2}, compiletest::collect_tests_from_dir::{closure#1}>>
    2025-11-28T07:33:38.1245192Z	  14: compiletest::collect_tests_from_dir
    2025-11-28T07:33:38.1246228Z	  15: <rayon::iter::map::MapFolder<rayon::iter::reduce::ReduceFolder<compiletest::collect_tests_from_dir::{closure#2}, core::result::Result<compiletest::TestCollector, std::io::error::Error>>, compiletest::collect_tests_from_dir::{closure#0}> as rayon::iter::plumbing::Folder<core::result::Result<std::fs::DirEntry, std::io::error::Error>>>::consume
    2025-11-28T07:33:38.1248225Z	  16: <&rayon::iter::par_bridge::IterParallelProducer<std::fs::ReadDir> as rayon::iter::plumbing::UnindexedProducer>::fold_with::<rayon::iter::map::MapFolder<rayon::iter::reduce::ReduceFolder<compiletest::collect_tests_from_dir::{closure#2}, core::result::Result<compiletest::TestCollector, std::io::error::Error>>, compiletest::collect_tests_from_dir::{closure#0}>>
    2025-11-28T07:33:38.1250218Z	  17: rayon::iter::plumbing::bridge_unindexed_producer_consumer::<&rayon::iter::par_bridge::IterParallelProducer<std::fs::ReadDir>, rayon::iter::map::MapConsumer<rayon::iter::reduce::ReduceConsumer<compiletest::collect_tests_from_dir::{closure#2}, compiletest::collect_tests_from_dir::{closure#1}>, compiletest::collect_tests_from_dir::{closure#0}>>
    2025-11-28T07:33:38.1252929Z	  18: <rayon_core::job::StackJob<rayon_core::latch::SpinLatch, rayon_core::join::join_context::call_b<core::result::Result<compiletest::TestCollector, std::io::error::Error>, rayon::iter::plumbing::bridge_unindexed_producer_consumer<&rayon::iter::par_bridge::IterParallelProducer<std::fs::ReadDir>, rayon::iter::map::MapConsumer<rayon::iter::reduce::ReduceConsumer<compiletest::collect_tests_from_dir::{closure#2}, compiletest::collect_tests_from_dir::{closure#1}>, compiletest::collect_tests_from_dir::{closure#0}>>::{closure#1}>::{closure#0}, core::result::Result<compiletest::TestCollector, std::io::error::Error>> as rayon_core::job::Job>::execute
    2025-11-28T07:33:38.1254796Z	  19: <rayon_core::registry::WorkerThread>::wait_until_cold
    2025-11-28T07:33:38.1255086Z	  20: <rayon_core::registry::ThreadBuilder>::run
    2025-11-28T07:33:38.1255447Z	note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    2025-11-28T07:33:38.1262033Z	Bootstrap failed while executing `--stage 2 test --skip compiler --skip src`
    2025-11-28T07:33:38.1282988Z	Build completed unsuccessfully in 0:28:48
    2025-11-28T07:33:38.1434275Z	  local time: Fri Nov 28 07:33:38 UTC 2025
    2025-11-28T07:33:38.4611554Z	  network time: Fri, 28 Nov 2025 07:33:38 GMT
    2025-11-28T07:33:39.7336440Z	##[error]Process completed with exit code 1.
    

    After reviewing other tests, I can't find the problem. Does it require specific registration in Rustc to use 'add-core-stubs' correctly?

  10. bjorn3 commented on Nov 28, 2025

    @bjorn3
    Member

    The directive recently got renamed to //@ add-minicore.

  11. cezarbbb commented on Nov 28, 2025

    @cezarbbb
    ContributorAuthor

    The directive recently got renamed to //@ add-minicore.

    Thanks! I've read the minicore page before. However, I didn't see similar examples in other tests, so I didn't try it. I will try it now.

  12. added a commit that references this issue on Nov 29, 2025
  13. added a commit that references this issue on Nov 29, 2025
  14. added a commit that references this issue on Nov 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-no_stdArea: `#![no_std]`C-discussionCategory: Discussion or questions that doesn't represent real issues.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions