Skip to content

Add experimental backtrace-trace-only std feature #143910

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 15, 2025

Conversation

ChrisDenton
Copy link
Member

@ChrisDenton ChrisDenton commented Jul 13, 2025

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:

# .cargo/config.toml
[unstable]
build-std = ["core", "alloc", "panic_unwind", "std"]
build-std-features = ["backtrace", "backtrace-trace-only", "panic-unwind"]
# 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

@rustbot
Copy link
Collaborator

rustbot commented Jul 13, 2025

r? @tgross35

rustbot has assigned @tgross35.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jul 13, 2025
@ChrisDenton ChrisDenton force-pushed the no-symbolization branch 4 times, most recently from f7963bb to 1dccc65 Compare July 14, 2025 01:28
@ChrisDenton
Copy link
Member Author

A quick test on an empty bin project does shows a fairly substantial difference in final binary size (exact numbers may vary of course):

platform symbolize trace only diff
Linux 426 KiB 123 KiB 303 KiB
Windows 125 KiB 70 KiB 55 KiB

@tgross35
Copy link
Contributor

Two comments then r=me

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.

Any idea why we don't have a default feature in std? If we did it would make this change a bit easier. I assume probably something related to bootstrap / config options.

@@ -92,6 +92,7 @@ backtrace = [
'object/rustc-dep-of-std',
'miniz_oxide/rustc-dep-of-std',
]
backtrace-trace-only = []
Copy link
Member

@bjorn3 bjorn3 Jul 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will still compile addr2line, gimli and object. Maybe instead have a feature to enable just backtraces and then another feature which enables this feature and in addition enables backtrace symbolication.
Edit: You already suggested that in the PR description.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, doing this fully will require making changes to backtrace-rs, which I'm trying to avoid for the initial implementation. Also, although it's unstable, I don't want to break people currently using build-std-features just yet.

if cfg!(feature = "backtrace-trace-only") {
const HEX_WIDTH: usize = 2 + 2 * core::mem::size_of::<usize>();
let frame_ip = frame.ip();
res = writeln!(bt_fmt.formatter(), "{idx:4}: {frame_ip:HEX_WIDTH$?}");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be able to actually symbolize the backtraces this would need to print both the path of the DSO (executable or dylib) and the offset within this DSO. It could be a dylib loaded at runtime and thanks to ASLR the exact location of DSOs can't be determined anymore after the fact unless we print it here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could take inspiration on what backtrace-rs does on Fuchsia which unconditionally does backtrace symbolication out of process.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this work normally when symbols aren't available? The backtrace is just unusable?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't think the backtraces are all that usable without symbols when ASLR is disabled. I guess it still shows symbol names for system libraries.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'm going to punt on doing the hard thing again 🙂. This is (arguably) a pre-existing issue and at least somewhat platform specific so would be much better fixed in backtrace-rs than std. This feature can then use whatever backtrace-rs has once that's written.

@hanna-kruppe
Copy link
Contributor

cc #139209

@ChrisDenton
Copy link
Member Author

Any idea why we don't have a default feature in std? If we did it would make this change a bit easier. I assume probably something related to bootstrap / config options.

I've no idea tbh.

I'd note that designing a build-std MVP suitable for stabilisation is now a project goal, which is likely to bring changes to how it all works. Another reason not to be too disruptive at this point.

@ChrisDenton
Copy link
Member Author

@bors r=tgross35 rollup

@bors
Copy link
Collaborator

bors commented Jul 14, 2025

📌 Commit 9fd3886 has been approved by tgross35

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 14, 2025
Kobzol added a commit to Kobzol/rust that referenced this pull request Jul 14, 2025
…ross35

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`
jhpratt added a commit to jhpratt/rust that referenced this pull request Jul 15, 2025
…ross35

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``
bors added a commit that referenced this pull request Jul 15, 2025
Rollup of 16 pull requests

Successful merges:

 - #142301 (tests: Fix duplicated-path-in-error fail with musl)
 - #142936 (rustdoc-json: Structured attributes)
 - #143355 (wrapping shift: remove first bitmask and table)
 - #143630 (Drop `./x suggest`)
 - #143738 (Move several float tests to floats/mod.rs)
 - #143752 (Don't panic if WASI_SDK_PATH not set when detecting compiler)
 - #143820 (Fixed a core crate compilation failure when enabling the `optimize_for_size` feature on some targets)
 - #143837 (Adjust `run_make_support::symbols` helpers)
 - #143878 (Port `#[pointee]` to the new attribute parsing infrastructure)
 - #143907 (core: make `str::split_at_unchecked()` inline)
 - #143910 (Add experimental `backtrace-trace-only` std feature)
 - #143927 (Preserve constness in trait objects up to hir ty lowering)
 - #143935 (rustc_type_ir/walk: move docstring to `TypeWalker` itself)
 - #143938 (Update books)
 - #143941 (update `cfg_select!` documentation)
 - #143948 (Update mdbook to 0.4.52)

Failed merges:

 - #143926 (Remove deprecated fields in bootstrap)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit that referenced this pull request Jul 15, 2025
Rollup of 16 pull requests

Successful merges:

 - #142301 (tests: Fix duplicated-path-in-error fail with musl)
 - #142936 (rustdoc-json: Structured attributes)
 - #143355 (wrapping shift: remove first bitmask and table)
 - #143630 (Drop `./x suggest`)
 - #143738 (Move several float tests to floats/mod.rs)
 - #143752 (Don't panic if WASI_SDK_PATH not set when detecting compiler)
 - #143820 (Fixed a core crate compilation failure when enabling the `optimize_for_size` feature on some targets)
 - #143837 (Adjust `run_make_support::symbols` helpers)
 - #143878 (Port `#[pointee]` to the new attribute parsing infrastructure)
 - #143907 (core: make `str::split_at_unchecked()` inline)
 - #143910 (Add experimental `backtrace-trace-only` std feature)
 - #143927 (Preserve constness in trait objects up to hir ty lowering)
 - #143935 (rustc_type_ir/walk: move docstring to `TypeWalker` itself)
 - #143938 (Update books)
 - #143941 (update `cfg_select!` documentation)
 - #143948 (Update mdbook to 0.4.52)

Failed merges:

 - #143926 (Remove deprecated fields in bootstrap)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit that referenced this pull request Jul 15, 2025
Rollup of 13 pull requests

Successful merges:

 - #142301 (tests: Fix duplicated-path-in-error fail with musl)
 - #143630 (Drop `./x suggest`)
 - #143736 (Give all bytes of TypeId provenance)
 - #143752 (Don't panic if WASI_SDK_PATH not set when detecting compiler)
 - #143837 (Adjust `run_make_support::symbols` helpers)
 - #143878 (Port `#[pointee]` to the new attribute parsing infrastructure)
 - #143905 (Recover and suggest to use `;` to construct array type)
 - #143907 (core: make `str::split_at_unchecked()` inline)
 - #143910 (Add experimental `backtrace-trace-only` std feature)
 - #143927 (Preserve constness in trait objects up to hir ty lowering)
 - #143935 (rustc_type_ir/walk: move docstring to `TypeWalker` itself)
 - #143938 (Update books)
 - #143941 (update `cfg_select!` documentation)

Failed merges:

 - #143926 (Remove deprecated fields in bootstrap)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 2e37e24 into rust-lang:master Jul 15, 2025
11 checks passed
@rustbot rustbot added this to the 1.90.0 milestone Jul 15, 2025
rust-timer added a commit that referenced this pull request Jul 15, 2025
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``
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants