8000 Use the debugger rendez-vous to populate the module list on Linux by schopin-mozilla · Pull Request #195 · rust-minidump/minidump-writer · GitHub
[go: up one dir, main page]

Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .cargo/android-runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
BINARY=$1
shift

# Cargo doesn't expose the target triple to the runner, so derive it from the
# binary path (.../target/<triple>/...).
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 x86_64-linux-android --bin test
# 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/x86_64-linux-android/debug/test /data/local/$BINARY" "$@"
adb shell "chmod 777 /data/local/$BINARY && env TEST_HELPER=/data/local/target/$TARGET/debug/test /data/local/$BINARY" "$@"
6 changes: 6 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,9 @@ linker = "x86_64-linux-android30-clang"
# By default the linker _doesn't_ generate a build-id, however we want one for our tests.
rustflags = ["-C", "link-args=-Wl,--build-id=sha1"]
runner = [".cargo/android-runner.sh"]

[target.aarch64-linux-android]
linker = "aarch64-linux-android30-clang"
# By default the linker _doesn't_ generate a build-id, however we want one for our tests.
rustflags = ["-C", "link-args=-Wl,--build-id=sha1"]
runner = [".cargo/android-runner.sh"]
2 changes: 2 additions & 0 deletions Cargo.lock
10000

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ memmap2 = "0.9"
byteorder = "1.4"
error-graph = { version = "0.1.1", features = ["serde"] }
failspot = "0.2.0"
plain = { version = "0.2.3", default-features = false }
process-backend = { version = "0.1.0", path = "crates/linux/process-backend", features = ["testing"] }

# Used for parsing procfs info.
Expand Down
2 changes: 2 additions & 0 deletions crates/linux/process-backend/src/local/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,6 @@ pub enum Error {
PtracePeekDataFailed(c_int),
#[error("ProcessReader returned an error")]
ProcessReader(#[source] process_reader::ReadError),
#[error("ProcessReader returned an error during an exact read")]
ProcessReaderExact(#[source] process_reader::ReadExactError),
}
4 changes: 4 additions & 0 deletions crates/linux/process-backend/src/local/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,10 @@ impl ProcessReader {
pub fn read_at 8000 (&self, address: usize, buf: &mut [u8]) -> Result<usize, Error> {
self.0.read_at(address, buf).map_err(Error::ProcessReader)
}

pub fn read_pod<T: process_reader::Plain>(&self, address: usize) -> Result<T, Error> {
self.0.read_pod(address).map_err(Error::ProcessReaderExact)
}
}

#[derive(Debug)]
Expand Down
1 change: 1 addition & 0 deletions crates/process-reader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ serde = ["dep:serde"]

[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies]
libc = { workspace = true, default-features = false }
plain = { version = "0.2.3", default-features = false }
serde = { version = "1.0.228", default-features = false, features = ["derive"], optional = true }
26 changes: 26 additions & 0 deletions crates/process-reader/src/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ use core::{
};

pub use error::{ReadError, ReadExactError};
pub use plain::Plain;

mod error;
mod wrapper;
Expand Down Expand Up @@ -300,6 +301,31 @@ impl ProcessReader {
}
}

/// Reads a plain-old-data value of type `T` from the target process at
/// `address`.
///
/// This reads exactly `size_of::<T>()` bytes into a freshly zeroed `T` using
/// [`read_exact_at`](Self::read_exact_at). The [`Plain`] bound guarantees
/// that every possible bit pattern is a valid `T`, so the bytes read from the
/// target process are always a valid value.
///
/// # Errors
///
/// Returns [`ReadExactError`] if the underlying exact read cannot fill the
/// value.
pub fn read_pod<T: Plain>(&self, address: usize) -> Result<T, ReadExactError> {
// Safety: `Plain` is an unsafe trait that may only be implemented on
// types for which every possible bit pattern is valid, so there is
// nothing we could read from the other process that isn't a valid value
// for `T`.
let mut pod: T = unsafe { core::mem::zeroed() };
let bytes = unsafe {
core::slice::from_raw_parts_mut(ptr::from_mut(&mut pod).cast::<u8>(), size_of::<T>())
};
self.read_exact_at(address, bytes)?;
Ok(pod)
}

/// Attempts to read bytes from the target process at `address`.
///
/// This method copies bytes from `address` in the target process into `buf`
Expand Down
6 changes: 6 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// Because of the nature of this crate, there are lots of times we cast aliased types to `u64`
// Often, on 64-bit platforms, it's already that, so Clippy gets upset at the u64-to-u64
// conversion.
#![allow(clippy::useless_conversion)]

cfg_if::cfg_if! {
if #[cfg(any(target_os = "linux", target_os = "android"))] {
mod linux;
Expand All @@ -9,6 +14,7 @@ cfg_if::cfg_if! {
ThreadName,
SuspendThreads,
CpuInfoFileOpen,
EnumerateMappingsFromProc,
}
}

Expand Down
11 changes: 10 additions & 1 deletion src/linux/dumper_cpu_info/arm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use {
super::{CpuInfoError, ProcessInspector},
crate::minidump_format::*,
failspot::failspot,
scroll::Pwrite,
std::{
collections::HashSet,
Expand Down Expand Up @@ -191,9 +192,17 @@ pub fn write_cpu_information(
// readable from regular Android applications on later versions
// (>= 4.1) of the Android platform.

if failspot!(CpuInfoFileOpen) {
process_inspector.fail_one_syscall_with(libc::EPERM);
}

let cpuinfo_file = match process_inspector.read_file("/proc/cpuinfo") {
Ok(x) => x,
Err(_) => {
Err(e) => {
// Surface a failspot-injected failure as a soft error.
if failspot!(CpuInfoFileOpen) {
return Err(CpuInfoError::ReadFileError(e));
}
// Do not return Error here to allow the minidump generation
// to happen properly.
return Ok(());
Expand Down
Loading
Loading
0