Skip to content

Commit f41d0a4

Browse files
committed
android: set abort message
Android has the ability to supply an abort message [1]. This message is automatically included in the debug trace, which helps debugging [2]. Modify panic_abort to populate this message before calling abort(). [1] https://android.googlesource.com/platform/bionic/+/master/libc/include/android/set_abort_message.h [2] https://source.android.com/devices/tech/debug/native-crash
1 parent 2287a88 commit f41d0a4

File tree

4 files changed

+53
-0
lines changed

4 files changed

+53
-0
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -2471,6 +2471,7 @@ dependencies = [
24712471
name = "panic_abort"
24722472
version = "0.0.0"
24732473
dependencies = [
2474+
"alloc",
24742475
"cfg-if 0.1.10",
24752476
"compiler_builtins",
24762477
"core",

library/panic_abort/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ bench = false
1313
doc = false
1414

1515
[dependencies]
16+
alloc = { path = "../alloc" }
1617
cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
1718
core = { path = "../core" }
1819
libc = { version = "0.2", default-features = false }

library/panic_abort/src/android.rs

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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+
}

library/panic_abort/src/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
#![feature(staged_api)]
1919
#![feature(rustc_attrs)]
2020
#![feature(asm)]
21+
#![cfg_attr(target_os = "android", feature(try_reserve))]
22+
#[cfg(target_os = "android")]
23+
mod android;
2124

2225
use core::any::Any;
2326
use core::panic::BoxMeUp;
@@ -31,6 +34,10 @@ pub unsafe extern "C" fn __rust_panic_cleanup(_: *mut u8) -> *mut (dyn Any + Sen
3134
// "Leak" the payload and shim to the relevant abort on the platform in question.
3235
#[rustc_std_internal_symbol]
3336
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+
3441
abort();
3542

3643
cfg_if::cfg_if! {

0 commit comments

Comments
 (0)