Print query stack on ICEs

This commit is contained in:
John Kåre Alsaker 2018-03-20 23:41:25 +01:00
parent a143462783
commit 4fd188e5f3
3 changed files with 49 additions and 1 deletions

View File

@ -14,6 +14,8 @@
use dep_graph::{DepNodeIndex, DepNode, DepKind, DepNodeColor};
use errors::DiagnosticBuilder;
use errors::Level;
use ty::tls;
use ty::{TyCtxt};
use ty::maps::config::QueryDescription;
use ty::maps::job::{QueryResult, QueryInfo};
@ -108,6 +110,33 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
})
}
pub fn try_print_query_stack() {
eprintln!("query stack during panic:");
tls::with_context_opt(|icx| {
if let Some(icx) = icx {
let mut current_query = icx.query.clone();
let mut i = 0;
while let Some(query) = current_query {
let mut db = DiagnosticBuilder::new(icx.tcx.sess.diagnostic(),
Level::FailureNote,
&format!("#{} [{}] {}",
i,
query.info.query.name(),
query.info.query.describe(icx.tcx)));
db.set_span(icx.tcx.sess.codemap().def_span(query.info.span));
icx.tcx.sess.diagnostic().force_print_db(db);
current_query = query.parent.clone();
i += 1;
}
}
});
eprintln!("end of query stack");
}
/// Try to read a node index for the node dep_node.
/// A node will have an index, when it's already been marked green, or when we can mark it
/// green. This function will mark the current task as a reader of the specified node, when
@ -219,6 +248,12 @@ macro_rules! define_maps {
}
impl<$tcx> Query<$tcx> {
pub fn name(&self) -> &'static str {
match *self {
$(Query::$name(_) => stringify!($name),)*
}
}
pub fn describe(&self, tcx: TyCtxt) -> String {
let (r, name) = match *self {
$(Query::$name(key) => {

View File

@ -17,12 +17,14 @@ use std::fmt::Debug;
use std::hash::{Hash, BuildHasher};
use std::iter::repeat;
use std::panic;
use std::env;
use std::path::Path;
use std::time::{Duration, Instant};
use std::sync::mpsc::{Sender};
use syntax_pos::{SpanData};
use ty::maps::{QueryMsg};
use ty::TyCtxt;
use dep_graph::{DepNode};
use proc_macro;
use lazy_static;
@ -48,7 +50,13 @@ lazy_static! {
fn panic_hook(info: &panic::PanicInfo) {
if !proc_macro::__internal::in_sess() {
(*DEFAULT_HOOK)(info)
(*DEFAULT_HOOK)(info);
let backtrace = env::var_os("RUST_BACKTRACE").map(|x| &x != "0").unwrap_or(false);
if backtrace {
TyCtxt::try_print_query_stack();
}
}
}

View File

@ -641,6 +641,11 @@ impl Handler {
self.tracked_diagnostic_codes.borrow().contains(code)
}
pub fn force_print_db(&self, mut db: DiagnosticBuilder) {
self.emitter.borrow_mut().emit(&db);
db.cancel();
}
fn emit_db(&self, db: &DiagnosticBuilder) {
let diagnostic = &**db;