Auto merge of #108938 - chenyukang:yukang/fix-107910-shorten-ice, r=cjgillot
Shorten backtraces for queries in ICEs r? `@jyn514` Fixes #107910
This commit is contained in:
commit
77c836e1ae
@ -488,6 +488,18 @@ macro_rules! expand_if_cached {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Don't show the backtrace for query system by default
|
||||||
|
/// use `RUST_BACKTRACE=full` to show all the backtraces
|
||||||
|
#[inline(never)]
|
||||||
|
pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
|
||||||
|
where
|
||||||
|
F: FnOnce() -> T,
|
||||||
|
{
|
||||||
|
let result = f();
|
||||||
|
std::hint::black_box(());
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros
|
// NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros
|
||||||
// invoked by `rustc_query_append`.
|
// invoked by `rustc_query_append`.
|
||||||
macro_rules! define_queries {
|
macro_rules! define_queries {
|
||||||
@ -498,9 +510,12 @@ mod get_query_incr {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
$(
|
$(
|
||||||
#[inline(always)]
|
// Adding `__rust_end_short_backtrace` marker to backtraces so that we emit the frames
|
||||||
#[tracing::instrument(level = "trace", skip(tcx))]
|
// when `RUST_BACKTRACE=1`, add a new mod with `$name` here is to allow duplicate naming
|
||||||
pub(super) fn $name<'tcx>(
|
pub mod $name {
|
||||||
|
use super::*;
|
||||||
|
#[inline(never)]
|
||||||
|
pub fn __rust_end_short_backtrace<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
key: query_keys::$name<'tcx>,
|
key: query_keys::$name<'tcx>,
|
||||||
@ -514,6 +529,7 @@ pub(super) fn $name<'tcx>(
|
|||||||
mode
|
mode
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -521,9 +537,10 @@ mod get_query_non_incr {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
$(
|
$(
|
||||||
#[inline(always)]
|
pub mod $name {
|
||||||
#[tracing::instrument(level = "trace", skip(tcx))]
|
use super::*;
|
||||||
pub(super) fn $name<'tcx>(
|
#[inline(never)]
|
||||||
|
pub fn __rust_end_short_backtrace<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
key: query_keys::$name<'tcx>,
|
key: query_keys::$name<'tcx>,
|
||||||
@ -536,17 +553,18 @@ pub(super) fn $name<'tcx>(
|
|||||||
key,
|
key,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn engine(incremental: bool) -> QueryEngine {
|
pub(crate) fn engine(incremental: bool) -> QueryEngine {
|
||||||
if incremental {
|
if incremental {
|
||||||
QueryEngine {
|
QueryEngine {
|
||||||
$($name: get_query_incr::$name,)*
|
$($name: get_query_incr::$name::__rust_end_short_backtrace,)*
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
QueryEngine {
|
QueryEngine {
|
||||||
$($name: get_query_non_incr::$name,)*
|
$($name: get_query_non_incr::$name::__rust_end_short_backtrace,)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -578,10 +596,15 @@ pub(super) fn $name<'tcx>() -> DynamicQuery<'tcx, query_storage::$name<'tcx>> {
|
|||||||
query_cache: offset_of!(QueryCaches<'tcx> => $name),
|
query_cache: offset_of!(QueryCaches<'tcx> => $name),
|
||||||
cache_on_disk: |tcx, key| ::rustc_middle::query::cached::$name(tcx, key),
|
cache_on_disk: |tcx, key| ::rustc_middle::query::cached::$name(tcx, key),
|
||||||
execute_query: |tcx, key| erase(tcx.$name(key)),
|
execute_query: |tcx, key| erase(tcx.$name(key)),
|
||||||
compute: |tcx, key| query_provided_to_value::$name(
|
compute: |tcx, key| {
|
||||||
|
use crate::plumbing::__rust_begin_short_backtrace;
|
||||||
|
__rust_begin_short_backtrace(||
|
||||||
|
query_provided_to_value::$name(
|
||||||
tcx,
|
tcx,
|
||||||
call_provider!([$($modifiers)*][tcx, $name, key])
|
call_provider!([$($modifiers)*][tcx, $name, key])
|
||||||
),
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
can_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] true false),
|
can_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] true false),
|
||||||
try_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] {
|
try_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] {
|
||||||
|tcx, key, prev_index, index| {
|
|tcx, key, prev_index, index| {
|
||||||
|
@ -68,13 +68,17 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut hit = false;
|
let mut hit = false;
|
||||||
let mut stop = false;
|
|
||||||
backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
|
backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
|
||||||
hit = true;
|
hit = true;
|
||||||
|
|
||||||
|
// Any frames between `__rust_begin_short_backtrace` and `__rust_end_short_backtrace`
|
||||||
|
// are omitted from the backtrace in short mode, `__rust_end_short_backtrace` will be
|
||||||
|
// called before the panic hook, so we won't ignore any frames if there is no
|
||||||
|
// invoke of `__rust_begin_short_backtrace`.
|
||||||
if print_fmt == PrintFmt::Short {
|
if print_fmt == PrintFmt::Short {
|
||||||
if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
|
if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
|
||||||
if start && sym.contains("__rust_begin_short_backtrace") {
|
if start && sym.contains("__rust_begin_short_backtrace") {
|
||||||
stop = true;
|
start = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if sym.contains("__rust_end_short_backtrace") {
|
if sym.contains("__rust_end_short_backtrace") {
|
||||||
@ -88,9 +92,6 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
|
|||||||
res = bt_fmt.frame().symbol(frame, symbol);
|
res = bt_fmt.frame().symbol(frame, symbol);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if stop {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#[cfg(target_os = "nto")]
|
#[cfg(target_os = "nto")]
|
||||||
if libc::__my_thread_exit as *mut libc::c_void == frame.ip() {
|
if libc::__my_thread_exit as *mut libc::c_void == frame.ip() {
|
||||||
if !hit && start {
|
if !hit && start {
|
||||||
|
9
tests/run-make/short-ice/Makefile
Normal file
9
tests/run-make/short-ice/Makefile
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
include ../tools.mk
|
||||||
|
|
||||||
|
# ignore-windows
|
||||||
|
|
||||||
|
export RUSTC := $(RUSTC_ORIGINAL)
|
||||||
|
export TMPDIR := $(TMPDIR)
|
||||||
|
|
||||||
|
all:
|
||||||
|
bash check.sh
|
36
tests/run-make/short-ice/check.sh
Normal file
36
tests/run-make/short-ice/check.sh
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
RUST_BACKTRACE=1 $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-1.log 2>&1
|
||||||
|
RUST_BACKTRACE=full $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-2.log 2>&1
|
||||||
|
|
||||||
|
short=$(cat $TMPDIR/rust-test-1.log | wc -l)
|
||||||
|
full=$(cat $TMPDIR/rust-test-2.log | wc -l)
|
||||||
|
rustc_query_count=$(cat $TMPDIR/rust-test-1.log | grep rustc_query_ | wc -l)
|
||||||
|
rustc_query_count_full=$(cat $TMPDIR/rust-test-2.log | grep rustc_query_ | wc -l)
|
||||||
|
|
||||||
|
begin_count=$(cat $TMPDIR/rust-test-2.log | grep __rust_begin_short_backtrace | wc -l)
|
||||||
|
end_count=$(cat $TMPDIR/rust-test-2.log | grep __rust_end_short_backtrace | wc -l)
|
||||||
|
|
||||||
|
cat $TMPDIR/rust-test-1.log
|
||||||
|
echo "====================="
|
||||||
|
cat $TMPDIR/rust-test-2.log
|
||||||
|
echo "====================="
|
||||||
|
|
||||||
|
echo "short backtrace: $short"
|
||||||
|
echo "full backtrace: $full"
|
||||||
|
echo "begin_count: $begin_count"
|
||||||
|
echo "end_count : $end_count"
|
||||||
|
echo "rustc_query_count: $rustc_query_count"
|
||||||
|
echo "rustc_query_count_full: $rustc_query_count_full"
|
||||||
|
|
||||||
|
## backtraces to vary a bit depending on platform and configuration options,
|
||||||
|
## here we make sure that the short backtrace of rustc_query is shorter than the full,
|
||||||
|
## and marks are in pairs.
|
||||||
|
if [ $short -lt $full ] &&
|
||||||
|
[ $begin_count -eq $end_count ] &&
|
||||||
|
[ $(($rustc_query_count + 10)) -lt $rustc_query_count_full ] &&
|
||||||
|
[ $rustc_query_count_full -gt 10 ]; then
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
7
tests/run-make/short-ice/src/lib.rs
Normal file
7
tests/run-make/short-ice/src/lib.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fn func(s: &str) {
|
||||||
|
println!("{}", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
func(1);
|
||||||
|
}
|
@ -8,6 +8,8 @@ LL | fn main() { missing_ident; }
|
|||||||
stack backtrace:
|
stack backtrace:
|
||||||
(end_short_backtrace)
|
(end_short_backtrace)
|
||||||
(begin_short_backtrace)
|
(begin_short_backtrace)
|
||||||
|
(end_short_backtrace)
|
||||||
|
(begin_short_backtrace)
|
||||||
|
|
||||||
error: the compiler unexpectedly panicked. this is a bug.
|
error: the compiler unexpectedly panicked. this is a bug.
|
||||||
|
|
||||||
|
61
tests/ui/panics/short-ice-remove-middle-frames-2.rs
Normal file
61
tests/ui/panics/short-ice-remove-middle-frames-2.rs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// compile-flags:-Cstrip=none
|
||||||
|
// run-fail
|
||||||
|
// check-run-results
|
||||||
|
// exec-env:RUST_BACKTRACE=1
|
||||||
|
// ignore-android FIXME #17520
|
||||||
|
// ignore-wasm no panic support
|
||||||
|
// ignore-openbsd no support for libbacktrace without filename
|
||||||
|
// ignore-emscripten no panic
|
||||||
|
// ignore-sgx Backtraces not symbolized
|
||||||
|
// ignore-fuchsia Backtraces not symbolized
|
||||||
|
// ignore-msvc the `__rust_{begin,end}_short_backtrace` symbols aren't reliable.
|
||||||
|
|
||||||
|
/// This test case make sure that we can have multiple pairs of `__rust_{begin,end}_short_backtrace`
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn __rust_begin_short_backtrace<T, F: FnOnce() -> T>(f: F) -> T {
|
||||||
|
let result = f();
|
||||||
|
std::hint::black_box(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn __rust_end_short_backtrace<T, F: FnOnce() -> T>(f: F) -> T {
|
||||||
|
let result = f();
|
||||||
|
std::hint::black_box(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn first() {
|
||||||
|
__rust_end_short_backtrace(|| second());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn second() {
|
||||||
|
third(); // won't show up
|
||||||
|
}
|
||||||
|
|
||||||
|
fn third() {
|
||||||
|
fourth(); // won't show up
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fourth() {
|
||||||
|
__rust_begin_short_backtrace(|| fifth());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fifth() {
|
||||||
|
__rust_end_short_backtrace(|| sixth());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sixth() {
|
||||||
|
seven(); // won't show up
|
||||||
|
}
|
||||||
|
|
||||||
|
fn seven() {
|
||||||
|
__rust_begin_short_backtrace(|| eight());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eight() {
|
||||||
|
panic!("debug!!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
first();
|
||||||
|
}
|
11
tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
Normal file
11
tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
thread 'main' panicked at 'debug!!!', $DIR/short-ice-remove-middle-frames-2.rs:56:5
|
||||||
|
stack backtrace:
|
||||||
|
0: std::panicking::begin_panic
|
||||||
|
1: short_ice_remove_middle_frames_2::eight
|
||||||
|
2: short_ice_remove_middle_frames_2::seven::{{closure}}
|
||||||
|
3: short_ice_remove_middle_frames_2::fifth
|
||||||
|
4: short_ice_remove_middle_frames_2::fourth::{{closure}}
|
||||||
|
5: short_ice_remove_middle_frames_2::first
|
||||||
|
6: short_ice_remove_middle_frames_2::main
|
||||||
|
7: core::ops::function::FnOnce::call_once
|
||||||
|
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
|
57
tests/ui/panics/short-ice-remove-middle-frames.rs
Normal file
57
tests/ui/panics/short-ice-remove-middle-frames.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// compile-flags:-Cstrip=none
|
||||||
|
// run-fail
|
||||||
|
// check-run-results
|
||||||
|
// exec-env:RUST_BACKTRACE=1
|
||||||
|
// ignore-android FIXME #17520
|
||||||
|
// ignore-wasm no panic support
|
||||||
|
// ignore-openbsd no support for libbacktrace without filename
|
||||||
|
// ignore-emscripten no panic
|
||||||
|
// ignore-sgx Backtraces not symbolized
|
||||||
|
// ignore-fuchsia Backtraces not symbolized
|
||||||
|
// ignore-msvc the `__rust_{begin,end}_short_backtrace` symbols aren't reliable.
|
||||||
|
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn __rust_begin_short_backtrace<T, F: FnOnce() -> T>(f: F) -> T {
|
||||||
|
let result = f();
|
||||||
|
std::hint::black_box(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn __rust_end_short_backtrace<T, F: FnOnce() -> T>(f: F) -> T {
|
||||||
|
let result = f();
|
||||||
|
std::hint::black_box(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn first() {
|
||||||
|
__rust_end_short_backtrace(|| second());
|
||||||
|
// do not take effect since we already has a inner call of __rust_end_short_backtrace
|
||||||
|
}
|
||||||
|
|
||||||
|
fn second() {
|
||||||
|
__rust_end_short_backtrace(|| third());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn third() {
|
||||||
|
fourth(); // won't show up in backtrace
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fourth() {
|
||||||
|
fifth(); // won't show up in backtrace
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fifth() {
|
||||||
|
__rust_begin_short_backtrace(|| sixth());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sixth() {
|
||||||
|
seven();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn seven() {
|
||||||
|
panic!("debug!!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
first();
|
||||||
|
}
|
12
tests/ui/panics/short-ice-remove-middle-frames.run.stderr
Normal file
12
tests/ui/panics/short-ice-remove-middle-frames.run.stderr
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
thread 'main' panicked at 'debug!!!', $DIR/short-ice-remove-middle-frames.rs:52:5
|
||||||
|
stack backtrace:
|
||||||
|
0: std::panicking::begin_panic
|
||||||
|
1: short_ice_remove_middle_frames::seven
|
||||||
|
2: short_ice_remove_middle_frames::sixth
|
||||||
|
3: short_ice_remove_middle_frames::fifth::{{closure}}
|
||||||
|
4: short_ice_remove_middle_frames::second
|
||||||
|
5: short_ice_remove_middle_frames::first::{{closure}}
|
||||||
|
6: short_ice_remove_middle_frames::first
|
||||||
|
7: short_ice_remove_middle_frames::main
|
||||||
|
8: core::ops::function::FnOnce::call_once
|
||||||
|
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
|
Loading…
Reference in New Issue
Block a user