File tree Expand file tree Collapse file tree 10 files changed +174
-0
lines changed
src/test/run-make-fulldeps
c-unwind-abi-catch-lib-panic Expand file tree Collapse file tree 10 files changed +174
-0
lines changed Original file line number Diff line number Diff line change 1+ -include ../tools.mk
2+
3+ all :
4+ # Compile `panic.rs` and `add.c` into object files.
5+ #
6+ # Note that we invoke `rustc` directly, so we may emit an object rather
7+ # than an archive. We'll do that later.
8+ $(BARE_RUSTC ) $(RUSTFLAGS ) \
9+ --out-dir $(TMPDIR ) \
10+ --emit=obj panic.rs
11+ $(call COMPILE_OBJ,$(TMPDIR ) /add.o,add.c)
12+
13+ # Now, create an archive using these two objects.
14+ $(AR) crus $(TMPDIR)/libadd.a $(TMPDIR)/add.o $(TMPDIR)/panic.o
15+
16+ # Compile `main.rs`, which will link into our library, and run it.
17+ $(RUSTC) main.rs
18+ $(call RUN,main)
Original file line number Diff line number Diff line change 1+ #ifdef _WIN32
2+ __declspec(dllexport )
3+ #endif
4+
5+ // An external function, defined in Rust.
6+ extern void panic_if_greater_than_10 (unsigned x );
7+
8+ unsigned add_small_numbers (unsigned a , unsigned b ) {
9+ unsigned c = a + b ;
10+ panic_if_greater_than_10 (c );
11+ return c ;
12+ }
Original file line number Diff line number Diff line change 1+ //! A test for calling `C-unwind` functions across foreign function boundaries.
2+ //!
3+ //! This test triggers a panic in a Rust library that our foreign function invokes. This shows
4+ //! that we can unwind through the C code in that library, and catch the underlying panic.
5+ #![ feature( c_unwind) ]
6+
7+ use std:: panic:: { catch_unwind, AssertUnwindSafe } ;
8+
9+ fn main ( ) {
10+ // Call `add_small_numbers`, passing arguments that will trigger a panic, and catch it.
11+ let caught_unwind = catch_unwind ( AssertUnwindSafe ( || {
12+ let ( a, b) = ( 10 , 1 ) ;
13+ let _c = unsafe { add_small_numbers ( a, b) } ;
14+ unreachable ! ( "should have unwound instead of returned" ) ;
15+ } ) ) ;
16+
17+ // Assert that we did indeed panic, then unwrap and downcast the panic into the sum.
18+ assert ! ( caught_unwind. is_err( ) ) ;
19+ let panic_obj = caught_unwind. unwrap_err ( ) ;
20+ let panic_u32 = * panic_obj. downcast_ref :: < u32 > ( ) . unwrap ( ) ;
21+ assert_eq ! ( panic_u32, 11 ) ;
22+ }
23+
24+ #[ link( name = "add" ) ]
25+ extern "C-unwind" {
26+ /// An external function, defined in C.
27+ ///
28+ /// Returns the sum of two numbers, or panics if the sum is greater than 10.
29+ fn add_small_numbers ( a : u32 , b : u32 ) -> u32 ;
30+ }
Original file line number Diff line number Diff line change 1+ #![ crate_type = "staticlib" ]
2+ #![ feature( c_unwind) ]
3+
4+ /// This function will panic if `x` is greater than 10.
5+ ///
6+ /// This function is called by `add_small_numbers`.
7+ #[ no_mangle]
8+ pub extern "C-unwind" fn panic_if_greater_than_10 ( x : u32 ) {
9+ if x > 10 {
10+ panic ! ( x) ; // That is too big!
11+ }
12+ }
Original file line number Diff line number Diff line change 1+ -include ../tools.mk
2+
3+ all : $(call NATIVE_STATICLIB,add)
4+ $(RUSTC ) main.rs
5+ $(call RUN,main) || exit 1
Original file line number Diff line number Diff line change 1+ #ifdef _WIN32
2+ __declspec(dllexport )
3+ #endif
4+
5+ // An external function, defined in Rust.
6+ extern void panic_if_greater_than_10 (unsigned x );
7+
8+ unsigned add_small_numbers (unsigned a , unsigned b ) {
9+ unsigned c = a + b ;
10+ panic_if_greater_than_10 (c );
11+ return c ;
12+ }
Original file line number Diff line number Diff line change 1+ //! A test for calling `C-unwind` functions across foreign function boundaries.
2+ //!
3+ //! This test triggers a panic when calling a foreign function that calls *back* into Rust.
4+ #![ feature( c_unwind) ]
5+
6+ use std:: panic:: { catch_unwind, AssertUnwindSafe } ;
7+
8+ fn main ( ) {
9+ // Call `add_small_numbers`, passing arguments that will trigger a panic, and catch it.
10+ let caught_unwind = catch_unwind ( AssertUnwindSafe ( || {
11+ let ( a, b) = ( 10 , 1 ) ;
12+ let _c = unsafe { add_small_numbers ( a, b) } ;
13+ unreachable ! ( "should have unwound instead of returned" ) ;
14+ } ) ) ;
15+
16+ // Assert that we did indeed panic, then unwrap and downcast the panic into the sum.
17+ assert ! ( caught_unwind. is_err( ) ) ;
18+ let panic_obj = caught_unwind. unwrap_err ( ) ;
19+ let panic_u32 = * panic_obj. downcast_ref :: < u32 > ( ) . unwrap ( ) ;
20+ assert_eq ! ( panic_u32, 11 ) ;
21+ }
22+
23+ #[ link( name = "add" , kind = "static" ) ]
24+ extern "C-unwind" {
25+ /// An external function, defined in C.
26+ ///
27+ /// Returns the sum of two numbers, or panics if the sum is greater than 10.
28+ fn add_small_numbers ( a : u32 , b : u32 ) -> u32 ;
29+ }
30+
31+ /// This function will panic if `x` is greater than 10.
32+ ///
33+ /// This function is called by `add_small_numbers`.
34+ #[ no_mangle]
35+ pub extern "C-unwind" fn panic_if_greater_than_10 ( x : u32 ) {
36+ if x > 10 {
37+ panic ! ( x) ; // That is too big!
38+ }
39+ }
Original file line number Diff line number Diff line change 1+ -include ../tools.mk
2+
3+ all : $(call NATIVE_STATICLIB,add)
4+ $(RUSTC ) main.rs
5+ $(call RUN,main) || exit 1
Original file line number Diff line number Diff line change 1+ #ifdef _WIN32
2+ __declspec(dllexport )
3+ #endif
4+
5+ // An external function, defined in Rust.
6+ extern void panic_if_greater_than_10 (unsigned x );
7+
8+ unsigned add_small_numbers (unsigned a , unsigned b ) {
9+ unsigned c = a + b ;
10+ panic_if_greater_than_10 (c );
11+ return c ;
12+ }
Original file line number Diff line number Diff line change 1+ //! A test for calling `C-unwind` functions across foreign function boundaries.
2+ //!
3+ //! This test does *not* trigger a panic. The exercises the "happy path" when calling a foreign
4+ //! function that calls *back* into Rust.
5+ #![ feature( c_unwind) ]
6+
7+ fn main ( ) {
8+ let ( a, b) = ( 9 , 1 ) ;
9+ let c = unsafe { add_small_numbers ( a, b) } ;
10+ assert_eq ! ( c, 10 ) ;
11+ }
12+
13+ #[ link( name = "add" , kind = "static" ) ]
14+ extern {
15+ /// An external function, defined in C.
16+ ///
17+ /// Returns the sum of two numbers, or panics if the sum is greater than 10.
18+ fn add_small_numbers ( a : u32 , b : u32 ) -> u32 ;
19+ }
20+
21+ /// This function will panic if `x` is greater than 10.
22+ ///
23+ /// This function is called by `add_small_numbers`.
24+ #[ no_mangle]
25+ pub extern "C-unwind" fn panic_if_greater_than_10 ( x : u32 ) {
26+ if x > 10 {
27+ panic ! ( x) ; // That is too big!
28+ }
29+ }
You can’t perform that action at this time.
0 commit comments