Skip to content

Commit 13f9889

Browse files
Embed GDB pretty printers in rlibs and dylibs
Instead of collecting pretty printers transitively when building executables/staticlibs/cdylibs, let the debugger find each crate's pretty printers via its .debug_gdb_scripts section. This covers the case where libraries defining custom pretty printers are loaded dynamically.
1 parent 26f05dc commit 13f9889

File tree

2 files changed

+24
-29
lines changed
  • compiler
    • rustc_codegen_llvm/src/debuginfo
    • rustc_codegen_ssa/src

2 files changed

+24
-29
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// .debug_gdb_scripts binary section.
22

3+
use std::collections::BTreeSet;
34
use std::ffi::CString;
45

5-
use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive;
66
use rustc_codegen_ssa::traits::*;
77
use rustc_hir::attrs::AttributeKind;
88
use rustc_hir::def_id::LOCAL_CRATE;
@@ -53,10 +53,14 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
5353

5454
// Next, add the pretty printers that were specified via the `#[debugger_visualizer]`
5555
// attribute.
56-
let visualizers = collect_debugger_visualizers_transitive(
57-
cx.tcx,
58-
DebuggerVisualizerType::GdbPrettyPrinter,
59-
);
56+
let visualizers = cx
57+
.tcx
58+
.debugger_visualizers(LOCAL_CRATE)
59+
.iter()
60+
.filter(|visualizer| {
61+
visualizer.visualizer_type == DebuggerVisualizerType::GdbPrettyPrinter
62+
})
63+
.collect::<BTreeSet<_>>();
6064
let crate_name = cx.tcx.crate_name(LOCAL_CRATE);
6165
for (index, visualizer) in visualizers.iter().enumerate() {
6266
// The initial byte `4` instructs GDB that the following pretty printer
@@ -96,31 +100,14 @@ pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
96100
let omit_gdb_pretty_printer_section =
97101
find_attr!(cx.tcx.hir_krate_attrs(), AttributeKind::OmitGdbPrettyPrinterSection);
98102

99-
// We collect pretty printers transitively for all crates, so we make sure
100-
// that the section is only emitted for leaf crates.
101-
let embed_visualizers = cx.tcx.crate_types().iter().any(|&crate_type| match crate_type {
102-
CrateType::Executable | CrateType::Cdylib | CrateType::Staticlib | CrateType::Sdylib => {
103-
// These are crate types for which we will embed pretty printers since they
104-
// are treated as leaf crates.
105-
true
106-
}
107-
CrateType::ProcMacro => {
108-
// We could embed pretty printers for proc macro crates too but it does not
109-
// seem like a good default, since this is a rare use case and we don't
110-
// want to slow down the common case.
111-
false
112-
}
113-
CrateType::Rlib | CrateType::Dylib => {
114-
// Don't embed pretty printers for these crate types; the compiler
115-
// can see the `#[debug_visualizer]` attributes when using the
116-
// library, and emitting `.debug_gdb_scripts` regardless would
117-
// break `#![omit_gdb_pretty_printer_section]`.
118-
false
119-
}
120-
});
103+
// We could embed pretty printers for proc macro crates too but it does not
104+
// seem like a good default, since this is a rare use case and we don't
105+
// want to slow down the common case.
106+
let proc_macro_only =
107+
cx.tcx.crate_types().iter().all(|&crate_type| crate_type == CrateType::ProcMacro);
121108

122109
!omit_gdb_pretty_printer_section
123110
&& cx.sess().opts.debuginfo != DebugInfo::None
124111
&& cx.sess().target.emit_debug_gdb_scripts
125-
&& embed_visualizers
112+
&& !proc_macro_only
126113
}

compiler/rustc_codegen_ssa/src/base.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,15 @@ pub fn collect_debugger_visualizers_transitive(
609609
) -> BTreeSet<DebuggerVisualizerFile> {
610610
tcx.debugger_visualizers(LOCAL_CRATE)
611611
.iter()
612-
.chain(tcx.crates(()).iter().flat_map(|&cnum| tcx.debugger_visualizers(cnum)))
612+
.chain(
613+
tcx.crates(())
614+
.iter()
615+
.filter(|&cnum| {
616+
let used_crate_source = tcx.used_crate_source(*cnum);
617+
used_crate_source.rlib.is_some() || used_crate_source.rmeta.is_some()
618+
})
619+
.flat_map(|&cnum| tcx.debugger_visualizers(cnum)),
620+
)
613621
.filter(|visualizer| visualizer.visualizer_type == visualizer_type)
614622
.cloned()
615623
.collect::<BTreeSet<_>>()

0 commit comments

Comments
 (0)