Merge of rust-lang/backtrace-rs#705: Add `optimize(size)` to some particularly large functions
* Check `as-if-std` only on nightly
* Add `optimize(size)` to some particularly large functions
It saves a few kb in hello world binaries when built as part of libstd.
The comments are formatted like they are so that if this feature
is stabilized they can be identified and used unconditionally.
diff --git a/.github/actions/build-with-patched-std/action.yml b/.github/actions/build-with-patched-std/action.yml
index 5466a22..46edb7e 100644
--- a/.github/actions/build-with-patched-std/action.yml
+++ b/.github/actions/build-with-patched-std/action.yml
@@ -31,8 +31,10 @@
# symlink on Linux and a junction on Windows, so it will exist on both
# platforms.
RUSTC_BUILD_DIR: build/host
+ RUST_BACKTRACE: 1
working-directory: ${{ inputs.rustc-dir }}
run: |
+ set -x
rm -rf "$RUSTC_BUILD_DIR/stage0-std"
(cd library/backtrace && git checkout ${{ inputs.backtrace-commit }})
diff --git a/.github/workflows/check-binary-size.yml b/.github/workflows/check-binary-size.yml
index b7025e7..5e8ba72 100644
--- a/.github/workflows/check-binary-size.yml
+++ b/.github/workflows/check-binary-size.yml
@@ -13,6 +13,7 @@
# Both the "measure" and "report" jobs need to know this.
env:
SIZE_DATA_DIR: sizes
+ RUST_BACKTRACE: 1
# Responsibility is divided between two jobs "measure" and "report", so that the
# job that builds (and potentnially runs) untrusted code does not have PR write
@@ -55,17 +56,20 @@
with:
repository: rust-lang/rust
path: ${{ env.RUSTC_DIR }}
+ # Arbitrary version from 2024-04-28
+ ref: cc74ed08d53fbb440b4ab70035a92d89d418d23c
- name: Set up std repository and backtrace submodule for size test
shell: bash
working-directory: ${{ env.RUSTC_DIR }}
env:
PR_SOURCE_REPO: ${{ github.event.pull_request.head.repo.full_name }}
run: |
+ set -x
# Bootstrap config
- cat <<EOF > config.toml
+ cat <<EOF > bootstrap.toml
change-id = 9999999
[llvm]
- download-ci-llvm = true
+ download-ci-llvm = "if-unchanged"
[rust]
incremental = false
EOF
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 0000000..9d74db3
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,52 @@
+name: Release-plz
+
+permissions:
+ pull-requests: write
+ contents: write
+
+on:
+ push: { branches: [master] }
+
+jobs:
+ # Release unpublished packages.
+ release-plz-release:
+ name: Release-plz release
+ runs-on: ubuntu-24.04
+ if: ${{ github.repository_owner == 'rust-lang' }}
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: Install Rust toolchain
+ run: rustup update stable --no-self-update && rustup default stable
+ - name: Run release-plz
+ uses: release-plz/action@v0.5
+ with:
+ command: release
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
+
+ # Create a PR with the new versions and changelog, preparing the next release.
+ release-plz-pr:
+ name: Release-plz PR
+ runs-on: ubuntu-24.04
+ if: ${{ github.repository_owner == 'rust-lang' }}
+ concurrency:
+ group: release-plz-${{ github.ref }}
+ cancel-in-progress: false
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: Install Rust toolchain
+ run: rustup update stable --no-self-update && rustup default stable
+ - name: Run release-plz
+ uses: release-plz/action@v0.5
+ with:
+ command: release-pr
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
diff --git a/Cargo.lock b/Cargo.lock
index 38b5fe1..e4a21b7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -93,9 +93,9 @@
[[package]]
name = "libc"
-version = "0.2.159"
+version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
+checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "libloading"
diff --git a/Cargo.toml b/Cargo.toml
index c2d4f15..b363e45 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -38,7 +38,7 @@
"alloc",
] }
-[target.'cfg(windows)'.dependencies]
+[target.'cfg(any(windows, target_os = "cygwin"))'.dependencies]
windows-targets = "0.52.6"
[target.'cfg(not(all(windows, target_env = "msvc", not(target_vendor = "uwp"))))'.dependencies]
diff --git a/crates/as-if-std/Cargo.toml b/crates/as-if-std/Cargo.toml
index 092905f..9e11b5e 100644
--- a/crates/as-if-std/Cargo.toml
+++ b/crates/as-if-std/Cargo.toml
@@ -27,7 +27,7 @@
optional = true
features = ['read_core', 'elf', 'macho', 'pe', 'xcoff', 'unaligned', 'archive']
-[target.'cfg(windows)'.dependencies]
+[target.'cfg(any(windows, target_os = "cygwin"))'.dependencies]
windows-targets = "0.52.6"
[features]
diff --git a/crates/cpp_smoke_test/Cargo.toml b/crates/cpp_smoke_test/Cargo.toml
index e1e51d9..4746ee0 100644
--- a/crates/cpp_smoke_test/Cargo.toml
+++ b/crates/cpp_smoke_test/Cargo.toml
@@ -4,6 +4,7 @@
authors = ["Nick Fitzgerald <fitzgen@gmail.com>"]
edition = "2021"
build = "build.rs"
+publish = false
[build-dependencies]
cc = "1.0"
diff --git a/crates/debuglink/Cargo.toml b/crates/debuglink/Cargo.toml
index 5e62abd..f832320 100644
--- a/crates/debuglink/Cargo.toml
+++ b/crates/debuglink/Cargo.toml
@@ -2,6 +2,7 @@
name = "debuglink"
version = "0.1.0"
edition = "2021"
+publish = false
[dependencies]
backtrace = { path = "../.." }
diff --git a/crates/line-tables-only/Cargo.toml b/crates/line-tables-only/Cargo.toml
index 4aa28f6..9cdd22b 100644
--- a/crates/line-tables-only/Cargo.toml
+++ b/crates/line-tables-only/Cargo.toml
@@ -2,6 +2,7 @@
name = "line-tables-only"
version = "0.1.0"
edition = "2021"
+publish = false
[build-dependencies]
cc = "1.0"
diff --git a/crates/macos_frames_test/Cargo.toml b/crates/macos_frames_test/Cargo.toml
index 849e764..cab83d0 100644
--- a/crates/macos_frames_test/Cargo.toml
+++ b/crates/macos_frames_test/Cargo.toml
@@ -3,6 +3,7 @@
version = "0.1.0"
authors = ["Aaron Hill <aa1ronham@gmail.com>"]
edition = "2021"
+publish = false
[dependencies.backtrace]
path = "../.."
diff --git a/crates/without_debuginfo/Cargo.toml b/crates/without_debuginfo/Cargo.toml
index b8c9394..37f10a6 100644
--- a/crates/without_debuginfo/Cargo.toml
+++ b/crates/without_debuginfo/Cargo.toml
@@ -3,6 +3,7 @@
version = "0.1.0"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
edition = "2021"
+publish = false
[dependencies.backtrace]
path = "../.."
diff --git a/src/capture.rs b/src/capture.rs
index fef2964..eb67259 100644
--- a/src/capture.rs
+++ b/src/capture.rs
@@ -28,7 +28,7 @@
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct Backtrace {
// Frames here are listed from top-to-bottom of the stack
- frames: Vec<BacktraceFrame>,
+ frames: Box<[BacktraceFrame]>,
}
#[derive(Clone, Copy)]
@@ -143,7 +143,7 @@
#[derive(Clone)]
pub struct BacktraceFrame {
frame: Frame,
- symbols: Option<Vec<BacktraceSymbol>>,
+ symbols: Option<Box<[BacktraceSymbol]>>,
}
#[derive(Clone)]
@@ -186,11 +186,11 @@
}
/// Resolve all addresses in the frame to their symbolic names.
- fn resolve_symbols(&self) -> Vec<BacktraceSymbol> {
+ fn resolve_symbols(&self) -> Box<[BacktraceSymbol]> {
let mut symbols = Vec::new();
let sym = |symbol: &Symbol| {
symbols.push(BacktraceSymbol {
- name: symbol.name().map(|m| m.as_bytes().to_vec()),
+ name: symbol.name().map(|m| m.as_bytes().into()),
addr: symbol.addr().map(TracePtr),
filename: symbol.filename().map(|m| m.to_owned()),
lineno: symbol.lineno(),
@@ -204,7 +204,7 @@
resolve(ip.into_void(), sym);
}
}
- symbols
+ symbols.into_boxed_slice()
}
}
@@ -220,7 +220,7 @@
#[derive(Clone)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct BacktraceSymbol {
- name: Option<Vec<u8>>,
+ name: Option<Box<[u8]>>,
addr: Option<TracePtr>,
filename: Option<PathBuf>,
lineno: Option<u32>,
@@ -306,7 +306,9 @@
});
frames.shrink_to_fit();
- Backtrace { frames }
+ Backtrace {
+ frames: frames.into_boxed_slice(),
+ }
}
/// Returns the frames from when this backtrace was captured.
@@ -320,7 +322,7 @@
/// This function requires the `std` feature of the `backtrace` crate to be
/// enabled, and the `std` feature is enabled by default.
pub fn frames(&self) -> &[BacktraceFrame] {
- self.frames.as_slice()
+ self.frames.as_ref()
}
/// If this backtrace was created from `new_unresolved` then this function
@@ -340,7 +342,9 @@
impl From<Vec<BacktraceFrame>> for Backtrace {
fn from(frames: Vec<BacktraceFrame>) -> Self {
- Backtrace { frames }
+ Backtrace {
+ frames: frames.into_boxed_slice(),
+ }
}
}
@@ -358,7 +362,7 @@
// more information on https://github.com/rust-lang/backtrace-rs/pull/526
impl Into<Vec<BacktraceFrame>> for Backtrace {
fn into(self) -> Vec<BacktraceFrame> {
- self.frames
+ self.frames.into_vec()
}
}
@@ -553,7 +557,7 @@
ip: usize,
symbol_address: usize,
module_base_address: Option<usize>,
- symbols: Option<Vec<BacktraceSymbol>>,
+ symbols: Option<Box<[BacktraceSymbol]>>,
}
impl Serialize for BacktraceFrame {
diff --git a/src/lib.rs b/src/lib.rs
index ab5e64c..13ca6b5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -150,7 +150,7 @@
static mut LOCK: *mut Mutex<()> = ptr::null_mut();
static INIT: Once = Once::new();
// Whether this thread is the one that holds the lock
- thread_local!(static LOCK_HELD: Cell<bool> = Cell::new(false));
+ thread_local!(static LOCK_HELD: Cell<bool> = const { Cell::new(false) });
impl Drop for LockGuard {
fn drop(&mut self) {
@@ -247,5 +247,5 @@
))]
mod dbghelp;
// Auto-generated by windows-bindgen/riddle
-#[cfg(windows)]
+#[cfg(any(windows, target_os = "cygwin"))]
mod windows_sys;
diff --git a/src/symbolize/gimli.rs b/src/symbolize/gimli.rs
index 04fed66..d7ff410 100644
--- a/src/symbolize/gimli.rs
+++ b/src/symbolize/gimli.rs
@@ -43,6 +43,7 @@
target_os = "solaris",
target_os = "illumos",
target_os = "aix",
+ target_os = "cygwin",
))] {
#[path = "gimli/mmap_unix.rs"]
mod mmap;
@@ -195,7 +196,7 @@
}
cfg_if::cfg_if! {
- if #[cfg(windows)] {
+ if #[cfg(any(windows, target_os = "cygwin"))] {
mod coff;
use self::coff::{handle_split_dwarf, Object};
} else if #[cfg(any(target_vendor = "apple"))] {
@@ -211,7 +212,7 @@
}
cfg_if::cfg_if! {
- if #[cfg(windows)] {
+ if #[cfg(any(windows, target_os = "cygwin"))] {
mod libs_windows;
use libs_windows::native_libraries;
} else if #[cfg(target_vendor = "apple")] {
diff --git a/src/symbolize/gimli/libs_windows.rs b/src/symbolize/gimli/libs_windows.rs
index 355dc06..1d9a74c 100644
--- a/src/symbolize/gimli/libs_windows.rs
+++ b/src/symbolize/gimli/libs_windows.rs
@@ -1,6 +1,5 @@
use super::super::super::windows_sys::*;
use super::mystd::ffi::OsString;
-use super::mystd::os::windows::prelude::*;
use super::{coff, mmap, Library, LibrarySegment};
use alloc::vec;
use alloc::vec::Vec;
@@ -43,13 +42,79 @@
}
}
+// Safety: long_path should be null-terminated
+#[cfg(target_os = "cygwin")]
+unsafe fn get_posix_path(long_path: &[u16]) -> Option<OsString> {
+ use super::mystd::os::unix::ffi::OsStringExt;
+
+ unsafe extern "C" {
+ // Doc: https://cygwin.com/cygwin-api/func-cygwin-conv-path.html
+ // Src: https://github.com/cygwin/cygwin/blob/718a15ba50e0d01c79800bd658c2477f9a603540/winsup/cygwin/path.cc#L3902
+ // Safety:
+ // * `what` should be `CCP_WIN_W_TO_POSIX` here
+ // * `from` is null-terminated UTF-16 path
+ // * `to` is buffer, the buffer size is `size`.
+ fn cygwin_conv_path(
+ what: libc::c_uint,
+ from: *const u16,
+ to: *mut u8,
+ size: libc::size_t,
+ ) -> libc::ssize_t;
+ }
+ const CCP_WIN_W_TO_POSIX: libc::c_uint = 3;
+
+ // If `size` is 0, returns needed buffer size, including null terminator;
+ // or -1 if error.
+ // Safety: if `size` is 0, `to` is not used.
+ let name_len = unsafe {
+ cygwin_conv_path(
+ CCP_WIN_W_TO_POSIX,
+ long_path.as_ptr(),
+ core::ptr::null_mut(),
+ 0,
+ )
+ };
+ // Expect at least 1 for null terminator.
+ // It's not likely to return error here.
+ if name_len < 1 {
+ return None;
+ }
+ let name_len = name_len as usize;
+ let mut name_buffer = Vec::with_capacity(name_len);
+ // Safety: `name_buffer` is large enough.
+ let res = unsafe {
+ cygwin_conv_path(
+ CCP_WIN_W_TO_POSIX,
+ long_path.as_ptr(),
+ name_buffer.as_mut_ptr(),
+ name_len,
+ )
+ };
+ // It's not likely to return error here.
+ if res != 0 {
+ return None;
+ }
+ // Remove the null terminator.
+ unsafe { name_buffer.set_len(name_len - 1) };
+ let name = OsString::from_vec(name_buffer);
+ Some(name)
+}
+
unsafe fn load_library(me: &MODULEENTRY32W) -> Option<Library> {
- let pos = me
- .szExePath
- .iter()
- .position(|i| *i == 0)
- .unwrap_or(me.szExePath.len());
- let name = OsString::from_wide(&me.szExePath[..pos]);
+ #[cfg(windows)]
+ let name = {
+ use super::mystd::os::windows::prelude::*;
+ let pos = me
+ .szExePath
+ .iter()
+ .position(|i| *i == 0)
+ .unwrap_or(me.szExePath.len());
+ OsString::from_wide(&me.szExePath[..pos])
+ };
+ #[cfg(target_os = "cygwin")]
+ // Safety: the path with max length MAX_PATH always contains a null
+ // terminator. Don't slice it.
+ let name = unsafe { get_posix_path(&me.szExePath[..])? };
// MinGW libraries currently don't support ASLR
// (rust-lang/rust#16514), but DLLs can still be relocated around in