Repository navigation
Missing symbol in no_std application on panic (windows-msvc) #54137
Description
Activity
- addedA-linkageArea: linking into static, shared libraries and binariesArea: linking into static, shared libraries and binariesO-windows-msvcToolchain: MSVC, Operating system: WindowsToolchain: MSVC, Operating system: Windows
on Sep 11, 2018 - addedC-bugCategory: This is a bug.Category: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
on Jul 19, 2019 I'm facing the same issue with stable version 1.36. I don't know if it is an issue in the documentation which doesn't state that on Windows, you have to link with CRT or in the crate
panic_abortthat doesn't define this symbole on msvc starget.In src\librustc_codegen_llvm\context.rs, a different name is defined for
rust_eh_personality:let llfn = match tcx.lang_items().eh_personality() { Some(def_id) if !wants_msvc_seh(self.sess()) => { resolve_and_get_fn(self, def_id, tcx.intern_substs(&[])) } _ => { let name = if wants_msvc_seh(self.sess()) { "__CxxFrameHandler3" } else { "rust_eh_personality" }; let fty = self.type_variadic_func(&[], self.type_i32()); self.declare_cfn(name, fty) } };
But, unfortunatly, in crate libpanic_abort,
rust_eh_personalityis inconditionnaly defined.Two examples of code that compiles:
- with CRT linkage
#![cfg(target_os = "windows")] #![no_std] #![no_main] #![windows_subsystem = "console"] use core::panic::PanicInfo; // required by no_std #[panic_handler] fn handle_panic(_info: &PanicInfo) -> ! { loop {} } // linkage to CRT library according to crt-static flag set in .cargo/config: // [target.x86_64-pc-windows-msvc] // rustflags = ["-C", "target-feature=+crt-static"] #[cfg(target_feature = "crt-static")] #[link(name = "libcmt")] extern {} #[cfg(not(target_feature = "crt-static"))] #[link(name = "msvcrt")] extern {} // CRT is used, the entry point is main #[no_mangle] pub extern "C" fn main() -> i32 { panic!(); }
- with symbole
__CxxFrameHandler3
#![cfg(target_os = "windows")] #![no_std] #![no_main] #![windows_subsystem = "console"] use core::panic::PanicInfo; // required by no_std #[panic_handler] fn handle_panic(_info: &PanicInfo) -> ! { loop {} } #[no_mangle] pub unsafe extern "C" fn memset(mem: *mut u8, _val: i32, _n: usize) -> *mut u8 { mem } #[no_mangle] pub unsafe extern "C" fn memcpy(dest: *mut u8, _src: *const u8, _n: usize) -> *mut u8 { dest } #[no_mangle] pub unsafe extern "C" fn memcmp(_mem1: *const u8, _mem2: *const u8, _n: usize) -> i32 { 0 } #[no_mangle] pub extern "C" fn __CxxFrameHandler3() { } // no CRT and console subsystem => the entry point is mainCRTStartup #[no_mangle] pub extern "C" fn mainCRTStartup() -> ! { panic!(); }
Reacted by Bruno Lemke, Matthias and Arthur Le MoigneFrom the comments it looks like __CxxFrameHandler3 is used as the personality function on msvc to convince LLVM to use SEH instead of Dwarf exception handling, so it does not inject a dependency to _Unwind_Resume. Is this even necessary for panic=abort? Couldn't we keep rust_eh_personality on msvc if panic=abort and everything would work fine?
Could we just forward to
__CxxFrameHandler3inrust_eh_personality, and remove the requirement of__CxxFrameHandler3in context.rs? I'll try to do that later.- added 2 commits that reference this issue
on Apr 5, 2021 Going to close this as this no longer seems to be an issue. See here for more information.
- marked compile cdylib is ok,but staticlib can't link to __cxxframehandler3 #62795 as a duplicate of this issue
on Dec 28, 2024
A no_std application with the panic strategy set to abort and a panic_handler defined still needs the symbol "__CxxFrameHandler3" if a panic is invoked. The toolchain is nightly-x86_64-pc-windows-msvc.
A sample failing to compile due to this can be found at this repository. It contains a minimal implementation of a no_std binary for windows with stubs for the needed memory functions and the panic_handler.
I expected the application to compile just fine, because a panic_handler is defined and the panic strategy is set to "abort".
Instead I get a linker error complaining about the missing symbol "__CxxFrameHandler3". This only occurs if panic! is called. If I instead just loop forever in the main function, the compiler will return no error and work just fine.
Meta