mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Auto merge of #91742 - cjgillot:force-backtrace, r=estebank
Print a backtrace when query forcing fails. The aim of this PR is to help debugging incremental compilation bugs where query forcing panics. For instance: https://github.com/rust-lang/rust/issues/90682 https://github.com/rust-lang/rust/issues/90697 https://github.com/rust-lang/rust/issues/90715 https://github.com/rust-lang/rust/issues/90739 https://github.com/rust-lang/rust/issues/91401 These bugs happen when the dep-graph attempts to force a dep-node whose fingerprint does not correspond to an actual DefPathHash. PR https://github.com/rust-lang/rust/pull/91741 attempts to hide this bug. I still don't know how to reproduce these bugs, so I sadly could not test this debugging device.
This commit is contained in:
commit
f0bc76ac41
@ -6,6 +6,7 @@ use rustc_data_structures::sharded::{self, Sharded};
|
|||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_data_structures::steal::Steal;
|
use rustc_data_structures::steal::Steal;
|
||||||
use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering};
|
use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering};
|
||||||
|
use rustc_data_structures::OnDrop;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
|
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
@ -671,17 +672,24 @@ impl<K: DepKind> DepGraph<K> {
|
|||||||
let prev_index = data.previous.node_to_index_opt(dep_node)?;
|
let prev_index = data.previous.node_to_index_opt(dep_node)?;
|
||||||
|
|
||||||
match data.colors.get(prev_index) {
|
match data.colors.get(prev_index) {
|
||||||
Some(DepNodeColor::Green(dep_node_index)) => Some((prev_index, dep_node_index)),
|
Some(DepNodeColor::Green(dep_node_index)) => return Some((prev_index, dep_node_index)),
|
||||||
Some(DepNodeColor::Red) => None,
|
Some(DepNodeColor::Red) => return None,
|
||||||
None => {
|
None => {}
|
||||||
// This DepNode and the corresponding query invocation existed
|
|
||||||
// in the previous compilation session too, so we can try to
|
|
||||||
// mark it as green by recursively marking all of its
|
|
||||||
// dependencies green.
|
|
||||||
self.try_mark_previous_green(qcx, data, prev_index, &dep_node)
|
|
||||||
.map(|dep_node_index| (prev_index, dep_node_index))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let backtrace = backtrace_printer(qcx.dep_context().sess(), data, prev_index);
|
||||||
|
|
||||||
|
// This DepNode and the corresponding query invocation existed
|
||||||
|
// in the previous compilation session too, so we can try to
|
||||||
|
// mark it as green by recursively marking all of its
|
||||||
|
// dependencies green.
|
||||||
|
let ret = self
|
||||||
|
.try_mark_previous_green(qcx, data, prev_index, &dep_node)
|
||||||
|
.map(|dep_node_index| (prev_index, dep_node_index));
|
||||||
|
|
||||||
|
// We succeeded, no backtrace.
|
||||||
|
backtrace.disable();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self, qcx, data, parent_dep_node_index), level = "debug")]
|
#[instrument(skip(self, qcx, data, parent_dep_node_index), level = "debug")]
|
||||||
@ -794,7 +802,10 @@ impl<K: DepKind> DepGraph<K> {
|
|||||||
let prev_deps = data.previous.edge_targets_from(prev_dep_node_index);
|
let prev_deps = data.previous.edge_targets_from(prev_dep_node_index);
|
||||||
|
|
||||||
for &dep_dep_node_index in prev_deps {
|
for &dep_dep_node_index in prev_deps {
|
||||||
self.try_mark_parent_green(qcx, data, dep_dep_node_index, dep_node)?
|
let backtrace = backtrace_printer(qcx.dep_context().sess(), data, dep_dep_node_index);
|
||||||
|
let success = self.try_mark_parent_green(qcx, data, dep_dep_node_index, dep_node);
|
||||||
|
backtrace.disable();
|
||||||
|
success?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we got here without hitting a `return` that means that all
|
// If we got here without hitting a `return` that means that all
|
||||||
@ -1364,3 +1375,26 @@ impl DepNodeColorMap {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn backtrace_printer<'a, K: DepKind>(
|
||||||
|
sess: &'a rustc_session::Session,
|
||||||
|
graph: &'a DepGraphData<K>,
|
||||||
|
node: SerializedDepNodeIndex,
|
||||||
|
) -> OnDrop<impl Fn() + 'a> {
|
||||||
|
OnDrop(
|
||||||
|
#[inline(never)]
|
||||||
|
#[cold]
|
||||||
|
move || {
|
||||||
|
let node = graph.previous.index_to_node(node);
|
||||||
|
// Do not try to rely on DepNode's Debug implementation, since it may panic.
|
||||||
|
let diag = rustc_errors::Diagnostic::new(
|
||||||
|
rustc_errors::Level::FailureNote,
|
||||||
|
&format!(
|
||||||
|
"encountered while trying to mark dependency green: {:?}({})",
|
||||||
|
node.kind, node.hash
|
||||||
|
),
|
||||||
|
);
|
||||||
|
sess.diagnostic().force_print_diagnostic(diag);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user