Skip to content

Commit

Permalink
Rollup merge of rust-lang#83607 - Berrysoft:master, r=nagisa
Browse files Browse the repository at this point in the history
Add `__CxxFrameHandler3` in `panic_abort`

Fix rust-lang#54137

<del>I initially tried to forward to `__CxxFrameHandler3` from `rust_eh_personality`, but later I found that LLVM uses handler names to distinguish exception type. Therefore I choose to add `__CxxFrameHandler3` in `panic_abort`. Anyway it solves the link problem, and this function will never be called.</del>

It seems that the original issue was solved, but still adding these tests.
  • Loading branch information
Dylan-DPC authored Apr 5, 2021
2 parents f3cc923 + 48acdb7 commit 52437be
Show file tree
Hide file tree
Showing 7 changed files with 249 additions and 0 deletions.
13 changes: 13 additions & 0 deletions library/panic_abort/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,19 @@ pub mod personalities {
)))]
pub extern "C" fn rust_eh_personality() {}

// On *-pc-windows-msvc we need such a symbol to make linker happy.
#[allow(non_snake_case)]
#[no_mangle]
#[cfg(all(target_os = "windows", target_env = "msvc"))]
pub extern "C" fn __CxxFrameHandler3(
_record: usize,
_frame: usize,
_context: usize,
_dispatcher: usize,
) -> u32 {
1
}

// On x86_64-pc-windows-gnu we use our own personality function that needs
// to return `ExceptionContinueSearch` as we're passing on all our frames.
#[rustc_std_internal_symbol]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// build-pass
// compile-flags: -C panic=abort -C target-feature=+crt-static
// aux-build:exit-success-if-unwind-msvc-no-std.rs
// only-msvc
// Test that `no_std` with `panic=abort` under MSVC toolchain
// doesn't cause error when linking to libcmt.
// We don't run this executable because it will hang in `rust_begin_unwind`

#![no_std]
#![no_main]

extern crate exit_success_if_unwind_msvc_no_std;

use core::panic::PanicInfo;

#[panic_handler]
fn handle_panic(_: &PanicInfo) -> ! {
loop {}
}

#[link(name = "libcmt")]
extern "C" {}

#[no_mangle]
pub extern "C" fn main() -> i32 {
exit_success_if_unwind_msvc_no_std::bar(do_panic);
0
}

fn do_panic() {
panic!();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// build-pass
// compile-flags: -C panic=abort
// aux-build:exit-success-if-unwind-msvc-no-std.rs
// only-msvc
// Test that `no_std` with `panic=abort` under MSVC toolchain
// doesn't cause error when linking to msvcrt.
// We don't run this executable because it will hang in `rust_begin_unwind`

#![no_std]
#![no_main]

extern crate exit_success_if_unwind_msvc_no_std;

use core::panic::PanicInfo;

#[panic_handler]
fn handle_panic(_: &PanicInfo) -> ! {
loop {}
}

#[link(name = "msvcrt")]
extern "C" {}

#[no_mangle]
pub extern "C" fn main() -> i32 {
exit_success_if_unwind_msvc_no_std::bar(do_panic);
0
}

fn do_panic() {
panic!();
}
54 changes: 54 additions & 0 deletions src/test/ui/panic-runtime/abort-link-to-unwind-msvc-no-std.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// build-pass
// compile-flags:-C panic=abort
// aux-build:exit-success-if-unwind-msvc-no-std.rs
// no-prefer-dynamic
// only-msvc
// We don't run this executable because it will hang in `rust_begin_unwind`

#![no_std]
#![no_main]
#![windows_subsystem = "console"]
#![feature(panic_abort)]

extern crate exit_success_if_unwind_msvc_no_std;
extern crate panic_abort;

use core::panic::PanicInfo;

#[panic_handler]
fn handle_panic(_: &PanicInfo) -> ! {
loop {}
}

#[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 memmove(dest: *mut u8, _src: *const u8, _n: usize) -> *mut u8 {
dest
}

#[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 memcmp(_mem1: *const u8, _mem2: *const u8, _n: usize) -> i32 {
0
}

#[no_mangle]
#[used]
static _fltused: i32 = 0;

#[no_mangle]
pub extern "C" fn mainCRTStartup() {
exit_success_if_unwind_msvc_no_std::bar(main);
}

fn main() {
panic!();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// compile-flags:-C panic=unwind
// no-prefer-dynamic

#![no_std]
#![crate_type = "rlib"]

struct Bomb;

impl Drop for Bomb {
fn drop(&mut self) {
#[link(name = "kernel32")]
extern "C" {
fn ExitProcess(code: u32) -> !;
}
unsafe {
ExitProcess(0);
}
}
}

pub fn bar(f: fn()) {
let _bomb = Bomb;
f();
}
47 changes: 47 additions & 0 deletions src/test/ui/panic-runtime/unwind-msvc-no-std-link-to-libcmt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// build-pass
// compile-flags: -C panic=unwind -C target-feature=+crt-static
// only-msvc
// Test that `no_std` with `panic=unwind` under MSVC toolchain
// doesn't cause error when linking to libcmt.

#![no_std]
#![no_main]
#![feature(alloc_error_handler)]
#![feature(panic_unwind)]

use core::alloc::{GlobalAlloc, Layout};

struct DummyAllocator;

unsafe impl GlobalAlloc for DummyAllocator {
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
core::ptr::null_mut()
}

unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
}

#[global_allocator]
static ALLOC: DummyAllocator = DummyAllocator;

#[alloc_error_handler]
fn rust_oom(_layout: Layout) -> ! {
panic!()
}

extern crate panic_unwind;

use core::panic::PanicInfo;

#[panic_handler]
fn handle_panic(_: &PanicInfo) -> ! {
loop {}
}

#[link(name = "libcmt")]
extern "C" {}

#[no_mangle]
pub extern "C" fn main() -> i32 {
panic!();
}
47 changes: 47 additions & 0 deletions src/test/ui/panic-runtime/unwind-msvc-no-std-link-to-msvcrt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// build-pass
// compile-flags: -C panic=unwind
// only-msvc
// Test that `no_std` with `panic=unwind` under MSVC toolchain
// doesn't cause error when linking to msvcrt.

#![no_std]
#![no_main]
#![feature(alloc_error_handler)]
#![feature(panic_unwind)]

use core::alloc::{GlobalAlloc, Layout};

struct DummyAllocator;

unsafe impl GlobalAlloc for DummyAllocator {
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
core::ptr::null_mut()
}

unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
}

#[global_allocator]
static ALLOC: DummyAllocator = DummyAllocator;

#[alloc_error_handler]
fn rust_oom(_layout: Layout) -> ! {
panic!()
}

extern crate panic_unwind;

use core::panic::PanicInfo;

#[panic_handler]
fn handle_panic(_: &PanicInfo) -> ! {
loop {}
}

#[link(name = "msvcrt")]
extern "C" {}

#[no_mangle]
pub extern "C" fn main() -> i32 {
panic!();
}

0 comments on commit 52437be

Please sign in to comment.