Skip to content

Commit

Permalink
Auto merge of rust-lang#91742 - cjgillot:force-backtrace, r=estebank
Browse files Browse the repository at this point in the history
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: rust-lang#90682 rust-lang#90697 rust-lang#90715 rust-lang#90739 rust-lang#91401

These bugs happen when the dep-graph attempts to force a dep-node whose fingerprint does not correspond to an actual DefPathHash. PR rust-lang#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.
  • Loading branch information
bors committed Feb 24, 2023
2 parents c5c7d2b + 870dd16 commit f0bc76a
Showing 1 changed file with 45 additions and 11 deletions.
56 changes: 45 additions & 11 deletions compiler/rustc_query_system/src/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use rustc_data_structures::sharded::{self, Sharded};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::steal::Steal;
use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering};
use rustc_data_structures::OnDrop;
use rustc_index::vec::IndexVec;
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
use smallvec::{smallvec, SmallVec};
Expand Down Expand Up @@ -671,17 +672,24 @@ impl<K: DepKind> DepGraph<K> {
let prev_index = data.previous.node_to_index_opt(dep_node)?;

match data.colors.get(prev_index) {
Some(DepNodeColor::Green(dep_node_index)) => Some((prev_index, dep_node_index)),
Some(DepNodeColor::Red) => 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))
}
Some(DepNodeColor::Green(dep_node_index)) => return Some((prev_index, dep_node_index)),
Some(DepNodeColor::Red) => return None,
None => {}
}

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")]
Expand Down Expand Up @@ -794,7 +802,10 @@ impl<K: DepKind> DepGraph<K> {
let prev_deps = data.previous.edge_targets_from(prev_dep_node_index);

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
Expand Down Expand Up @@ -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);
},
)
}

0 comments on commit f0bc76a

Please sign in to comment.