mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Rollup merge of #104645 - yukiomoto:log-backtrace-option, r=oli-obk
Add log-backtrace option to show backtraces along with logging according to #90698, I added a compiler option, `-Zlog-backtrace=filter`, where `filter` is a module name, to show backtraces for logging without rebuilding. resolve #90698
This commit is contained in:
commit
96bb02f35c
@ -4273,6 +4273,7 @@ version = "0.0.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc_span",
|
"rustc_span",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
"tracing-core",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"tracing-tree",
|
"tracing-tree",
|
||||||
]
|
]
|
||||||
|
@ -231,6 +231,10 @@ fn run_compiler(
|
|||||||
registry: diagnostics_registry(),
|
registry: diagnostics_registry(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if !tracing::dispatcher::has_been_set() {
|
||||||
|
init_rustc_env_logger_with_backtrace_option(&config.opts.unstable_opts.log_backtrace);
|
||||||
|
}
|
||||||
|
|
||||||
match make_input(config.opts.error_format, &matches.free) {
|
match make_input(config.opts.error_format, &matches.free) {
|
||||||
Err(reported) => return Err(reported),
|
Err(reported) => return Err(reported),
|
||||||
Ok(Some((input, input_file_path))) => {
|
Ok(Some((input, input_file_path))) => {
|
||||||
@ -1300,7 +1304,14 @@ pub fn install_ice_hook() {
|
|||||||
/// This allows tools to enable rust logging without having to magically match rustc's
|
/// This allows tools to enable rust logging without having to magically match rustc's
|
||||||
/// tracing crate version.
|
/// tracing crate version.
|
||||||
pub fn init_rustc_env_logger() {
|
pub fn init_rustc_env_logger() {
|
||||||
if let Err(error) = rustc_log::init_rustc_env_logger() {
|
init_rustc_env_logger_with_backtrace_option(&None);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This allows tools to enable rust logging without having to magically match rustc's
|
||||||
|
/// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to
|
||||||
|
/// choose a target module you wish to show backtraces along with its logging.
|
||||||
|
pub fn init_rustc_env_logger_with_backtrace_option(backtrace_target: &Option<String>) {
|
||||||
|
if let Err(error) = rustc_log::init_rustc_env_logger_with_backtrace_option(backtrace_target) {
|
||||||
early_error(ErrorOutputType::default(), &error.to_string());
|
early_error(ErrorOutputType::default(), &error.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1366,7 +1377,6 @@ mod signal_handler {
|
|||||||
pub fn main() -> ! {
|
pub fn main() -> ! {
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
let start_rss = get_resident_set_size();
|
let start_rss = get_resident_set_size();
|
||||||
init_rustc_env_logger();
|
|
||||||
signal_handler::install();
|
signal_handler::install();
|
||||||
let mut callbacks = TimePassesCallbacks::default();
|
let mut callbacks = TimePassesCallbacks::default();
|
||||||
install_ice_hook();
|
install_ice_hook();
|
||||||
|
@ -748,6 +748,7 @@ fn test_unstable_options_tracking_hash() {
|
|||||||
tracked!(link_only, true);
|
tracked!(link_only, true);
|
||||||
tracked!(llvm_plugins, vec![String::from("plugin_name")]);
|
tracked!(llvm_plugins, vec![String::from("plugin_name")]);
|
||||||
tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
|
tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
|
||||||
|
tracked!(log_backtrace, Some("filter".to_string()));
|
||||||
tracked!(maximal_hir_to_mir_coverage, true);
|
tracked!(maximal_hir_to_mir_coverage, true);
|
||||||
tracked!(merge_functions, Some(MergeFunctions::Disabled));
|
tracked!(merge_functions, Some(MergeFunctions::Disabled));
|
||||||
tracked!(mir_emit_retag, true);
|
tracked!(mir_emit_retag, true);
|
||||||
|
@ -7,6 +7,7 @@ edition = "2021"
|
|||||||
tracing = "0.1.28"
|
tracing = "0.1.28"
|
||||||
tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
|
tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
|
||||||
tracing-tree = "0.2.0"
|
tracing-tree = "0.2.0"
|
||||||
|
tracing-core = "0.1.28"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rustc_span = { path = "../rustc_span" }
|
rustc_span = { path = "../rustc_span" }
|
||||||
|
@ -45,16 +45,34 @@
|
|||||||
use std::env::{self, VarError};
|
use std::env::{self, VarError};
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
use std::io::{self, IsTerminal};
|
use std::io::{self, IsTerminal};
|
||||||
|
use tracing_core::{Event, Subscriber};
|
||||||
use tracing_subscriber::filter::{Directive, EnvFilter, LevelFilter};
|
use tracing_subscriber::filter::{Directive, EnvFilter, LevelFilter};
|
||||||
|
use tracing_subscriber::fmt::{
|
||||||
|
format::{self, FormatEvent, FormatFields},
|
||||||
|
FmtContext,
|
||||||
|
};
|
||||||
use tracing_subscriber::layer::SubscriberExt;
|
use tracing_subscriber::layer::SubscriberExt;
|
||||||
|
|
||||||
pub fn init_rustc_env_logger() -> Result<(), Error> {
|
pub fn init_rustc_env_logger() -> Result<(), Error> {
|
||||||
init_env_logger("RUSTC_LOG")
|
init_rustc_env_logger_with_backtrace_option(&None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_rustc_env_logger_with_backtrace_option(
|
||||||
|
backtrace_target: &Option<String>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
init_env_logger_with_backtrace_option("RUSTC_LOG", backtrace_target)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// In contrast to `init_rustc_env_logger` this allows you to choose an env var
|
/// In contrast to `init_rustc_env_logger` this allows you to choose an env var
|
||||||
/// other than `RUSTC_LOG`.
|
/// other than `RUSTC_LOG`.
|
||||||
pub fn init_env_logger(env: &str) -> Result<(), Error> {
|
pub fn init_env_logger(env: &str) -> Result<(), Error> {
|
||||||
|
init_env_logger_with_backtrace_option(env, &None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_env_logger_with_backtrace_option(
|
||||||
|
env: &str,
|
||||||
|
backtrace_target: &Option<String>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
let filter = match env::var(env) {
|
let filter = match env::var(env) {
|
||||||
Ok(env) => EnvFilter::new(env),
|
Ok(env) => EnvFilter::new(env),
|
||||||
_ => EnvFilter::default().add_directive(Directive::from(LevelFilter::WARN)),
|
_ => EnvFilter::default().add_directive(Directive::from(LevelFilter::WARN)),
|
||||||
@ -88,11 +106,47 @@ pub fn init_env_logger(env: &str) -> Result<(), Error> {
|
|||||||
let layer = layer.with_thread_ids(true).with_thread_names(true);
|
let layer = layer.with_thread_ids(true).with_thread_names(true);
|
||||||
|
|
||||||
let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer);
|
let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer);
|
||||||
tracing::subscriber::set_global_default(subscriber).unwrap();
|
match backtrace_target {
|
||||||
|
Some(str) => {
|
||||||
|
let fmt_layer = tracing_subscriber::fmt::layer()
|
||||||
|
.with_writer(io::stderr)
|
||||||
|
.without_time()
|
||||||
|
.event_format(BacktraceFormatter { backtrace_target: str.to_string() });
|
||||||
|
let subscriber = subscriber.with(fmt_layer);
|
||||||
|
tracing::subscriber::set_global_default(subscriber).unwrap();
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
tracing::subscriber::set_global_default(subscriber).unwrap();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct BacktraceFormatter {
|
||||||
|
backtrace_target: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, N> FormatEvent<S, N> for BacktraceFormatter
|
||||||
|
where
|
||||||
|
S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>,
|
||||||
|
N: for<'a> FormatFields<'a> + 'static,
|
||||||
|
{
|
||||||
|
fn format_event(
|
||||||
|
&self,
|
||||||
|
_ctx: &FmtContext<'_, S, N>,
|
||||||
|
mut writer: format::Writer<'_>,
|
||||||
|
event: &Event<'_>,
|
||||||
|
) -> fmt::Result {
|
||||||
|
let target = event.metadata().target();
|
||||||
|
if !target.contains(&self.backtrace_target) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let backtrace = std::backtrace::Backtrace::capture();
|
||||||
|
writeln!(writer, "stack backtrace: \n{:?}", backtrace)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn stdout_isatty() -> bool {
|
pub fn stdout_isatty() -> bool {
|
||||||
io::stdout().is_terminal()
|
io::stdout().is_terminal()
|
||||||
}
|
}
|
||||||
|
@ -1411,6 +1411,8 @@ options! {
|
|||||||
"what location details should be tracked when using caller_location, either \
|
"what location details should be tracked when using caller_location, either \
|
||||||
`none`, or a comma separated list of location details, for which \
|
`none`, or a comma separated list of location details, for which \
|
||||||
valid options are `file`, `line`, and `column` (default: `file,line,column`)"),
|
valid options are `file`, `line`, and `column` (default: `file,line,column`)"),
|
||||||
|
log_backtrace: Option<String> = (None, parse_opt_string, [TRACKED],
|
||||||
|
"add a backtrace along with logging"),
|
||||||
ls: bool = (false, parse_bool, [UNTRACKED],
|
ls: bool = (false, parse_bool, [UNTRACKED],
|
||||||
"list the symbols defined by a library crate (default: no)"),
|
"list the symbols defined by a library crate (default: no)"),
|
||||||
macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
|
macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
-Z llvm-plugins=val -- a list LLVM plugins to enable (space separated)
|
-Z llvm-plugins=val -- a list LLVM plugins to enable (space separated)
|
||||||
-Z llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no)
|
-Z llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no)
|
||||||
-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`)
|
-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`)
|
||||||
|
-Z log-backtrace=val -- add a backtrace along with logging
|
||||||
-Z ls=val -- list the symbols defined by a library crate (default: no)
|
-Z ls=val -- list the symbols defined by a library crate (default: no)
|
||||||
-Z macro-backtrace=val -- show macro backtraces (default: no)
|
-Z macro-backtrace=val -- show macro backtraces (default: no)
|
||||||
-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)
|
-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)
|
||||||
|
9
tests/ui/attributes/log-backtrace.rs
Normal file
9
tests/ui/attributes/log-backtrace.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// run-pass
|
||||||
|
//
|
||||||
|
// This test makes sure that log-backtrace option doesn't give a compilation error.
|
||||||
|
//
|
||||||
|
// dont-check-compiler-stdout
|
||||||
|
// dont-check-compiler-stderr
|
||||||
|
// rustc-env:RUSTC_LOG=info
|
||||||
|
// compile-flags: -Zlog-backtrace=rustc_metadata::creader
|
||||||
|
fn main() {}
|
Loading…
Reference in New Issue
Block a user