Rollup merge of #97028 - ridwanabdillahi:pretty-printer, r=michaelwoerister
Add support for embedding pretty printers via `#[debugger_visualizer]` attribute Initial support for [RFC 3191](https://github.com/rust-lang/rfcs/pull/3191) in PR https://github.com/rust-lang/rust/pull/91779 was scoped to supporting embedding NatVis files using a new attribute. This PR implements the pretty printer support as stated in the RFC mentioned above. This change includes embedding pretty printers in the `.debug_gdb_scripts` just as the pretty printers for rustc are embedded today. Also added additional tests for embedded pretty printers. Additionally cleaned up error checking so all error checking is done up front regardless of the current target. RFC: https://github.com/rust-lang/rfcs/pull/3191
This commit is contained in:
commit
239287f013
27 changed files with 462 additions and 200 deletions
|
@ -5,11 +5,14 @@ use crate::llvm;
|
|||
use crate::builder::Builder;
|
||||
use crate::common::CodegenCx;
|
||||
use crate::value::Value;
|
||||
use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_middle::bug;
|
||||
use rustc_session::config::DebugInfo;
|
||||
use rustc_session::config::{CrateType, DebugInfo};
|
||||
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::DebuggerVisualizerType;
|
||||
|
||||
/// Inserts a side-effect free instruction sequence that makes sure that the
|
||||
/// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
|
||||
|
@ -37,9 +40,33 @@ pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, '
|
|||
|
||||
section_var.unwrap_or_else(|| {
|
||||
let section_name = b".debug_gdb_scripts\0";
|
||||
let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0";
|
||||
let mut section_contents = Vec::new();
|
||||
|
||||
// Add the pretty printers for the standard library first.
|
||||
section_contents.extend_from_slice(b"\x01gdb_load_rust_pretty_printers.py\0");
|
||||
|
||||
// Next, add the pretty printers that were specified via the `#[debugger_visualizer]` attribute.
|
||||
let visualizers = collect_debugger_visualizers_transitive(
|
||||
cx.tcx,
|
||||
DebuggerVisualizerType::GdbPrettyPrinter,
|
||||
);
|
||||
let crate_name = cx.tcx.crate_name(LOCAL_CRATE);
|
||||
for (index, visualizer) in visualizers.iter().enumerate() {
|
||||
// The initial byte `4` instructs GDB that the following pretty printer
|
||||
// is defined inline as opposed to in a standalone file.
|
||||
section_contents.extend_from_slice(b"\x04");
|
||||
let vis_name = format!("pretty-printer-{}-{}\n", crate_name.as_str(), index);
|
||||
section_contents.extend_from_slice(vis_name.as_bytes());
|
||||
section_contents.extend_from_slice(&visualizer.src);
|
||||
|
||||
// The final byte `0` tells GDB that the pretty printer has been
|
||||
// fully defined and can continue searching for additional
|
||||
// pretty printers.
|
||||
section_contents.extend_from_slice(b"\0");
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let section_contents = section_contents.as_slice();
|
||||
let llvm_type = cx.type_array(cx.type_i8(), section_contents.len() as u64);
|
||||
|
||||
let section_var = cx
|
||||
|
@ -62,7 +89,32 @@ pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
|
|||
let omit_gdb_pretty_printer_section =
|
||||
cx.tcx.sess.contains_name(cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section);
|
||||
|
||||
// To ensure the section `__rustc_debug_gdb_scripts_section__` will not create
|
||||
// ODR violations at link time, this section will not be emitted for rlibs since
|
||||
// each rlib could produce a different set of visualizers that would be embedded
|
||||
// in the `.debug_gdb_scripts` section. For that reason, we make sure that the
|
||||
// section is only emitted for leaf crates.
|
||||
let embed_visualizers = cx.sess().crate_types().iter().any(|&crate_type| match crate_type {
|
||||
CrateType::Executable | CrateType::Dylib | CrateType::Cdylib | CrateType::Staticlib => {
|
||||
// These are crate types for which we will embed pretty printers since they
|
||||
// are treated as leaf crates.
|
||||
true
|
||||
}
|
||||
CrateType::ProcMacro => {
|
||||
// We could embed pretty printers for proc macro crates too but it does not
|
||||
// seem like a good default, since this is a rare use case and we don't
|
||||
// want to slow down the common case.
|
||||
false
|
||||
}
|
||||
CrateType::Rlib => {
|
||||
// As per the above description, embedding pretty printers for rlibs could
|
||||
// lead to ODR violations so we skip this crate type as well.
|
||||
false
|
||||
}
|
||||
});
|
||||
|
||||
!omit_gdb_pretty_printer_section
|
||||
&& cx.sess().opts.debuginfo != DebugInfo::None
|
||||
&& cx.sess().target.emit_debug_gdb_scripts
|
||||
&& embed_visualizers
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue