mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Auto merge of #81469 - tweksteen:android_set_message, r=m-ou-se
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
This commit is contained in:
commit
7953910464
@ -2492,6 +2492,7 @@ dependencies = [
|
||||
name = "panic_abort"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"alloc",
|
||||
"cfg-if 0.1.10",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
|
@ -13,6 +13,7 @@ bench = false
|
||||
doc = false
|
||||
|
||||
[dependencies]
|
||||
alloc = { path = "../alloc" }
|
||||
cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
|
||||
core = { path = "../core" }
|
||||
libc = { version = "0.2", default-features = false }
|
||||
|
49
library/panic_abort/src/android.rs
Normal file
49
library/panic_abort/src/android.rs
Normal file
@ -0,0 +1,49 @@
|
||||
use alloc::string::String;
|
||||
use core::mem::transmute;
|
||||
use core::panic::BoxMeUp;
|
||||
use core::ptr::copy_nonoverlapping;
|
||||
|
||||
const ANDROID_SET_ABORT_MESSAGE: &[u8] = b"android_set_abort_message\0";
|
||||
type SetAbortMessageType = unsafe extern "C" fn(*const libc::c_char) -> ();
|
||||
|
||||
// Forward the abort message to libc's android_set_abort_message. We try our best to populate the
|
||||
// message but as this function may already be called as part of a failed allocation, it may not be
|
||||
// possible to do so.
|
||||
//
|
||||
// Some methods of core are on purpose avoided (such as try_reserve) as these rely on the correct
|
||||
// resolution of rust_eh_personality which is loosely defined in panic_abort.
|
||||
//
|
||||
// Weakly resolve the symbol for android_set_abort_message. This function is only available
|
||||
// for API >= 21.
|
||||
pub(crate) unsafe fn android_set_abort_message(payload: *mut &mut dyn BoxMeUp) {
|
||||
let func_addr =
|
||||
libc::dlsym(libc::RTLD_DEFAULT, ANDROID_SET_ABORT_MESSAGE.as_ptr() as *const libc::c_char)
|
||||
as usize;
|
||||
if func_addr == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let payload = (*payload).get();
|
||||
let msg = match payload.downcast_ref::<&'static str>() {
|
||||
Some(msg) => msg.as_bytes(),
|
||||
None => match payload.downcast_ref::<String>() {
|
||||
Some(msg) => msg.as_bytes(),
|
||||
None => &[],
|
||||
},
|
||||
};
|
||||
if msg.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate a new buffer to append the null byte.
|
||||
let size = msg.len() + 1usize;
|
||||
let buf = libc::malloc(size) as *mut libc::c_char;
|
||||
if buf.is_null() {
|
||||
return; // allocation failure
|
||||
}
|
||||
copy_nonoverlapping(msg.as_ptr(), buf as *mut u8, msg.len());
|
||||
buf.offset(msg.len() as isize).write(0);
|
||||
|
||||
let func = transmute::<usize, SetAbortMessageType>(func_addr);
|
||||
func(buf);
|
||||
}
|
@ -19,6 +19,9 @@
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(asm)]
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
mod android;
|
||||
|
||||
use core::any::Any;
|
||||
use core::panic::BoxMeUp;
|
||||
|
||||
@ -31,6 +34,10 @@ pub unsafe extern "C" fn __rust_panic_cleanup(_: *mut u8) -> *mut (dyn Any + Sen
|
||||
// "Leak" the payload and shim to the relevant abort on the platform in question.
|
||||
#[rustc_std_internal_symbol]
|
||||
pub unsafe extern "C" fn __rust_start_panic(_payload: *mut &mut dyn BoxMeUp) -> u32 {
|
||||
// Android has the ability to attach a message as part of the abort.
|
||||
#[cfg(target_os = "android")]
|
||||
android::android_set_abort_message(_payload);
|
||||
|
||||
abort();
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
|
Loading…
Reference in New Issue
Block a user