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