1
Fork 0

Rollup merge of #105517 - pcc:process-panic-after-fork, r=davidtwco

Fix process-panic-after-fork.rs to pass on newer versions of Android.

The test process-panic-after-fork.rs was checking that abort() resulted in SIGSEGV on Android. This non-standard behavior was fixed back in 2013, so let's fix the test to also accept the standard behavior on Android.
This commit is contained in:
Matthias Krüger 2023-01-07 20:43:20 +01:00 committed by GitHub
commit 3d18c4d62d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -84,42 +84,47 @@ fn expect_aborted(status: ExitStatus) {
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
{ {
// Android signals an abort() call with SIGSEGV at address 0xdeadbaad assert!(signal == libc::SIGABRT || signal == libc::SIGSEGV);
// See e.g. https://groups.google.com/g/android-ndk/c/laW1CJc7Icc
assert!(signal == libc::SIGSEGV);
// Additional checks performed: if signal == libc::SIGSEGV {
// 1. Find last tombstone (similar to coredump but in text format) from the // Pre-KitKat versions of Android signal an abort() with SIGSEGV at address 0xdeadbaad
// same executable (path) as we are (must be because of usage of fork): // See e.g. https://groups.google.com/g/android-ndk/c/laW1CJc7Icc
// This ensures that we look into the correct tombstone. //
// 2. Cause of crash is a SIGSEGV with address 0xdeadbaad. // This behavior was changed in KitKat to send a standard SIGABRT signal.
// 3. libc::abort call is in one of top two functions on callstack. // See: https://r.android.com/60341
// The last two steps distinguish between a normal SIGSEGV and one caused //
// by libc::abort. // Additional checks performed:
// 1. Find last tombstone (similar to coredump but in text format) from the
// same executable (path) as we are (must be because of usage of fork):
// This ensures that we look into the correct tombstone.
// 2. Cause of crash is a SIGSEGV with address 0xdeadbaad.
// 3. libc::abort call is in one of top two functions on callstack.
// The last two steps distinguish between a normal SIGSEGV and one caused
// by libc::abort.
let this_exe = std::env::current_exe().unwrap().into_os_string().into_string().unwrap(); let this_exe = std::env::current_exe().unwrap().into_os_string().into_string().unwrap();
let exe_string = format!(">>> {this_exe} <<<"); let exe_string = format!(">>> {this_exe} <<<");
let tombstone = (0..100) let tombstone = (0..100)
.map(|n| format!("/data/tombstones/tombstone_{n:02}")) .map(|n| format!("/data/tombstones/tombstone_{n:02}"))
.filter(|f| std::path::Path::new(&f).exists()) .filter(|f| std::path::Path::new(&f).exists())
.map(|f| std::fs::read_to_string(&f).expect("Cannot read tombstone file")) .map(|f| std::fs::read_to_string(&f).expect("Cannot read tombstone file"))
.filter(|f| f.contains(&exe_string)) .filter(|f| f.contains(&exe_string))
.last() .last()
.expect("no tombstone found"); .expect("no tombstone found");
println!("Content of tombstone:\n{tombstone}"); println!("Content of tombstone:\n{tombstone}");
assert!( assert!(tombstone
tombstone.contains("signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad") .contains("signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad"));
); let abort_on_top = tombstone
let abort_on_top = tombstone .lines()
.lines() .skip_while(|l| !l.contains("backtrace:"))
.skip_while(|l| !l.contains("backtrace:")) .skip(1)
.skip(1) .take_while(|l| l.starts_with(" #"))
.take_while(|l| l.starts_with(" #")) .take(2)
.take(2) .any(|f| f.contains("/system/lib/libc.so (abort"));
.any(|f| f.contains("/system/lib/libc.so (abort")); assert!(abort_on_top);
assert!(abort_on_top); }
} }
} }