File tree 4 files changed +53
-0
lines changed
4 files changed +53
-0
lines changed Original file line number Diff line number Diff line change @@ -2471,6 +2471,7 @@ dependencies = [
2471
2471
name = " panic_abort"
2472
2472
version = " 0.0.0"
2473
2473
dependencies = [
2474
+ " alloc" ,
2474
2475
" cfg-if 0.1.10" ,
2475
2476
" compiler_builtins" ,
2476
2477
" core" ,
Original file line number Diff line number Diff line change @@ -13,6 +13,7 @@ bench = false
13
13
doc = false
14
14
15
15
[dependencies ]
16
+ alloc = { path = " ../alloc" }
16
17
cfg-if = { version = " 0.1.8" , features = [' rustc-dep-of-std' ] }
17
18
core = { path = " ../core" }
18
19
libc = { version = " 0.2" , default-features = false }
Original file line number Diff line number Diff line change
1
+ use alloc:: string:: String ;
2
+ use alloc:: vec:: Vec ;
3
+ use core:: mem:: transmute;
4
+ use core:: panic:: BoxMeUp ;
5
+
6
+ const ANDROID_SET_ABORT_MESSAGE : & [ u8 ] = b"android_set_abort_message\0 " ;
7
+ type SetAbortMessageType = unsafe extern "C" fn ( * const libc:: c_char ) -> ( ) ;
8
+
9
+ // Forward the abort message to libc's android_set_abort_message. The fallible allocator is used
10
+ // to avoid panicking, as this function may already be called as part of a failed allocation.
11
+ //
12
+ // Weakly resolve the symbol for android_set_abort_message. This function is only available
13
+ // for API >= 21.
14
+ pub ( crate ) unsafe fn android_set_abort_message ( payload : * mut & mut dyn BoxMeUp ) {
15
+ let func_addr =
16
+ libc:: dlsym ( libc:: RTLD_DEFAULT , ANDROID_SET_ABORT_MESSAGE . as_ptr ( ) as * const libc:: c_char )
17
+ as usize ;
18
+ if func_addr == 0 {
19
+ return ;
20
+ }
21
+
22
+ let payload = ( * payload) . get ( ) ;
23
+ let msg = match payload. downcast_ref :: < & ' static str > ( ) {
24
+ Some ( msg) => msg. as_bytes ( ) ,
25
+ None => match payload. downcast_ref :: < String > ( ) {
26
+ Some ( msg) => msg. as_bytes ( ) ,
27
+ None => & [ ] ,
28
+ } ,
29
+ } ;
30
+ if msg. is_empty ( ) {
31
+ return ;
32
+ }
33
+
34
+ let size = msg. len ( ) + 1 ;
35
+ let mut v = Vec :: new ( ) ;
36
+ if v. try_reserve ( size) . is_err ( ) {
37
+ return ;
38
+ }
39
+
40
+ v. extend ( msg) ;
41
+ v. push ( 0 ) ;
42
+ let func = transmute :: < usize , SetAbortMessageType > ( func_addr) ;
43
+ func ( v. as_ptr ( ) as * const libc:: c_char ) ;
44
+ }
Original file line number Diff line number Diff line change 18
18
#![ feature( staged_api) ]
19
19
#![ feature( rustc_attrs) ]
20
20
#![ feature( asm) ]
21
+ #![ cfg_attr( target_os = "android" , feature( try_reserve) ) ]
22
+ #[ cfg( target_os = "android" ) ]
23
+ mod android;
21
24
22
25
use core:: any:: Any ;
23
26
use core:: panic:: BoxMeUp ;
@@ -31,6 +34,10 @@ pub unsafe extern "C" fn __rust_panic_cleanup(_: *mut u8) -> *mut (dyn Any + Sen
31
34
// "Leak" the payload and shim to the relevant abort on the platform in question.
32
35
#[ rustc_std_internal_symbol]
33
36
pub unsafe extern "C" fn __rust_start_panic ( _payload : * mut & mut dyn BoxMeUp ) -> u32 {
37
+ // Android has the ability to attach a message as part of the abort.
38
+ #[ cfg( target_os = "android" ) ]
39
+ android:: android_set_abort_message ( _payload) ;
40
+
34
41
abort ( ) ;
35
42
36
43
cfg_if:: cfg_if! {
You can’t perform that action at this time.
0 commit comments