diff --git a/.cargo/android-runner.sh b/.cargo/android-runner.sh index cfd908bf..23b55b85 100755 --- a/.cargo/android-runner.sh +++ b/.cargo/android-runner.sh @@ -10,4 +10,4 @@ TARGET=$(printf '%s' "$BINARY" | sed -E 's#(.*/)?target/([^/]+)/.*#\2#') # Make sure to run the following to copy the test helper binary over. # cargo run --target "$TARGET" --bin test adb push "$BINARY" "/data/local/$BINARY" -adb shell "chmod 777 /data/local/$BINARY && env TEST_HELPER=/data/local/target/$TARGET/debug/test /data/local/$BINARY" "$@" +adb shell "chmod 777 /data/local/$BINARY && env RUST_BACKTRACE='$RUST_BACKTRACE' TEST_HELPER=/data/local/target/$TARGET/debug/test /data/local/$BINARY" "$@" diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 99d6af7f..5be005ba 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -39,12 +39,23 @@ fn build_command() -> Command { cmd } +/// Must be taken by tests that use ptrace() to avoid racing on attaching to the parent, +/// leading to random failures. +static PTRACE_PARENT_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); + #[allow(unused)] pub fn spawn_child(command: &str, args: &[&str]) { let mut cmd = build_command(); cmd.arg(command).args(args); - let child = cmd.output().expect("failed to execute child"); + let child = { + // Panicking is fine as far as ptrace is concerned, + // no need to poison other tests. + let _guard = PTRACE_PARENT_LOCK + .lock() + .unwrap_or_else(|poisoned| poisoned.into_inner()); + cmd.output().expect("failed to execute child") + }; println!("Child output:"); println!("===stdout==="); diff --git a/tests/ptrace_dumper.rs b/tests/ptrace_dumper.rs index 75be7002..cdbb6f79 100644 --- a/tests/ptrace_dumper.rs +++ b/tests/ptrace_dumper.rs @@ -12,7 +12,6 @@ use { mem::size_of, os::unix::process::ExitStatusExt, ptr, - sync::Mutex, }, }; @@ -36,22 +35,13 @@ macro_rules! assert_no_soft_errors(($n: ident, $e: expr) => {{ __result }}); -static GLOBAL_LOCK: Mutex<()> = Mutex::new(()); - -macro_rules! one_at_a_time(() => { - let _guard_ = GLOBAL_LOCK.lock().unwrap_or_else(|e| e.into_inner()); -}); - #[test] fn setup() { - one_at_a_time!(); - spawn_child("setup", &[]); } #[test] fn thread_list_from_child() { - one_at_a_time!(); // Child spawns and looks in the parent (== this process) for its own thread-ID let (tx, rx) = std::sync::mpsc::sync_channel(1); @@ -110,8 +100,6 @@ fn thread_list_from_child() { #[test] fn thread_list_from_parent() { - one_at_a_time!(); - let num_of_threads = 5; let mut child = start_child_and_wait_for_threads(num_of_threads); let pid = child.id() as i32; @@ -187,23 +175,17 @@ fn thread_list_from_parent() { #[test] // Ensure that the linux-gate VDSO is included in the mapping list. fn mappings_include_linux_gate() { - one_at_a_time!(); - spawn_child("mappings_include_linux_gate", &[]); } #[test] fn linux_gate_mapping_id() { - one_at_a_time!(); - disabled_on_ci_and_android!(); spawn_child("linux_gate_mapping_id", &[]); } #[test] fn merges_mappings() { - one_at_a_time!(); - let page_size = unsafe { libc::sysconf(libc::_SC_PAGESIZE) }; assert!(page_size > 0); let page_size = usize::try_from(page_size).unwrap(); @@ -256,8 +238,6 @@ fn merges_mappings() { // Ensure that the linux-gate VDSO is included in the mapping list. #[test] fn file_id() { - one_at_a_time!(); - disabled_on_ci_and_android!(); spawn_child("file_id", &[]); } @@ -265,8 +245,6 @@ fn file_id() { #[cfg(not(target_os = "android"))] #[test] fn finds_mappings() { - one_at_a_time!(); - spawn_child( "find_mappings", &[ @@ -278,8 +256,6 @@ fn finds_mappings() { #[test] fn copies_from_process_self() { - one_at_a_time!(); - disabled_on_ci_and_android!(); let stack_var: libc::c_long = 0x11223344; @@ -296,8 +272,6 @@ fn copies_from_process_self() { // Ensures that we sanitize the stack properly #[test] fn sanitizes_stack_copies() { - one_at_a_time!(); - let num_of_threads = 1; let mut child = start_child_and_return(&["spawn_alloc_wait"]); let pid = child.id() as i32;