diff options
Diffstat (limited to 'library/backtrace')
-rw-r--r-- | library/backtrace/.github/workflows/check-binary-size.yml | 83 | ||||
-rw-r--r-- | library/backtrace/.github/workflows/main.yml | 2 | ||||
-rw-r--r-- | library/backtrace/Cargo.toml | 12 | ||||
-rw-r--r-- | library/backtrace/build.rs | 12 | ||||
-rw-r--r-- | library/backtrace/crates/as-if-std/Cargo.toml | 16 | ||||
-rw-r--r-- | library/backtrace/crates/as-if-std/build.rs | 8 | ||||
-rw-r--r-- | library/backtrace/src/print.rs | 3 | ||||
-rw-r--r-- | library/backtrace/src/print/fuchsia.rs | 7 | ||||
-rw-r--r-- | library/backtrace/src/symbolize/gimli/parse_running_mmaps_unix.rs | 81 | ||||
-rw-r--r-- | library/backtrace/src/symbolize/mod.rs | 2 | ||||
-rw-r--r-- | library/backtrace/src/windows.rs | 4 |
11 files changed, 203 insertions, 27 deletions
diff --git a/library/backtrace/.github/workflows/check-binary-size.yml b/library/backtrace/.github/workflows/check-binary-size.yml new file mode 100644 index 000000000..0beae1da9 --- /dev/null +++ b/library/backtrace/.github/workflows/check-binary-size.yml @@ -0,0 +1,83 @@ +# This workflow checks if a PR commit has changed the size of a hello world Rust program. +# It downloads Rustc and compiles two versions of a stage0 compiler - one using the base commit +# of the PR, and one using the latest commit in the PR. +# If the size of the hello world program has changed, it posts a comment to the PR. +name: Check binary size + +on: + pull_request_target: + branches: + - master + +jobs: + test: + name: Check binary size + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - name: Print info + run: | + echo "Current SHA: ${{ github.event.pull_request.head.sha }}" + echo "Base SHA: ${{ github.event.pull_request.base.sha }}" + - name: Clone Rustc + uses: actions/checkout@v3 + with: + repository: rust-lang/rust + fetch-depth: 1 + - name: Fetch backtrace + run: git submodule update --init library/backtrace + - name: Create hello world program that uses backtrace + run: printf "fn main() { panic!(); }" > foo.rs + - name: Build binary with base version of backtrace + run: | + printf "[llvm]\ndownload-ci-llvm = true\n\n[rust]\nincremental = false\n" > config.toml + cd library/backtrace + git remote add head-pr https://github.com/${{ github.event.pull_request.head.repo.full_name }} + git fetch --all + git checkout ${{ github.event.pull_request.base.sha }} + cd ../.. + git add library/backtrace + python3 x.py build library --stage 0 + ./build/x86_64-unknown-linux-gnu/stage0-sysroot/bin/rustc -O foo.rs -o binary-reference + - name: Build binary with PR version of backtrace + run: | + cd library/backtrace + git checkout ${{ github.event.pull_request.head.sha }} + cd ../.. + git add library/backtrace + rm -rf build/x86_64-unknown-linux-gnu/stage0-std + python3 x.py build library --stage 0 + ./build/x86_64-unknown-linux-gnu/stage0-sysroot/bin/rustc -O foo.rs -o binary-updated + - name: Display binary size + run: | + ls -la binary-* + echo "SIZE_REFERENCE=$(stat -c '%s' binary-reference)" >> "$GITHUB_ENV" + echo "SIZE_UPDATED=$(stat -c '%s' binary-updated)" >> "$GITHUB_ENV" + - name: Post a PR comment if the size has changed + uses: actions/github-script@v6 + with: + script: | + const reference = process.env.SIZE_REFERENCE; + const updated = process.env.SIZE_UPDATED; + const diff = updated - reference; + const plus = diff > 0 ? "+" : ""; + const diff_str = `${plus}${diff}B`; + + if (diff !== 0) { + const percent = (((updated / reference) - 1) * 100).toFixed(2); + // The body is created here and wrapped so "weirdly" to avoid whitespace at the start of the lines, + // which is interpreted as a code block by Markdown. + const body = `Below is the size of a hello-world Rust program linked with libstd with backtrace. + + Original binary size: **${reference}B** + Updated binary size: **${updated}B** + Difference: **${diff_str}** (${percent}%)`; + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body + }) + } diff --git a/library/backtrace/.github/workflows/main.yml b/library/backtrace/.github/workflows/main.yml index 29fff2795..21d7cb492 100644 --- a/library/backtrace/.github/workflows/main.yml +++ b/library/backtrace/.github/workflows/main.yml @@ -229,7 +229,7 @@ jobs: with: submodules: true - name: Install Rust - run: rustup update 1.55.0 && rustup default 1.55.0 + run: rustup update 1.65.0 && rustup default 1.65.0 - run: cargo build miri: diff --git a/library/backtrace/Cargo.toml b/library/backtrace/Cargo.toml index cff2c9e66..6714b3b7d 100644 --- a/library/backtrace/Cargo.toml +++ b/library/backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "backtrace" -version = "0.3.68" +version = "0.3.69" authors = ["The Rust Project Developers"] build = "build.rs" license = "MIT OR Apache-2.0" @@ -14,6 +14,7 @@ A library to acquire a stack trace (backtrace) at runtime in a Rust program. autoexamples = true autotests = true edition = "2018" +exclude = ["/ci/"] [workspace] members = ['crates/cpp_smoke_test', 'crates/as-if-std'] @@ -27,7 +28,6 @@ exclude = [ [dependencies] cfg-if = "1.0" rustc-demangle = "0.1.4" -libc = { version = "0.2.146", default-features = false } # Optionally enable the ability to serialize a `Backtrace`, controlled through # the `serialize-*` features below. @@ -37,11 +37,13 @@ rustc-serialize = { version = "0.3", optional = true } # Optionally demangle C++ frames' symbols in backtraces. cpp_demangle = { default-features = false, version = "0.4.0", optional = true, features = ["alloc"] } -addr2line = { version = "0.20.0", default-features = false } +[target.'cfg(not(all(windows, target_env = "msvc", not(target_vendor = "uwp"))))'.dependencies] miniz_oxide = { version = "0.7.0", default-features = false } +addr2line = { version = "0.21.0", default-features = false } +libc = { version = "0.2.146", default-features = false } -[dependencies.object] -version = "0.31.1" +[target.'cfg(not(all(windows, target_env = "msvc", not(target_vendor = "uwp"))))'.dependencies.object] +version = "0.32.0" default-features = false features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive'] diff --git a/library/backtrace/build.rs b/library/backtrace/build.rs index 812fbb1fe..9bd3abd16 100644 --- a/library/backtrace/build.rs +++ b/library/backtrace/build.rs @@ -1,8 +1,10 @@ extern crate cc; use std::env; +use std::path::Path; -fn main() { +// Must be public so the build script of `std` can call it. +pub fn main() { match env::var("CARGO_CFG_TARGET_OS").unwrap_or_default().as_str() { "android" => build_android(), _ => {} @@ -10,7 +12,13 @@ fn main() { } fn build_android() { - let expansion = match cc::Build::new().file("src/android-api.c").try_expand() { + // Resolve `src/android-api.c` relative to this file. + // Required to support calling this from the `std` build script. + let android_api_c = Path::new(file!()) + .parent() + .unwrap() + .join("src/android-api.c"); + let expansion = match cc::Build::new().file(android_api_c).try_expand() { Ok(result) => result, Err(e) => { println!("failed to run C compiler: {}", e); diff --git a/library/backtrace/crates/as-if-std/Cargo.toml b/library/backtrace/crates/as-if-std/Cargo.toml index 012e60f8f..bcbcfe159 100644 --- a/library/backtrace/crates/as-if-std/Cargo.toml +++ b/library/backtrace/crates/as-if-std/Cargo.toml @@ -15,15 +15,21 @@ bench = false cfg-if = "1.0" rustc-demangle = "0.1.21" libc = { version = "0.2.146", default-features = false } -addr2line = { version = "0.20.0", default-features = false, optional = true } -miniz_oxide = { version = "0.7", default-features = false } -[dependencies.object] -version = "0.31.1" +[target.'cfg(not(all(windows, target_env = "msvc", not(target_vendor = "uwp"))))'.dependencies] +miniz_oxide = { version = "0.7.0", optional = true, default-features = false } +addr2line = { version = "0.21.0", optional = true, default-features = false } + +[target.'cfg(not(all(windows, target_env = "msvc", not(target_vendor = "uwp"))))'.dependencies.object] +version = "0.32.0" default-features = false optional = true features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive'] +[build-dependencies] +# Dependency of the `backtrace` crate +cc = "1.0.67" + [features] default = ['backtrace'] -backtrace = ['addr2line', 'object'] +backtrace = ['addr2line', 'miniz_oxide', 'object'] diff --git a/library/backtrace/crates/as-if-std/build.rs b/library/backtrace/crates/as-if-std/build.rs index 7018b1017..7669f555d 100644 --- a/library/backtrace/crates/as-if-std/build.rs +++ b/library/backtrace/crates/as-if-std/build.rs @@ -1,3 +1,11 @@ +// backtrace-rs requires a feature check on Android targets, so +// we need to run its build.rs as well. +#[allow(unused_extern_crates)] +#[path = "../../build.rs"] +mod backtrace_build_rs; + fn main() { println!("cargo:rustc-cfg=backtrace_in_libstd"); + + backtrace_build_rs::main(); } diff --git a/library/backtrace/src/print.rs b/library/backtrace/src/print.rs index 8d9cbe3d4..395328a0a 100644 --- a/library/backtrace/src/print.rs +++ b/library/backtrace/src/print.rs @@ -83,7 +83,8 @@ impl<'a, 'b> BacktraceFmt<'a, 'b> { /// This is currently a no-op but is added for future compatibility with /// backtrace formats. pub fn finish(&mut self) -> fmt::Result { - // Currently a no-op-- including this hook to allow for future additions. + #[cfg(target_os = "fuchsia")] + fuchsia::finish_context(self.fmt)?; Ok(()) } diff --git a/library/backtrace/src/print/fuchsia.rs b/library/backtrace/src/print/fuchsia.rs index ce3f17862..cb872697d 100644 --- a/library/backtrace/src/print/fuchsia.rs +++ b/library/backtrace/src/print/fuchsia.rs @@ -425,7 +425,7 @@ impl DsoPrinter<'_, '_> { /// This function prints the Fuchsia symbolizer markup for all information contained in a DSO. pub fn print_dso_context(out: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - out.write_str("{{{reset}}}\n")?; + out.write_str("{{{reset:begin}}}\n")?; let mut visitor = DsoPrinter { writer: out, module_count: 0, @@ -434,3 +434,8 @@ pub fn print_dso_context(out: &mut core::fmt::Formatter<'_>) -> core::fmt::Resul for_each_dso(&mut visitor); visitor.error } + +/// This function prints the Fuchsia symbolizer markup to end the backtrace. +pub fn finish_context(out: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + out.write_str("{{{reset:end}}}\n") +} diff --git a/library/backtrace/src/symbolize/gimli/parse_running_mmaps_unix.rs b/library/backtrace/src/symbolize/gimli/parse_running_mmaps_unix.rs index deeeb2971..5d4b34675 100644 --- a/library/backtrace/src/symbolize/gimli/parse_running_mmaps_unix.rs +++ b/library/backtrace/src/symbolize/gimli/parse_running_mmaps_unix.rs @@ -85,16 +85,37 @@ impl FromStr for MapsEntry { // 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" + // + // Note that paths may contain spaces, so we can't use `str::split` for parsing (until + // Split::remainder is stabilized #77998). fn from_str(s: &str) -> Result<Self, Self::Err> { - 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 pathname_str = parts.next().unwrap_or(""); // pathname may be omitted. + let (range_str, s) = s.trim_start().split_once(' ').unwrap_or((s, "")); + if range_str.is_empty() { + return Err("Couldn't find address"); + } + + let (perms_str, s) = s.trim_start().split_once(' ').unwrap_or((s, "")); + if perms_str.is_empty() { + return Err("Couldn't find permissions"); + } + + let (offset_str, s) = s.trim_start().split_once(' ').unwrap_or((s, "")); + if offset_str.is_empty() { + return Err("Couldn't find offset"); + } + + let (dev_str, s) = s.trim_start().split_once(' ').unwrap_or((s, "")); + if dev_str.is_empty() { + return Err("Couldn't find dev"); + } + + let (inode_str, s) = s.trim_start().split_once(' ').unwrap_or((s, "")); + if inode_str.is_empty() { + return Err("Couldn't find inode"); + } + + // Pathname may be omitted in which case it will be empty + let pathname_str = s.trim_start(); let hex = |s| usize::from_str_radix(s, 16).map_err(|_| "Couldn't parse hex number"); let address = if let Some((start, limit)) = range_str.split_once('-') { @@ -229,4 +250,46 @@ fn check_maps_entry_parsing_32bit() { pathname: Default::default(), } ); + assert_eq!( + "b7c79000-b7e02000 r--p 00000000 08:01 60662705 \ + /executable/path/with some spaces" + .parse::<MapsEntry>() + .unwrap(), + MapsEntry { + address: (0xb7c79000, 0xb7e02000), + perms: ['r', '-', '-', 'p'], + offset: 0x00000000, + dev: (0x08, 0x01), + inode: 0x60662705, + pathname: "/executable/path/with some spaces".into(), + } + ); + assert_eq!( + "b7c79000-b7e02000 r--p 00000000 08:01 60662705 \ + /executable/path/with multiple-continuous spaces " + .parse::<MapsEntry>() + .unwrap(), + MapsEntry { + address: (0xb7c79000, 0xb7e02000), + perms: ['r', '-', '-', 'p'], + offset: 0x00000000, + dev: (0x08, 0x01), + inode: 0x60662705, + pathname: "/executable/path/with multiple-continuous spaces ".into(), + } + ); + assert_eq!( + " b7c79000-b7e02000 r--p 00000000 08:01 60662705 \ + /executable/path/starts-with-spaces" + .parse::<MapsEntry>() + .unwrap(), + MapsEntry { + address: (0xb7c79000, 0xb7e02000), + perms: ['r', '-', '-', 'p'], + offset: 0x00000000, + dev: (0x08, 0x01), + inode: 0x60662705, + pathname: "/executable/path/starts-with-spaces".into(), + } + ); } diff --git a/library/backtrace/src/symbolize/mod.rs b/library/backtrace/src/symbolize/mod.rs index dbc346522..a7c199506 100644 --- a/library/backtrace/src/symbolize/mod.rs +++ b/library/backtrace/src/symbolize/mod.rs @@ -471,7 +471,7 @@ cfg_if::cfg_if! { mod dbghelp; use dbghelp as imp; } else if #[cfg(all( - any(unix, windows), + any(unix, all(windows, target_env = "gnu")), not(target_vendor = "uwp"), not(target_os = "emscripten"), any(not(backtrace_in_libstd), feature = "backtrace"), diff --git a/library/backtrace/src/windows.rs b/library/backtrace/src/windows.rs index 9ec3ba99b..92c2b2e66 100644 --- a/library/backtrace/src/windows.rs +++ b/library/backtrace/src/windows.rs @@ -177,9 +177,9 @@ macro_rules! ffi { assert_eq!($name as usize, winapi::$name as usize); let mut x: unsafe extern "system" fn($($args)*) -> $ret; x = $name; - drop(x); + let _ = x; x = winapi::$name; - drop(x); + let _ = x; } } )* |