Skip to content

Commit 4fd188e

Browse files
committed
Print query stack on ICEs
1 parent a143462 commit 4fd188e

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

src/librustc/ty/maps/plumbing.rs

+35
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
1515
use dep_graph::{DepNodeIndex, DepNode, DepKind, DepNodeColor};
1616
use errors::DiagnosticBuilder;
17+
use errors::Level;
18+
use ty::tls;
1719
use ty::{TyCtxt};
1820
use ty::maps::config::QueryDescription;
1921
use ty::maps::job::{QueryResult, QueryInfo};
@@ -108,6 +110,33 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
108110
})
109111
}
110112

113+
pub fn try_print_query_stack() {
114+
eprintln!("query stack during panic:");
115+
116+
tls::with_context_opt(|icx| {
117+
if let Some(icx) = icx {
118+
let mut current_query = icx.query.clone();
119+
let mut i = 0;
120+
121+
while let Some(query) = current_query {
122+
let mut db = DiagnosticBuilder::new(icx.tcx.sess.diagnostic(),
123+
Level::FailureNote,
124+
&format!("#{} [{}] {}",
125+
i,
126+
query.info.query.name(),
127+
query.info.query.describe(icx.tcx)));
128+
db.set_span(icx.tcx.sess.codemap().def_span(query.info.span));
129+
icx.tcx.sess.diagnostic().force_print_db(db);
130+
131+
current_query = query.parent.clone();
132+
i += 1;
133+
}
134+
}
135+
});
136+
137+
eprintln!("end of query stack");
138+
}
139+
111140
/// Try to read a node index for the node dep_node.
112141
/// A node will have an index, when it's already been marked green, or when we can mark it
113142
/// green. This function will mark the current task as a reader of the specified node, when
@@ -219,6 +248,12 @@ macro_rules! define_maps {
219248
}
220249

221250
impl<$tcx> Query<$tcx> {
251+
pub fn name(&self) -> &'static str {
252+
match *self {
253+
$(Query::$name(_) => stringify!($name),)*
254+
}
255+
}
256+
222257
pub fn describe(&self, tcx: TyCtxt) -> String {
223258
let (r, name) = match *self {
224259
$(Query::$name(key) => {

src/librustc/util/common.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ use std::fmt::Debug;
1717
use std::hash::{Hash, BuildHasher};
1818
use std::iter::repeat;
1919
use std::panic;
20+
use std::env;
2021
use std::path::Path;
2122
use std::time::{Duration, Instant};
2223

2324
use std::sync::mpsc::{Sender};
2425
use syntax_pos::{SpanData};
2526
use ty::maps::{QueryMsg};
27+
use ty::TyCtxt;
2628
use dep_graph::{DepNode};
2729
use proc_macro;
2830
use lazy_static;
@@ -48,7 +50,13 @@ lazy_static! {
4850

4951
fn panic_hook(info: &panic::PanicInfo) {
5052
if !proc_macro::__internal::in_sess() {
51-
(*DEFAULT_HOOK)(info)
53+
(*DEFAULT_HOOK)(info);
54+
55+
let backtrace = env::var_os("RUST_BACKTRACE").map(|x| &x != "0").unwrap_or(false);
56+
57+
if backtrace {
58+
TyCtxt::try_print_query_stack();
59+
}
5260
}
5361
}
5462

src/librustc_errors/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,11 @@ impl Handler {
641641
self.tracked_diagnostic_codes.borrow().contains(code)
642642
}
643643

644+
pub fn force_print_db(&self, mut db: DiagnosticBuilder) {
645+
self.emitter.borrow_mut().emit(&db);
646+
db.cancel();
647+
}
648+
644649
fn emit_db(&self, db: &DiagnosticBuilder) {
645650
let diagnostic = &**db;
646651

0 commit comments

Comments
 (0)