diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 29fff2795..00a195e7f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,18 +22,18 @@ jobs: rust: beta - os: ubuntu-20.04 rust: nightly - - os: macos-latest - rust: stable - - os: macos-latest - rust: nightly + # - os: macos-latest + # rust: stable + # - os: macos-latest + # rust: nightly # Note that these are on nightly due to rust-lang/rust#63700 not being # on stable yet - - os: windows-latest - rust: stable-x86_64-msvc - - os: windows-latest - rust: stable-i686-msvc - - os: windows-latest - rust: stable-x86_64-gnu + # - os: windows-latest + # rust: stable-x86_64-msvc + # - os: windows-latest + # rust: stable-i686-msvc + # - os: windows-latest + # rust: stable-x86_64-gnu steps: - uses: actions/checkout@v3 with: @@ -115,77 +115,77 @@ jobs: - run: cargo build --manifest-path crates/as-if-std/Cargo.toml - run: cargo build --manifest-path crates/as-if-std/Cargo.toml --no-default-features - windows_arm64: - name: Windows AArch64 - runs-on: windows-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - name: Install Rust - run: rustup update stable --no-self-update && rustup default stable - shell: bash - - run: echo RUSTFLAGS=-Dwarnings >> $GITHUB_ENV - shell: bash - - run: rustup target add aarch64-pc-windows-msvc - - run: cargo test --no-run --target aarch64-pc-windows-msvc - - run: cargo test --no-run --target aarch64-pc-windows-msvc --features verify-winapi - - ios: - name: iOS - runs-on: macos-latest - strategy: - matrix: - include: - - target: aarch64-apple-ios - sdk: iphoneos - - target: x86_64-apple-ios - sdk: iphonesimulator - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - run: rustup target add ${{ matrix.target }} - - run: | - export RUSTFLAGS=-Dwarnings - export SDK_PATH=`xcrun --show-sdk-path --sdk ${{ matrix.sdk }}` - export RUSTFLAGS="-C link-arg=-isysroot -C link-arg=$SDK_PATH" - cargo test --no-run --target ${{ matrix.target }} - name: Build tests - - docker: - name: Docker - runs-on: ubuntu-20.04 - strategy: - fail-fast: false - matrix: - target: - - aarch64-unknown-linux-gnu - - arm-unknown-linux-gnueabihf - - armv7-unknown-linux-gnueabihf - - i586-unknown-linux-gnu - - i686-unknown-linux-gnu - - powerpc64-unknown-linux-gnu - - s390x-unknown-linux-gnu - - x86_64-pc-windows-gnu - - x86_64-unknown-linux-gnu - - x86_64-unknown-linux-musl - - arm-linux-androideabi - - armv7-linux-androideabi - - aarch64-linux-android - - i686-linux-android - - x86_64-linux-android - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - name: Install Rust - run: rustup update stable && rustup default stable - - run: rustup target add ${{ matrix.target }} - - run: cargo generate-lockfile - - run: echo RUSTFLAGS=-Dwarnings >> $GITHUB_ENV - shell: bash - - run: ./ci/run-docker.sh ${{ matrix.target }} + # windows_arm64: + # name: Windows AArch64 + # runs-on: windows-latest + # steps: + # - uses: actions/checkout@v3 + # with: + # submodules: true + # - name: Install Rust + # run: rustup update stable --no-self-update && rustup default stable + # shell: bash + # - run: echo RUSTFLAGS=-Dwarnings >> $GITHUB_ENV + # shell: bash + # - run: rustup target add aarch64-pc-windows-msvc + # - run: cargo test --no-run --target aarch64-pc-windows-msvc + # - run: cargo test --no-run --target aarch64-pc-windows-msvc --features verify-winapi + + # ios: + # name: iOS + # runs-on: macos-latest + # strategy: + # matrix: + # include: + # - target: aarch64-apple-ios + # sdk: iphoneos + # - target: x86_64-apple-ios + # sdk: iphonesimulator + # steps: + # - uses: actions/checkout@v3 + # with: + # submodules: true + # - run: rustup target add ${{ matrix.target }} + # - run: | + # export RUSTFLAGS=-Dwarnings + # export SDK_PATH=`xcrun --show-sdk-path --sdk ${{ matrix.sdk }}` + # export RUSTFLAGS="-C link-arg=-isysroot -C link-arg=$SDK_PATH" + # cargo test --no-run --target ${{ matrix.target }} + # name: Build tests + + # docker: + # name: Docker + # runs-on: ubuntu-20.04 + # strategy: + # fail-fast: false + # matrix: + # target: + # - aarch64-unknown-linux-gnu + # - arm-unknown-linux-gnueabihf + # - armv7-unknown-linux-gnueabihf + # - i586-unknown-linux-gnu + # - i686-unknown-linux-gnu + # - powerpc64-unknown-linux-gnu + # - s390x-unknown-linux-gnu + # - x86_64-pc-windows-gnu + # - x86_64-unknown-linux-gnu + # - x86_64-unknown-linux-musl + # - arm-linux-androideabi + # - armv7-linux-androideabi + # - aarch64-linux-android + # - i686-linux-android + # - x86_64-linux-android + # steps: + # - uses: actions/checkout@v3 + # with: + # submodules: true + # - name: Install Rust + # run: rustup update stable && rustup default stable + # - run: rustup target add ${{ matrix.target }} + # - run: cargo generate-lockfile + # - run: echo RUSTFLAGS=-Dwarnings >> $GITHUB_ENV + # shell: bash + # - run: ./ci/run-docker.sh ${{ matrix.target }} rustfmt: name: Rustfmt @@ -198,28 +198,28 @@ jobs: run: rustup update stable && rustup default stable && rustup component add rustfmt - run: cargo fmt --all -- --check - build: - name: Build Targets - runs-on: ubuntu-20.04 - strategy: - matrix: - target: - - wasm32-unknown-unknown - - wasm32-wasi - - x86_64-unknown-fuchsia - - x86_64-fortanix-unknown-sgx - - x86_64-unknown-illumos - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - name: Install Rust - run: rustup update nightly && rustup default nightly - - run: rustup target add ${{ matrix.target }} - - run: echo RUSTFLAGS=-Dwarnings >> $GITHUB_ENV - shell: bash - - run: cargo build --target ${{ matrix.target }} - - run: cargo build --manifest-path crates/as-if-std/Cargo.toml --target ${{ matrix.target }} + # build: + # name: Build Targets + # runs-on: ubuntu-20.04 + # strategy: + # matrix: + # target: + # - wasm32-unknown-unknown + # - wasm32-wasi + # - x86_64-unknown-fuchsia + # - x86_64-fortanix-unknown-sgx + # - x86_64-unknown-illumos + # steps: + # - uses: actions/checkout@v3 + # with: + # submodules: true + # - name: Install Rust + # run: rustup update nightly && rustup default nightly + # - run: rustup target add ${{ matrix.target }} + # - run: echo RUSTFLAGS=-Dwarnings >> $GITHUB_ENV + # shell: bash + # - run: cargo build --target ${{ matrix.target }} + # - run: cargo build --manifest-path crates/as-if-std/Cargo.toml --target ${{ matrix.target }} msrv: name: MSRV diff --git a/src/symbolize/gimli/libs_dl_iterate_phdr.rs b/src/symbolize/gimli/libs_dl_iterate_phdr.rs index 9f0304ce8..a5f6b92c5 100644 --- a/src/symbolize/gimli/libs_dl_iterate_phdr.rs +++ b/src/symbolize/gimli/libs_dl_iterate_phdr.rs @@ -18,12 +18,11 @@ pub(super) fn native_libraries() -> Vec { } fn infer_current_exe(base_addr: usize) -> OsString { - if let Ok(entries) = super::parse_running_mmaps::parse_maps() { + if let Some(entries) = super::parse_running_mmaps::parse_maps() { let opt_path = entries - .iter() + .filter_map(|e| e.ok()) .find(|e| e.ip_matches(base_addr) && e.pathname().len() > 0) - .map(|e| e.pathname()) - .cloned(); + .map(|e| e.pathname().clone()); if let Some(path) = opt_path { return path; } diff --git a/src/symbolize/gimli/parse_running_mmaps_unix.rs b/src/symbolize/gimli/parse_running_mmaps_unix.rs index deeeb2971..87ebf1c91 100644 --- a/src/symbolize/gimli/parse_running_mmaps_unix.rs +++ b/src/symbolize/gimli/parse_running_mmaps_unix.rs @@ -3,9 +3,9 @@ // general purpose, but it hasn't been tested elsewhere. use super::mystd::fs::File; -use super::mystd::io::Read; +use super::mystd::io::{self, BufRead, BufReader, ErrorKind}; use super::mystd::str::FromStr; -use super::{OsString, String, Vec}; +use super::OsString; #[derive(PartialEq, Eq, Debug)] pub(super) struct MapsEntry { @@ -18,13 +18,13 @@ pub(super) struct MapsEntry { /// x = execute /// s = shared /// p = private (copy on write) - perms: [char; 4], + // perms: [u8; 4], /// Offset into the file (or "whatever"). - offset: usize, + // offset: usize, /// device (major, minor) - dev: (usize, usize), + // dev: (usize, usize), /// inode on the device. 0 indicates that no inode is associated with the memory region (e.g. uninitalized data aka BSS). - inode: usize, + // inode: usize, /// Usually the file backing the mapping. /// /// Note: The man page for proc includes a note about "coordination" by @@ -53,79 +53,77 @@ pub(super) struct MapsEntry { pathname: OsString, } -pub(super) fn parse_maps() -> Result, &'static str> { - let mut v = Vec::new(); - let mut proc_self_maps = - File::open("/proc/self/maps").map_err(|_| "Couldn't open /proc/self/maps")?; - let mut buf = String::new(); - let _bytes_read = proc_self_maps - .read_to_string(&mut buf) - .map_err(|_| "Couldn't read /proc/self/maps")?; - for line in buf.lines() { - v.push(line.parse()?); - } - - Ok(v) +pub(super) fn parse_maps() -> Option>> { + let proc_self_maps = match File::open("/proc/self/maps") { + Ok(f) => f, + Err(_) => return None, + }; + let buf_read = BufReader::new(proc_self_maps); + Some( + buf_read + .lines() + .map(|res| res.and_then(|s| s.parse().map_err(|e| io::Error::from(e)))), + ) } impl MapsEntry { + #[inline] pub(super) fn pathname(&self) -> &OsString { &self.pathname } + #[inline] pub(super) fn ip_matches(&self, ip: usize) -> bool { self.address.0 <= ip && ip < self.address.1 } } impl FromStr for MapsEntry { - type Err = &'static str; + type Err = io::ErrorKind; // Format: address perms offset dev inode pathname // e.g.: "ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]" // e.g.: "7f5985f46000-7f5985f48000 rw-p 00039000 103:06 76021795 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2" // e.g.: "35b1a21000-35b1a22000 rw-p 00000000 00:00 0" fn from_str(s: &str) -> Result { - let mut parts = s - .split(' ') // space-separated fields - .filter(|s| s.len() > 0); // multiple spaces implies empty strings that need to be skipped. - let range_str = parts.next().ok_or("Couldn't find address")?; - let perms_str = parts.next().ok_or("Couldn't find permissions")?; - let offset_str = parts.next().ok_or("Couldn't find offset")?; - let dev_str = parts.next().ok_or("Couldn't find dev")?; - let inode_str = parts.next().ok_or("Couldn't find inode")?; + let missing_field = ErrorKind::NotFound; + let parse_err = ErrorKind::InvalidData; + let mut parts = s.split_ascii_whitespace(); + let range_str = parts.next().ok_or(missing_field)?; + let perms_str = parts.next().ok_or(missing_field)?; + let offset_str = parts.next().ok_or(missing_field)?; + let dev_str = parts.next().ok_or(missing_field)?; + let inode_str = parts.next().ok_or(missing_field)?; let pathname_str = parts.next().unwrap_or(""); // pathname may be omitted. - let hex = |s| usize::from_str_radix(s, 16).map_err(|_| "Couldn't parse hex number"); + let hex = |s| usize::from_str_radix(s, 16).map_err(|_| parse_err); let address = if let Some((start, limit)) = range_str.split_once('-') { (hex(start)?, hex(limit)?) } else { - return Err("Couldn't parse address range"); + return Err(parse_err); }; - let perms: [char; 4] = { - let mut chars = perms_str.chars(); - let mut c = || chars.next().ok_or("insufficient perms"); - let perms = [c()?, c()?, c()?, c()?]; - if chars.next().is_some() { - return Err("too many perms"); - } - perms + let _perms = if let &[r, w, x, p, ..] = perms_str.as_bytes() { + // If a system in the future adds a 5th field to the permission list, + // there's no reason to assume previous fields were invalidated. + [r, w, x, p] + } else { + return Err(parse_err); }; - let offset = hex(offset_str)?; - let dev = if let Some((major, minor)) = dev_str.split_once(':') { + let _offset = hex(offset_str)?; + let _dev = if let Some((major, minor)) = dev_str.split_once(':') { (hex(major)?, hex(minor)?) } else { - return Err("Couldn't parse dev"); + return Err(parse_err); }; - let inode = hex(inode_str)?; + let _inode = hex(inode_str)?; let pathname = pathname_str.into(); Ok(MapsEntry { address, - perms, - offset, - dev, - inode, + // perms, + // offset, + // dev, + // inode, pathname, }) } @@ -142,10 +140,10 @@ fn check_maps_entry_parsing_64bit() { .unwrap(), MapsEntry { address: (0xffffffffff600000, 0xffffffffff601000), - perms: ['-', '-', 'x', 'p'], - offset: 0x00000000, - dev: (0x00, 0x00), - inode: 0x0, + // perms: *b"--xp", + // offset: 0x00000000, + // dev: (0x00, 0x00), + // inode: 0x0, pathname: "[vsyscall]".into(), } ); @@ -157,10 +155,10 @@ fn check_maps_entry_parsing_64bit() { .unwrap(), MapsEntry { address: (0x7f5985f46000, 0x7f5985f48000), - perms: ['r', 'w', '-', 'p'], - offset: 0x00039000, - dev: (0x103, 0x06), - inode: 0x76021795, + // perms: *b"rw-p", + // offset: 0x00039000, + // dev: (0x103, 0x06), + // inode: 0x76021795, pathname: "/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2".into(), } ); @@ -170,10 +168,10 @@ fn check_maps_entry_parsing_64bit() { .unwrap(), MapsEntry { address: (0x35b1a21000, 0x35b1a22000), - perms: ['r', 'w', '-', 'p'], - offset: 0x00000000, - dev: (0x00, 0x00), - inode: 0x0, + // perms: *b"rw-p", + // offset: 0x00000000, + // dev: (0x00, 0x00), + // inode: 0x0, pathname: Default::default(), } ); @@ -194,10 +192,10 @@ fn check_maps_entry_parsing_32bit() { .unwrap(), MapsEntry { address: (0x08056000, 0x08077000), - perms: ['r', 'w', '-', 'p'], - offset: 0x00000000, - dev: (0x00, 0x00), - inode: 0x0, + // perms: *b"rw-p", + // offset: 0x00000000, + // dev: (0x00, 0x00), + // inode: 0x0, pathname: "[heap]".into(), } ); @@ -209,10 +207,10 @@ fn check_maps_entry_parsing_32bit() { .unwrap(), MapsEntry { address: (0xb7c79000, 0xb7e02000), - perms: ['r', '-', '-', 'p'], - offset: 0x00000000, - dev: (0x08, 0x01), - inode: 0x60662705, + // perms: *b"r--p", + // offset: 0x00000000, + // dev: (0x08, 0x01), + // inode: 0x60662705, pathname: "/usr/lib/locale/locale-archive".into(), } ); @@ -222,10 +220,10 @@ fn check_maps_entry_parsing_32bit() { .unwrap(), MapsEntry { address: (0xb7e02000, 0xb7e03000), - perms: ['r', 'w', '-', 'p'], - offset: 0x00000000, - dev: (0x00, 0x00), - inode: 0x0, + // perms: *b"rw-p", + // offset: 0x00000000, + // dev: (0x00, 0x00), + // inode: 0x0, pathname: Default::default(), } );