about summary refs log tree commit diff
path: root/library
diff options
context:
space:
mode:
authorSamuel Tardieu <sam@rfc1149.net>2025-07-15 12:52:42 +0200
committerGitHub <noreply@github.com>2025-07-15 12:52:42 +0200
commit2e37e241792643abb837dbcaca454b0e02fc5002 (patch)
treeb4fff21469b3c8cf4cfa24c8167f36be5c761e14 /library
parent460a627b839af1eaf222d342efa93e51c9c77b24 (diff)
parent9fd3886838afd28ee3834d0e7162fd6ab5adc944 (diff)
downloadrust-2e37e241792643abb837dbcaca454b0e02fc5002.tar.gz
rust-2e37e241792643abb837dbcaca454b0e02fc5002.zip
Rollup merge of #143910 - ChrisDenton:no-symbolization, r=tgross35
Add experimental `backtrace-trace-only` std feature

This experimentally allows building std with backtrace but without symbolisation. It does not affect stable and requires build-std to use. This doesn't change the backtrace crate itself so relies on the optimizer to remove the unused parts.

Example usage:

```toml
# .cargo/config.toml
[unstable]
build-std = ["core", "alloc", "panic_unwind", "std"]
build-std-features = ["backtrace", "backtrace-trace-only", "panic-unwind"]
```

```toml
# Cargo.toml
[profile.release]
opt-level = 3
lto = "thin"
codegen-units = 1
```

Ideally we should split the backtrace feature into `backtrace-trace` and `backtrace-symbolize` (with the latter dependent on the former) because Cargo features tend to work better when they're positive rather than negative. But I'm keen for this experiment not to break existing users.

cc ``@joshtriplett``
Diffstat (limited to 'library')
-rw-r--r--library/std/Cargo.toml3
-rw-r--r--library/std/src/sys/backtrace.rs100
-rw-r--r--library/sysroot/Cargo.toml1
3 files changed, 57 insertions, 47 deletions
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 62ece4b6961..86d23df5238 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -92,6 +92,9 @@ backtrace = [
     'object/rustc-dep-of-std',
     'miniz_oxide/rustc-dep-of-std',
 ]
+# Disable symbolization in backtraces. For use with -Zbuild-std.
+# FIXME: Ideally this should be an additive backtrace-symbolization feature
+backtrace-trace-only = []
 
 panic-unwind = ["dep:panic_unwind"]
 compiler-builtins-c = ["alloc/compiler-builtins-c"]
diff --git a/library/std/src/sys/backtrace.rs b/library/std/src/sys/backtrace.rs
index efa6a896dad..272d0fa4d1a 100644
--- a/library/std/src/sys/backtrace.rs
+++ b/library/std/src/sys/backtrace.rs
@@ -68,61 +68,67 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
                 return false;
             }
 
-            let mut hit = false;
-            backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
-                hit = true;
-
-                // `__rust_end_short_backtrace` means we are done hiding symbols
-                // for now. Print until we see `__rust_begin_short_backtrace`.
-                if print_fmt == PrintFmt::Short {
-                    if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
-                        if sym.contains("__rust_end_short_backtrace") {
-                            print = true;
-                            return;
-                        }
-                        if print && sym.contains("__rust_begin_short_backtrace") {
-                            print = false;
-                            return;
-                        }
-                        if !print {
-                            omitted_count += 1;
+            if cfg!(feature = "backtrace-trace-only") {
+                const HEX_WIDTH: usize = 2 + 2 * size_of::<usize>();
+                let frame_ip = frame.ip();
+                res = writeln!(bt_fmt.formatter(), "{idx:4}: {frame_ip:HEX_WIDTH$?}");
+            } else {
+                let mut hit = false;
+                backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
+                    hit = true;
+
+                    // `__rust_end_short_backtrace` means we are done hiding symbols
+                    // for now. Print until we see `__rust_begin_short_backtrace`.
+                    if print_fmt == PrintFmt::Short {
+                        if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
+                            if sym.contains("__rust_end_short_backtrace") {
+                                print = true;
+                                return;
+                            }
+                            if print && sym.contains("__rust_begin_short_backtrace") {
+                                print = false;
+                                return;
+                            }
+                            if !print {
+                                omitted_count += 1;
+                            }
                         }
                     }
-                }
 
-                if print {
-                    if omitted_count > 0 {
-                        debug_assert!(print_fmt == PrintFmt::Short);
-                        // only print the message between the middle of frames
-                        if !first_omit {
-                            let _ = writeln!(
-                                bt_fmt.formatter(),
-                                "      [... omitted {} frame{} ...]",
-                                omitted_count,
-                                if omitted_count > 1 { "s" } else { "" }
-                            );
+                    if print {
+                        if omitted_count > 0 {
+                            debug_assert!(print_fmt == PrintFmt::Short);
+                            // only print the message between the middle of frames
+                            if !first_omit {
+                                let _ = writeln!(
+                                    bt_fmt.formatter(),
+                                    "      [... omitted {} frame{} ...]",
+                                    omitted_count,
+                                    if omitted_count > 1 { "s" } else { "" }
+                                );
+                            }
+                            first_omit = false;
+                            omitted_count = 0;
                         }
-                        first_omit = false;
-                        omitted_count = 0;
+                        res = bt_fmt.frame().symbol(frame, symbol);
                     }
-                    res = bt_fmt.frame().symbol(frame, symbol);
+                });
+                #[cfg(target_os = "nto")]
+                if libc::__my_thread_exit as *mut libc::c_void == frame.ip() {
+                    if !hit && print {
+                        use crate::backtrace_rs::SymbolName;
+                        res = bt_fmt.frame().print_raw(
+                            frame.ip(),
+                            Some(SymbolName::new("__my_thread_exit".as_bytes())),
+                            None,
+                            None,
+                        );
+                    }
+                    return false;
                 }
-            });
-            #[cfg(target_os = "nto")]
-            if libc::__my_thread_exit as *mut libc::c_void == frame.ip() {
                 if !hit && print {
-                    use crate::backtrace_rs::SymbolName;
-                    res = bt_fmt.frame().print_raw(
-                        frame.ip(),
-                        Some(SymbolName::new("__my_thread_exit".as_bytes())),
-                        None,
-                        None,
-                    );
+                    res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
                 }
-                return false;
-            }
-            if !hit && print {
-                res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
             }
 
             idx += 1;
diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml
index 290c2eeed44..032f5272a9c 100644
--- a/library/sysroot/Cargo.toml
+++ b/library/sysroot/Cargo.toml
@@ -20,6 +20,7 @@ test = { path = "../test", public = true }
 [features]
 default = ["std_detect_file_io", "std_detect_dlsym_getauxval", "panic-unwind"]
 backtrace = ["std/backtrace"]
+backtrace-trace-only = ["std/backtrace-trace-only"]
 compiler-builtins-c = ["std/compiler-builtins-c"]
 compiler-builtins-mem = ["std/compiler-builtins-mem"]
 compiler-builtins-no-asm = ["std/compiler-builtins-no-asm"]