Skip to content

Commit 4e2a356

Browse files
committedJan 11, 2023
Add log-backtrace option to show backtraces along with logging
1 parent 1e4f900 commit 4e2a356

File tree

8 files changed

+83
-4
lines changed

8 files changed

+83
-4
lines changed
 

‎Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4273,6 +4273,7 @@ version = "0.0.0"
42734273
dependencies = [
42744274
"rustc_span",
42754275
"tracing",
4276+
"tracing-core",
42764277
"tracing-subscriber",
42774278
"tracing-tree",
42784279
]

‎compiler/rustc_driver/src/lib.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ fn run_compiler(
231231
registry: diagnostics_registry(),
232232
};
233233

234+
if !tracing::dispatcher::has_been_set() {
235+
init_rustc_env_logger_with_backtrace_option(&config.opts.unstable_opts.log_backtrace);
236+
}
237+
234238
match make_input(config.opts.error_format, &matches.free) {
235239
Err(reported) => return Err(reported),
236240
Ok(Some((input, input_file_path))) => {
@@ -1299,7 +1303,14 @@ pub fn install_ice_hook() {
12991303
/// This allows tools to enable rust logging without having to magically match rustc's
13001304
/// tracing crate version.
13011305
pub fn init_rustc_env_logger() {
1302-
if let Err(error) = rustc_log::init_rustc_env_logger() {
1306+
init_rustc_env_logger_with_backtrace_option(&None);
1307+
}
1308+
1309+
/// This allows tools to enable rust logging without having to magically match rustc's
1310+
/// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to
1311+
/// choose a target module you wish to show backtraces along with its logging.
1312+
pub fn init_rustc_env_logger_with_backtrace_option(backtrace_target: &Option<String>) {
1313+
if let Err(error) = rustc_log::init_rustc_env_logger_with_backtrace_option(backtrace_target) {
13031314
early_error(ErrorOutputType::default(), &error.to_string());
13041315
}
13051316
}
@@ -1365,7 +1376,6 @@ mod signal_handler {
13651376
pub fn main() -> ! {
13661377
let start_time = Instant::now();
13671378
let start_rss = get_resident_set_size();
1368-
init_rustc_env_logger();
13691379
signal_handler::install();
13701380
let mut callbacks = TimePassesCallbacks::default();
13711381
install_ice_hook();

‎compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,7 @@ fn test_unstable_options_tracking_hash() {
748748
tracked!(link_only, true);
749749
tracked!(llvm_plugins, vec![String::from("plugin_name")]);
750750
tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
751+
tracked!(log_backtrace, Some("filter".to_string()));
751752
tracked!(maximal_hir_to_mir_coverage, true);
752753
tracked!(merge_functions, Some(MergeFunctions::Disabled));
753754
tracked!(mir_emit_retag, true);

‎compiler/rustc_log/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ edition = "2021"
77
tracing = "0.1.28"
88
tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
99
tracing-tree = "0.2.0"
10+
tracing-core = "0.1.28"
1011

1112
[dev-dependencies]
1213
rustc_span = { path = "../rustc_span" }

‎compiler/rustc_log/src/lib.rs

+56-2
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,34 @@
4545
use std::env::{self, VarError};
4646
use std::fmt::{self, Display};
4747
use std::io::{self, IsTerminal};
48+
use tracing_core::{Event, Subscriber};
4849
use tracing_subscriber::filter::{Directive, EnvFilter, LevelFilter};
50+
use tracing_subscriber::fmt::{
51+
format::{self, FormatEvent, FormatFields},
52+
FmtContext,
53+
};
4954
use tracing_subscriber::layer::SubscriberExt;
5055

5156
pub fn init_rustc_env_logger() -> Result<(), Error> {
52-
init_env_logger("RUSTC_LOG")
57+
init_rustc_env_logger_with_backtrace_option(&None)
58+
}
59+
60+
pub fn init_rustc_env_logger_with_backtrace_option(
61+
backtrace_target: &Option<String>,
62+
) -> Result<(), Error> {
63+
init_env_logger_with_backtrace_option("RUSTC_LOG", backtrace_target)
5364
}
5465

5566
/// In contrast to `init_rustc_env_logger` this allows you to choose an env var
5667
/// other than `RUSTC_LOG`.
5768
pub fn init_env_logger(env: &str) -> Result<(), Error> {
69+
init_env_logger_with_backtrace_option(env, &None)
70+
}
71+
72+
pub fn init_env_logger_with_backtrace_option(
73+
env: &str,
74+
backtrace_target: &Option<String>,
75+
) -> Result<(), Error> {
5876
let filter = match env::var(env) {
5977
Ok(env) => EnvFilter::new(env),
6078
_ => EnvFilter::default().add_directive(Directive::from(LevelFilter::WARN)),
@@ -88,11 +106,47 @@ pub fn init_env_logger(env: &str) -> Result<(), Error> {
88106
let layer = layer.with_thread_ids(true).with_thread_names(true);
89107

90108
let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer);
91-
tracing::subscriber::set_global_default(subscriber).unwrap();
109+
match backtrace_target {
110+
Some(str) => {
111+
let fmt_layer = tracing_subscriber::fmt::layer()
112+
.with_writer(io::stderr)
113+
.without_time()
114+
.event_format(BacktraceFormatter { backtrace_target: str.to_string() });
115+
let subscriber = subscriber.with(fmt_layer);
116+
tracing::subscriber::set_global_default(subscriber).unwrap();
117+
}
118+
None => {
119+
tracing::subscriber::set_global_default(subscriber).unwrap();
120+
}
121+
};
92122

93123
Ok(())
94124
}
95125

126+
struct BacktraceFormatter {
127+
backtrace_target: String,
128+
}
129+
130+
impl<S, N> FormatEvent<S, N> for BacktraceFormatter
131+
where
132+
S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>,
133+
N: for<'a> FormatFields<'a> + 'static,
134+
{
135+
fn format_event(
136+
&self,
137+
_ctx: &FmtContext<'_, S, N>,
138+
mut writer: format::Writer<'_>,
139+
event: &Event<'_>,
140+
) -> fmt::Result {
141+
let target = event.metadata().target();
142+
if !target.contains(&self.backtrace_target) {
143+
return Ok(());
144+
}
145+
let backtrace = std::backtrace::Backtrace::capture();
146+
writeln!(writer, "stack backtrace: \n{:?}", backtrace)
147+
}
148+
}
149+
96150
pub fn stdout_isatty() -> bool {
97151
io::stdout().is_terminal()
98152
}

‎compiler/rustc_session/src/options.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,8 @@ options! {
14111411
"what location details should be tracked when using caller_location, either \
14121412
`none`, or a comma separated list of location details, for which \
14131413
valid options are `file`, `line`, and `column` (default: `file,line,column`)"),
1414+
log_backtrace: Option<String> = (None, parse_opt_string, [TRACKED],
1415+
"add a backtrace along with logging"),
14141416
ls: bool = (false, parse_bool, [UNTRACKED],
14151417
"list the symbols defined by a library crate (default: no)"),
14161418
macro_backtrace: bool = (false, parse_bool, [UNTRACKED],

‎tests/rustdoc-ui/z-help.stdout

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
-Z llvm-plugins=val -- a list LLVM plugins to enable (space separated)
7777
-Z llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no)
7878
-Z location-detail=val -- what location details should be tracked when using caller_location, either `none`, or a comma separated list of location details, for which valid options are `file`, `line`, and `column` (default: `file,line,column`)
79+
-Z log-backtrace=val -- add a backtrace along with logging
7980
-Z ls=val -- list the symbols defined by a library crate (default: no)
8081
-Z macro-backtrace=val -- show macro backtraces (default: no)
8182
-Z maximal-hir-to-mir-coverage=val -- save as much information as possible about the correspondence between MIR and HIR as source scopes (default: no)

‎tests/ui/attributes/log-backtrace.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// run-pass
2+
//
3+
// This test makes sure that log-backtrace option doesn't give a compilation error.
4+
//
5+
// dont-check-compiler-stdout
6+
// dont-check-compiler-stderr
7+
// rustc-env:RUSTC_LOG=info
8+
// compile-flags: -Zlog-backtrace=rustc_metadata::creader
9+
fn main() {}

0 commit comments

Comments
 (0)
Please sign in to comment.