From d51d98819bb9a92f7577cb80c84a6fda3df6bbb5 Mon Sep 17 00:00:00 2001 From: Alexa VanHattum Date: Wed, 7 Jul 2021 13:48:54 +0000 Subject: [PATCH 1/4] Custom panic hook for RMC including current item --- compiler/rustc_codegen_llvm/src/gotoc/mod.rs | 86 +++++++++++++++++++- compiler/rustc_codegen_llvm/src/lib.rs | 1 + 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/gotoc/mod.rs b/compiler/rustc_codegen_llvm/src/gotoc/mod.rs index 3df7ff4b9791..06aebadcf894 100644 --- a/compiler/rustc_codegen_llvm/src/gotoc/mod.rs +++ b/compiler/rustc_codegen_llvm/src/gotoc/mod.rs @@ -19,6 +19,9 @@ use rustc_serialize::json::ToJson; use rustc_session::config::{OutputFilenames, OutputType}; use rustc_session::Session; use rustc_target::abi::Endian; +use std::cell::RefCell; +use std::lazy::SyncLazy; +use std::panic; use tracing::{debug, warn}; mod assumptions; @@ -36,6 +39,60 @@ pub mod stubs; mod typ; mod utils; +// Use a thread-local global variable to track the current codegen item for debugging. +// If RMC panics during codegen, we can grab this item to include the problematic +// codegen item in the panic trace. +thread_local!(static CURRENT_CODEGEN_ITEM: RefCell> = RefCell::new(None)); + +// Updates the tracking global variable for panic debugging. +fn set_debug_item(s: String) { + CURRENT_CODEGEN_ITEM.with(|odb_cell| { + odb_cell.replace(Some(s)); + }); +} + +// Include RMC's bug reporting URL in our panics. +const BUG_REPORT_URL: &str = + "https://github.com/model-checking/rmc/issues/new?labels=bug&template=bug_report.md"; + +// Custom panic hook. +static DEFAULT_HOOK: SyncLazy) + Sync + Send + 'static>> = + SyncLazy::new(|| { + let hook = panic::take_hook(); + panic::set_hook(Box::new(|info| { + // Invoke the default handler, which prints the actual panic message and + // optionally a backtrace. This also prints Rustc's "file a bug here" message: + // it seems like the only way to remove that is to use rustc_driver::report_ice; + // however, adding that dependency to this crate causes a circular dependency. + // For now, just print our message after the Rust one and explicitly point to + // our bug template form. + (*DEFAULT_HOOK)(info); + + // Separate the output with an empty line + eprintln!(); + + // Print the current function if available + CURRENT_CODEGEN_ITEM.with(|cell| { + if let Some(current_item) = cell.borrow().clone() { + eprintln!("[RMC] current codegen item: {}", current_item); + } else { + eprintln!("[RMC] no current codegen item."); + } + }); + + // Separate the output with an empty line + eprintln!(); + + // Print the RMC message + eprintln!("RMC unexpectedly panicked during code generation.\n"); + eprintln!( + "If you are seeing this message, please file an issue here instead of on the Rust compiler: {}", + BUG_REPORT_URL + ); + })); + hook + }); + #[derive(Clone)] pub struct GotocCodegenBackend(); @@ -285,6 +342,9 @@ impl CodegenBackend for GotocCodegenBackend { ) -> Box { use rustc_hir::def_id::LOCAL_CRATE; + // Install panic hook + SyncLazy::force(&DEFAULT_HOOK); // Install ice hook + let codegen_units: &'tcx [CodegenUnit<'_>] = tcx.collect_and_partition_mono_items(()).1; let mm = machine_model_from_session(&tcx.sess); let mut c = GotocCtx::new(tcx, SymbolTable::new(mm)); @@ -294,8 +354,17 @@ impl CodegenBackend for GotocCodegenBackend { let items = cgu.items_in_deterministic_order(tcx); for (item, _) in items { match item { - MonoItem::Fn(instance) => c.declare_function(instance), - MonoItem::Static(def_id) => c.declare_static(def_id, item), + MonoItem::Fn(instance) => { + set_debug_item(format!( + "declare_function: {}", + c.readable_instance_name(instance) + )); + c.declare_function(instance) + } + MonoItem::Static(def_id) => { + set_debug_item(format!("declare_static: {:?}", def_id)); + c.declare_static(def_id, item) + } MonoItem::GlobalAsm(_) => { warn!( "Crate {} contains global ASM, which is not handled by RMC", @@ -311,8 +380,17 @@ impl CodegenBackend for GotocCodegenBackend { let items = cgu.items_in_deterministic_order(tcx); for (item, _) in items { match item { - MonoItem::Fn(instance) => c.codegen_function(instance), - MonoItem::Static(def_id) => c.codegen_static(def_id, item), + MonoItem::Fn(instance) => { + set_debug_item(format!( + "codegen_function: {}", + c.readable_instance_name(instance) + )); + c.codegen_function(instance) + } + MonoItem::Static(def_id) => { + set_debug_item(format!("codegen_static: {:?}", def_id)); + c.codegen_static(def_id, item) + } MonoItem::GlobalAsm(_) => {} // We have already warned above } } diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index ba0115482996..54d60f25495b 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -15,6 +15,7 @@ #![recursion_limit = "256"] #![feature(destructuring_assignment)] #![feature(box_patterns)] +#![feature(once_cell)] use back::write::{create_informational_target_machine, create_target_machine}; From be8b9b0781e657cafc63181e4a8e66a6b7c2628d Mon Sep 17 00:00:00 2001 From: Alexa VanHattum Date: Wed, 7 Jul 2021 19:05:58 +0000 Subject: [PATCH 2/4] Review comments --- compiler/rustc_codegen_llvm/src/gotoc/mod.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/gotoc/mod.rs b/compiler/rustc_codegen_llvm/src/gotoc/mod.rs index 06aebadcf894..43eecfd09de3 100644 --- a/compiler/rustc_codegen_llvm/src/gotoc/mod.rs +++ b/compiler/rustc_codegen_llvm/src/gotoc/mod.rs @@ -45,11 +45,16 @@ mod utils; thread_local!(static CURRENT_CODEGEN_ITEM: RefCell> = RefCell::new(None)); // Updates the tracking global variable for panic debugging. -fn set_debug_item(s: String) { +fn set_panic_debug_codegen_item(s: String) { CURRENT_CODEGEN_ITEM.with(|odb_cell| { odb_cell.replace(Some(s)); }); } +fn clear_panic_debug_codegen_item() { + CURRENT_CODEGEN_ITEM.with(|odb_cell| { + odb_cell.replace(None); + }); +} // Include RMC's bug reporting URL in our panics. const BUG_REPORT_URL: &str = @@ -355,14 +360,14 @@ impl CodegenBackend for GotocCodegenBackend { for (item, _) in items { match item { MonoItem::Fn(instance) => { - set_debug_item(format!( + set_panic_debug_codegen_item(format!( "declare_function: {}", c.readable_instance_name(instance) )); c.declare_function(instance) } MonoItem::Static(def_id) => { - set_debug_item(format!("declare_static: {:?}", def_id)); + set_panic_debug_codegen_item(format!("declare_static: {:?}", def_id)); c.declare_static(def_id, item) } MonoItem::GlobalAsm(_) => { @@ -374,6 +379,7 @@ impl CodegenBackend for GotocCodegenBackend { } } } + clear_panic_debug_codegen_item(); // then we move on to codegen for cgu in codegen_units { @@ -381,20 +387,21 @@ impl CodegenBackend for GotocCodegenBackend { for (item, _) in items { match item { MonoItem::Fn(instance) => { - set_debug_item(format!( + set_panic_debug_codegen_item(format!( "codegen_function: {}", c.readable_instance_name(instance) )); c.codegen_function(instance) } MonoItem::Static(def_id) => { - set_debug_item(format!("codegen_static: {:?}", def_id)); + set_panic_debug_codegen_item(format!("codegen_static: {:?}", def_id)); c.codegen_static(def_id, item) } MonoItem::GlobalAsm(_) => {} // We have already warned above } } } + clear_panic_debug_codegen_item(); Box::new(GotocCodegenResult { symtab: c.symbol_table, From 55fb5b443e1634415dff540cfca7acebc93843fd Mon Sep 17 00:00:00 2001 From: Alexa VanHattum Date: Wed, 7 Jul 2021 20:21:38 +0000 Subject: [PATCH 3/4] fmt --- src/test/cbmc/FatPointers/boxmuttrait.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/cbmc/FatPointers/boxmuttrait.rs b/src/test/cbmc/FatPointers/boxmuttrait.rs index 6ddc193a2a41..4cc9325161c0 100644 --- a/src/test/cbmc/FatPointers/boxmuttrait.rs +++ b/src/test/cbmc/FatPointers/boxmuttrait.rs @@ -3,9 +3,9 @@ #![feature(core_intrinsics)] #![feature(ptr_metadata)] +use std::any::Any; use std::io::{sink, Write}; use std::ptr::DynMetadata; -use std::any::Any; include!("../Helpers/vtable_utils_ignore.rs"); From dae547dab3f6be1f9d1862bb9b0a4b3467b84843 Mon Sep 17 00:00:00 2001 From: Alexa VanHattum Date: Thu, 8 Jul 2021 17:22:02 +0000 Subject: [PATCH 4/4] Closure for clearing --- compiler/rustc_codegen_llvm/src/gotoc/mod.rs | 57 ++++++++++---------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/gotoc/mod.rs b/compiler/rustc_codegen_llvm/src/gotoc/mod.rs index 43eecfd09de3..b23e14ab564f 100644 --- a/compiler/rustc_codegen_llvm/src/gotoc/mod.rs +++ b/compiler/rustc_codegen_llvm/src/gotoc/mod.rs @@ -44,18 +44,6 @@ mod utils; // codegen item in the panic trace. thread_local!(static CURRENT_CODEGEN_ITEM: RefCell> = RefCell::new(None)); -// Updates the tracking global variable for panic debugging. -fn set_panic_debug_codegen_item(s: String) { - CURRENT_CODEGEN_ITEM.with(|odb_cell| { - odb_cell.replace(Some(s)); - }); -} -fn clear_panic_debug_codegen_item() { - CURRENT_CODEGEN_ITEM.with(|odb_cell| { - odb_cell.replace(None); - }); -} - // Include RMC's bug reporting URL in our panics. const BUG_REPORT_URL: &str = "https://github.com/model-checking/rmc/issues/new?labels=bug&template=bug_report.md"; @@ -102,6 +90,19 @@ static DEFAULT_HOOK: SyncLazy) + Sync + Send + pub struct GotocCodegenBackend(); impl<'tcx> GotocCtx<'tcx> { + // Calls the closure while updating the tracked global variable marking the + // codegen item for panic debugging. + pub fn call_with_panic_debug_info) -> ()>( + &mut self, + call: F, + panic_debug: String, + ) { + CURRENT_CODEGEN_ITEM.with(|odb_cell| { + odb_cell.replace(Some(panic_debug)); + call(self); + odb_cell.replace(None); + }); + } pub fn codegen_block(&mut self, bb: BasicBlock, bbd: &BasicBlockData<'tcx>) { self.current_fn_mut().set_current_bb(bb); let label: String = self.current_fn().find_label(&bb); @@ -360,15 +361,16 @@ impl CodegenBackend for GotocCodegenBackend { for (item, _) in items { match item { MonoItem::Fn(instance) => { - set_panic_debug_codegen_item(format!( - "declare_function: {}", - c.readable_instance_name(instance) - )); - c.declare_function(instance) + c.call_with_panic_debug_info( + |ctx| ctx.declare_function(instance), + format!("declare_function: {}", c.readable_instance_name(instance)), + ); } MonoItem::Static(def_id) => { - set_panic_debug_codegen_item(format!("declare_static: {:?}", def_id)); - c.declare_static(def_id, item) + c.call_with_panic_debug_info( + |ctx| ctx.declare_static(def_id, item), + format!("declare_static: {:?}", def_id), + ); } MonoItem::GlobalAsm(_) => { warn!( @@ -379,7 +381,6 @@ impl CodegenBackend for GotocCodegenBackend { } } } - clear_panic_debug_codegen_item(); // then we move on to codegen for cgu in codegen_units { @@ -387,21 +388,21 @@ impl CodegenBackend for GotocCodegenBackend { for (item, _) in items { match item { MonoItem::Fn(instance) => { - set_panic_debug_codegen_item(format!( - "codegen_function: {}", - c.readable_instance_name(instance) - )); - c.codegen_function(instance) + c.call_with_panic_debug_info( + |ctx| ctx.codegen_function(instance), + format!("codegen_function: {}", c.readable_instance_name(instance)), + ); } MonoItem::Static(def_id) => { - set_panic_debug_codegen_item(format!("codegen_static: {:?}", def_id)); - c.codegen_static(def_id, item) + c.call_with_panic_debug_info( + |ctx| ctx.codegen_static(def_id, item), + format!("codegen_static: {:?}", def_id), + ); } MonoItem::GlobalAsm(_) => {} // We have already warned above } } } - clear_panic_debug_codegen_item(); Box::new(GotocCodegenResult { symtab: c.symbol_table,