Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rust-lang/backtrace-rs
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.3.68
Choose a base ref
...
head repository: rust-lang/backtrace-rs
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0.3.69
Choose a head ref
Loading
83 changes: 83 additions & 0 deletions .github/workflows/check-binary-size.yml
Original file line number Diff line number Diff line change
@@ -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
})
}
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -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:
12 changes: 7 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -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']

12 changes: 10 additions & 2 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
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(),
_ => {}
}
}

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);
16 changes: 11 additions & 5 deletions crates/as-if-std/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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']
8 changes: 8 additions & 0 deletions crates/as-if-std/build.rs
Original file line number Diff line number Diff line change
@@ -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();
}
3 changes: 2 additions & 1 deletion src/print.rs
Original file line number Diff line number Diff line change
@@ -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(())
}

7 changes: 6 additions & 1 deletion src/print/fuchsia.rs
Original file line number Diff line number Diff line change
@@ -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")
}
81 changes: 72 additions & 9 deletions src/symbolize/gimli/parse_running_mmaps_unix.rs
Original file line number Diff line number Diff line change
@@ -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(),
}
);
}
2 changes: 1 addition & 1 deletion src/symbolize/mod.rs
Original file line number Diff line number Diff line change
@@ -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"),
4 changes: 2 additions & 2 deletions src/windows.rs
Original file line number Diff line number Diff line change
@@ -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;
}
}
)*