From a9a1393cbff49bbba9e83aa164ef208485579f92 Mon Sep 17 00:00:00 2001 From: Hudson Ayers Date: Wed, 13 Oct 2021 17:01:31 -0700 Subject: [PATCH 1/4] Add -Z location-detail flag --- compiler/rustc_session/src/config.rs | 17 ++++++++++++++++- compiler/rustc_session/src/options.rs | 24 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index ac4bce7350b90..299dfed9d5dce 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -174,6 +174,20 @@ impl LinkerPluginLto { } } +/// The different settings that can be enabled via the `-Z location-detail` flag. +#[derive(Clone, PartialEq, Hash, Debug)] +pub struct LocationDetail { + pub file: bool, + pub line: bool, + pub column: bool, +} + +impl LocationDetail { + pub fn all() -> Self { + Self { file: true, line: true, column: true } + } +} + #[derive(Clone, PartialEq, Hash, Debug)] pub enum SwitchWithOptPath { Enabled(Option), @@ -2422,7 +2436,7 @@ crate mod dep_tracking { use super::LdImpl; use super::{ CFGuard, CrateType, DebugInfo, ErrorOutputType, InstrumentCoverage, LinkerPluginLto, - LtoCli, OptLevel, OutputType, OutputTypes, Passes, SourceFileHashAlgorithm, + LocationDetail, LtoCli, OptLevel, OutputType, OutputTypes, Passes, SourceFileHashAlgorithm, SwitchWithOptPath, SymbolManglingVersion, TrimmedDefPaths, }; use crate::lint; @@ -2513,6 +2527,7 @@ crate mod dep_tracking { Option, OutputType, RealFileName, + LocationDetail, ); impl DepTrackingHash for (T1, T2) diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index b3d36b396c51c..0bc868234afb1 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -368,6 +368,8 @@ mod desc { "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted"; pub const parse_linker_plugin_lto: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or the path to the linker plugin"; + pub const parse_location_detail: &str = + "comma seperated list of location details to track: `file`, `line`, or `column`"; pub const parse_switch_with_opt_path: &str = "an optional path to the profiling data output directory"; pub const parse_merge_functions: &str = "one of: `disabled`, `trampolines`, or `aliases`"; @@ -484,6 +486,25 @@ mod parse { } } + crate fn parse_location_detail(ld: &mut LocationDetail, v: Option<&str>) -> bool { + if let Some(v) = v { + ld.line = false; + ld.file = false; + ld.column = false; + for s in v.split(',') { + match s { + "file" => ld.file = true, + "line" => ld.line = true, + "column" => ld.column = true, + _ => return false, + } + } + true + } else { + false + } + } + crate fn parse_opt_comma_list(slot: &mut Option>, v: Option<&str>) -> bool { match v { Some(s) => { @@ -1152,6 +1173,9 @@ options! { "a list LLVM plugins to enable (space separated)"), llvm_time_trace: bool = (false, parse_bool, [UNTRACKED], "generate JSON tracing data file from LLVM data (default: no)"), + location_detail: LocationDetail = (LocationDetail::all(), parse_location_detail, [TRACKED], + "comma seperated list of location details to be tracked when using caller_location \ + valid options are `file`, `line`, and `column` (default: all)"), ls: bool = (false, parse_bool, [UNTRACKED], "list the symbols defined by a library crate (default: no)"), macro_backtrace: bool = (false, parse_bool, [UNTRACKED], From e1d94b8fd1ca1a1de6a56a3c53bb105fefacdd9c Mon Sep 17 00:00:00 2001 From: Hudson Ayers Date: Thu, 14 Oct 2021 09:20:32 -0700 Subject: [PATCH 2/4] Configure saved panic locations based on location-detail flag --- .../src/interpret/intrinsics/caller_location.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs index d4cbba1802931..b5e97ec8fe0f4 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs @@ -80,10 +80,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { line: u32, col: u32, ) -> MPlaceTy<'tcx, M::PointerTag> { - let file = - self.allocate_str(&filename.as_str(), MemoryKind::CallerLocation, Mutability::Not); - let line = Scalar::from_u32(line); - let col = Scalar::from_u32(col); + let loc_details = &self.tcx.sess.opts.debugging_opts.location_detail; + let file = if loc_details.file { + self.allocate_str(&filename.as_str(), MemoryKind::CallerLocation, Mutability::Not) + } else { + // FIXME: This creates a new allocation each time. It might be preferable to + // perform this allocation only once, and re-use the `MPlaceTy`. + // See https://github.com/rust-lang/rust/pull/89920#discussion_r730012398 + self.allocate_str("", MemoryKind::CallerLocation, Mutability::Not) + }; + let line = if loc_details.line { Scalar::from_u32(line) } else { Scalar::from_u32(0) }; + let col = if loc_details.column { Scalar::from_u32(col) } else { Scalar::from_u32(0) }; // Allocate memory for `CallerLocation` struct. let loc_ty = self From 8090f67fb7abc459b24eaa87a5309ed49ed96866 Mon Sep 17 00:00:00 2001 From: Hudson Ayers Date: Thu, 14 Oct 2021 10:46:07 -0700 Subject: [PATCH 3/4] document the unstable location-detail flag --- .../src/compiler-flags/location-detail.md | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/doc/unstable-book/src/compiler-flags/location-detail.md diff --git a/src/doc/unstable-book/src/compiler-flags/location-detail.md b/src/doc/unstable-book/src/compiler-flags/location-detail.md new file mode 100644 index 0000000000000..08d937cc28200 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/location-detail.md @@ -0,0 +1,43 @@ +# `location-detail` + +The tracking issue for this feature is: [#70580](https://github.com/rust-lang/rust/issues/70580). + +------------------------ + +Option `-Z location-detail=val` controls what location details are tracked when +using `caller_location`. This allows users to control what location details +are printed as part of panic messages, by allowing them to exclude any combination +of filenames, line numbers, and column numbers. This option is intended to provide +users with a way to mitigate the size impact of `#[track_caller]`. + +This option supports a comma separated list of location details to be included. Valid options +within this list are: + +- `file` - the filename of the panic will be included in the panic output +- `line` - the source line of the panic will be included in the panic output +- `column` - the source column of the panic will be included in the panic output + +Any combination of these three options are supported. If this option is not specified, +all three are included by default. + +An example of a panic output when using `-Z location-detail=line`: +```text +panicked at 'Process blink had a fault', :323:0 +``` + +The code size savings from this option are two-fold. First, the `&'static str` values +for each path to a file containing a panic are removed from the binary. For projects +with deep directory structures and many files with panics, this can add up. This category +of savings can only be realized by excluding filenames from the panic output. Second, +savings can be realized by allowing multiple panics to be fused into a single panicking +branch. It is often the case that within a single file, multiple panics with the same +panic message exist -- e.g. two calls to `Option::unwrap()` in a single line, or +two calls to `Result::expect()` on adjacent lines. If column and line information +are included in the `Location` struct passed to the panic handler, these branches cannot +be fused, as the output is different depending on which panic occurs. However if line +and column information is identical for all panics, these branches can be fused, which +can lead to substantial code size savings, especially for small embedded binaries with +many panics. + +The savings from this option are amplified when combined with the use of `-Zbuild-std`, as +otherwise paths for panics within the standard library are still included in your binary. From b802629311ee9873978e91f185657fd6ae3cba28 Mon Sep 17 00:00:00 2001 From: Hudson Ayers Date: Fri, 15 Oct 2021 08:58:28 -0700 Subject: [PATCH 4/4] add tests for -Zlocation-detail --- compiler/rustc_interface/src/tests.rs | 5 ++++- src/test/ui/panics/location-detail-panic-no-column.rs | 7 +++++++ .../ui/panics/location-detail-panic-no-column.run.stderr | 2 ++ src/test/ui/panics/location-detail-panic-no-file.rs | 7 +++++++ .../ui/panics/location-detail-panic-no-file.run.stderr | 2 ++ src/test/ui/panics/location-detail-panic-no-line.rs | 7 +++++++ .../ui/panics/location-detail-panic-no-line.run.stderr | 2 ++ src/test/ui/panics/location-detail-unwrap-no-file.rs | 8 ++++++++ .../ui/panics/location-detail-unwrap-no-file.run.stderr | 2 ++ 9 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/panics/location-detail-panic-no-column.rs create mode 100644 src/test/ui/panics/location-detail-panic-no-column.run.stderr create mode 100644 src/test/ui/panics/location-detail-panic-no-file.rs create mode 100644 src/test/ui/panics/location-detail-panic-no-file.run.stderr create mode 100644 src/test/ui/panics/location-detail-panic-no-line.rs create mode 100644 src/test/ui/panics/location-detail-panic-no-line.run.stderr create mode 100644 src/test/ui/panics/location-detail-unwrap-no-file.rs create mode 100644 src/test/ui/panics/location-detail-unwrap-no-file.run.stderr diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 844e5ab56a420..dab4d485e2d0b 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -5,7 +5,9 @@ use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig}; use rustc_session::config::InstrumentCoverage; use rustc_session::config::Strip; use rustc_session::config::{build_configuration, build_session_options, to_crate_config}; -use rustc_session::config::{rustc_optgroups, ErrorOutputType, ExternLocation, Options, Passes}; +use rustc_session::config::{ + rustc_optgroups, ErrorOutputType, ExternLocation, LocationDetail, Options, Passes, +}; use rustc_session::config::{CFGuard, ExternEntry, LinkerPluginLto, LtoCli, SwitchWithOptPath}; use rustc_session::config::{ Externs, OutputType, OutputTypes, SymbolManglingVersion, WasiExecModel, @@ -733,6 +735,7 @@ fn test_debugging_options_tracking_hash() { tracked!(instrument_mcount, true); tracked!(link_only, true); tracked!(llvm_plugins, vec![String::from("plugin_name")]); + tracked!(location_detail, LocationDetail { file: true, line: false, column: false }); tracked!(merge_functions, Some(MergeFunctions::Disabled)); tracked!(mir_emit_retag, true); tracked!(mir_opt_level, Some(4)); diff --git a/src/test/ui/panics/location-detail-panic-no-column.rs b/src/test/ui/panics/location-detail-panic-no-column.rs new file mode 100644 index 0000000000000..673e638ca0d6b --- /dev/null +++ b/src/test/ui/panics/location-detail-panic-no-column.rs @@ -0,0 +1,7 @@ +// run-fail +// check-run-results +// compile-flags: -Zlocation-detail=line,file + +fn main() { + panic!("column-redacted"); +} diff --git a/src/test/ui/panics/location-detail-panic-no-column.run.stderr b/src/test/ui/panics/location-detail-panic-no-column.run.stderr new file mode 100644 index 0000000000000..9f35623fba392 --- /dev/null +++ b/src/test/ui/panics/location-detail-panic-no-column.run.stderr @@ -0,0 +1,2 @@ +thread 'main' panicked at 'column-redacted', $DIR/location-detail-panic-no-column.rs:6:0 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/src/test/ui/panics/location-detail-panic-no-file.rs b/src/test/ui/panics/location-detail-panic-no-file.rs new file mode 100644 index 0000000000000..0e5d52cfd1534 --- /dev/null +++ b/src/test/ui/panics/location-detail-panic-no-file.rs @@ -0,0 +1,7 @@ +// run-fail +// check-run-results +// compile-flags: -Zlocation-detail=line,column + +fn main() { + panic!("file-redacted"); +} diff --git a/src/test/ui/panics/location-detail-panic-no-file.run.stderr b/src/test/ui/panics/location-detail-panic-no-file.run.stderr new file mode 100644 index 0000000000000..1e07e3a07afd5 --- /dev/null +++ b/src/test/ui/panics/location-detail-panic-no-file.run.stderr @@ -0,0 +1,2 @@ +thread 'main' panicked at 'file-redacted', :6:5 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/src/test/ui/panics/location-detail-panic-no-line.rs b/src/test/ui/panics/location-detail-panic-no-line.rs new file mode 100644 index 0000000000000..57f6d0ebcb9fa --- /dev/null +++ b/src/test/ui/panics/location-detail-panic-no-line.rs @@ -0,0 +1,7 @@ +// run-fail +// check-run-results +// compile-flags: -Zlocation-detail=file,column + +fn main() { + panic!("line-redacted"); +} diff --git a/src/test/ui/panics/location-detail-panic-no-line.run.stderr b/src/test/ui/panics/location-detail-panic-no-line.run.stderr new file mode 100644 index 0000000000000..cc3f1624c49ab --- /dev/null +++ b/src/test/ui/panics/location-detail-panic-no-line.run.stderr @@ -0,0 +1,2 @@ +thread 'main' panicked at 'line-redacted', $DIR/location-detail-panic-no-line.rs:0:5 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/src/test/ui/panics/location-detail-unwrap-no-file.rs b/src/test/ui/panics/location-detail-unwrap-no-file.rs new file mode 100644 index 0000000000000..d7f96f058e082 --- /dev/null +++ b/src/test/ui/panics/location-detail-unwrap-no-file.rs @@ -0,0 +1,8 @@ +// run-fail +// check-run-results +// compile-flags: -Zlocation-detail=line,column + +fn main() { + let opt: Option = None; + opt.unwrap(); +} diff --git a/src/test/ui/panics/location-detail-unwrap-no-file.run.stderr b/src/test/ui/panics/location-detail-unwrap-no-file.run.stderr new file mode 100644 index 0000000000000..f8f84b5c49a22 --- /dev/null +++ b/src/test/ui/panics/location-detail-unwrap-no-file.run.stderr @@ -0,0 +1,2 @@ +thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', :7:9 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace