Skip to content

Commit 029f485

Browse files
committed
Preserve, clarify, and extend debug information
`-Cdebuginfo=1` was never line tables only and can't be due to backwards compatibility issues. This was clarified and an option for line tables only was added. Additionally an option for line info directives only was added, which is well needed for some targets. The debug info options should now behave the same as clang's debug info options.
1 parent c5799b2 commit 029f485

File tree

12 files changed

+124
-65
lines changed

12 files changed

+124
-65
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+1-18
Original file line numberDiff line numberDiff line change
@@ -1019,24 +1019,7 @@ pub fn compile_unit_metadata(
10191019
}
10201020
.unwrap_or_default();
10211021
let split_name = split_name.to_str().unwrap();
1022-
1023-
// FIXME(#60020):
1024-
//
1025-
// This should actually be
1026-
//
1027-
// let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo);
1028-
//
1029-
// That is, we should set LLVM's emission kind to `LineTablesOnly` if
1030-
// we are compiling with "limited" debuginfo. However, some of the
1031-
// existing tools relied on slightly more debuginfo being generated than
1032-
// would be the case with `LineTablesOnly`, and we did not want to break
1033-
// these tools in a "drive-by fix", without a good idea or plan about
1034-
// what limited debuginfo should exactly look like. So for now we keep
1035-
// the emission kind as `FullDebug`.
1036-
//
1037-
// See https://github.com/rust-lang/rust/issues/60020 for details.
1038-
let kind = DebugEmissionKind::FullDebug;
1039-
assert!(tcx.sess.opts.debuginfo != DebugInfo::None);
1022+
let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo);
10401023

10411024
unsafe {
10421025
let compile_unit_file = llvm::LLVMRustDIBuilderCreateFile(

compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
372372
cx: &CodegenCx<'ll, 'tcx>,
373373
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
374374
) -> &'ll DIArray {
375-
if cx.sess().opts.debuginfo == DebugInfo::Limited {
375+
if cx.sess().opts.debuginfo != DebugInfo::Full {
376376
return create_DIArray(DIB(cx), &[]);
377377
}
378378

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -872,15 +872,17 @@ pub mod debuginfo {
872872
NoDebug,
873873
FullDebug,
874874
LineTablesOnly,
875+
DebugDirectivesOnly,
875876
}
876877

877878
impl DebugEmissionKind {
878879
pub fn from_generic(kind: rustc_session::config::DebugInfo) -> Self {
879880
use rustc_session::config::DebugInfo;
880881
match kind {
881882
DebugInfo::None => DebugEmissionKind::NoDebug,
882-
DebugInfo::Limited => DebugEmissionKind::LineTablesOnly,
883-
DebugInfo::Full => DebugEmissionKind::FullDebug,
883+
DebugInfo::LineDirectivesOnly => DebugEmissionKind::DebugDirectivesOnly,
884+
DebugInfo::LineTablesOnly => DebugEmissionKind::LineTablesOnly,
885+
DebugInfo::Limited | DebugInfo::Full => DebugEmissionKind::FullDebug,
884886
}
885887
}
886888
}

compiler/rustc_codegen_ssa/src/back/linker.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1114,8 +1114,11 @@ impl<'a> Linker for EmLinker<'a> {
11141114

11151115
fn debuginfo(&mut self, _strip: Strip) {
11161116
// Preserve names or generate source maps depending on debug info
1117+
// For more information see https://emscripten.org/docs/tools_reference/emcc.html#emcc-g
11171118
self.cmd.arg(match self.sess.opts.debuginfo {
11181119
DebugInfo::None => "-g0",
1120+
DebugInfo::LineDirectivesOnly => "-g3",
1121+
DebugInfo::LineTablesOnly => "-g3",
11191122
DebugInfo::Limited => "-g3",
11201123
DebugInfo::Full => "-g4",
11211124
});

compiler/rustc_interface/src/tests.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_session::config::{build_configuration, build_session_options, to_crate
88
use rustc_session::config::{rustc_optgroups, ErrorOutputType, ExternLocation, Options, Passes};
99
use rustc_session::config::{CFGuard, ExternEntry, LinkerPluginLto, LtoCli, SwitchWithOptPath};
1010
use rustc_session::config::{
11-
Externs, OutputType, OutputTypes, SymbolManglingVersion, WasiExecModel,
11+
DebugInfo, Externs, OutputType, OutputTypes, SymbolManglingVersion, WasiExecModel,
1212
};
1313
use rustc_session::lint::Level;
1414
use rustc_session::search_paths::SearchPath;
@@ -564,7 +564,7 @@ fn test_codegen_options_tracking_hash() {
564564
tracked!(code_model, Some(CodeModel::Large));
565565
tracked!(control_flow_guard, CFGuard::Checks);
566566
tracked!(debug_assertions, Some(true));
567-
tracked!(debuginfo, 0xdeadbeef);
567+
tracked!(debuginfo, DebugInfo::Limited);
568568
tracked!(embed_bitcode, false);
569569
tracked!(force_frame_pointers, Some(false));
570570
tracked!(force_unwind_tables, Some(true));

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,7 @@ enum class LLVMRustDebugEmissionKind {
641641
NoDebug,
642642
FullDebug,
643643
LineTablesOnly,
644+
DebugDirectivesOnly,
644645
};
645646

646647
static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind) {
@@ -651,6 +652,8 @@ static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind)
651652
return DICompileUnit::DebugEmissionKind::FullDebug;
652653
case LLVMRustDebugEmissionKind::LineTablesOnly:
653654
return DICompileUnit::DebugEmissionKind::LineTablesOnly;
655+
case LLVMRustDebugEmissionKind::DebugDirectivesOnly:
656+
return DICompileUnit::DebugEmissionKind::DebugDirectivesOnly;
654657
default:
655658
report_fatal_error("bad DebugEmissionKind.");
656659
}

compiler/rustc_session/src/config.rs

+5-25
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ impl_stable_hash_via_hash!(SymbolManglingVersion);
201201
#[derive(Clone, Copy, Debug, PartialEq, Hash)]
202202
pub enum DebugInfo {
203203
None,
204+
LineDirectivesOnly,
205+
LineTablesOnly,
204206
Limited,
205207
Full,
206208
}
@@ -1561,11 +1563,7 @@ fn parse_opt_level(
15611563
}
15621564
}
15631565

1564-
fn select_debuginfo(
1565-
matches: &getopts::Matches,
1566-
cg: &CodegenOptions,
1567-
error_format: ErrorOutputType,
1568-
) -> DebugInfo {
1566+
fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInfo {
15691567
let max_g = matches.opt_positions("g").into_iter().max();
15701568
let max_c = matches
15711569
.opt_strs_pos("C")
@@ -1575,25 +1573,7 @@ fn select_debuginfo(
15751573
if let Some("debuginfo") = s.splitn(2, '=').next() { Some(i) } else { None }
15761574
})
15771575
.max();
1578-
if max_g > max_c {
1579-
DebugInfo::Full
1580-
} else {
1581-
match cg.debuginfo {
1582-
0 => DebugInfo::None,
1583-
1 => DebugInfo::Limited,
1584-
2 => DebugInfo::Full,
1585-
arg => {
1586-
early_error(
1587-
error_format,
1588-
&format!(
1589-
"debug info level needs to be between \
1590-
0-2 (instead was `{}`)",
1591-
arg
1592-
),
1593-
);
1594-
}
1595-
}
1596-
}
1576+
if max_g > max_c { DebugInfo::Full } else { cg.debuginfo }
15971577
}
15981578

15991579
fn parse_native_lib_kind(
@@ -2055,7 +2035,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
20552035
// to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
20562036
// for more details.
20572037
let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
2058-
let debuginfo = select_debuginfo(matches, &cg, error_format);
2038+
let debuginfo = select_debuginfo(matches, &cg);
20592039

20602040
let mut search_paths = vec![];
20612041
for s in &matches.opt_strs("L") {

compiler/rustc_session/src/options.rs

+16-14
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ mod desc {
355355
pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2";
356356
pub const parse_cfguard: &str =
357357
"either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
358+
pub const parse_debuginfo: &str = "either an integer (0, 1, 2), `none`, `line-directives-only`, `line-tables-only`, `limited`, or `full`";
358359
pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`";
359360
pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavor::one_of();
360361
pub const parse_optimization_fuel: &str = "crate=integer";
@@ -509,17 +510,6 @@ mod parse {
509510
}
510511
}
511512

512-
/// Use this for any numeric option that has a static default.
513-
crate fn parse_number<T: Copy + FromStr>(slot: &mut T, v: Option<&str>) -> bool {
514-
match v.and_then(|s| s.parse().ok()) {
515-
Some(i) => {
516-
*slot = i;
517-
true
518-
}
519-
None => false,
520-
}
521-
}
522-
523513
/// Use this for any numeric option that lacks a static default.
524514
crate fn parse_opt_number<T: Copy + FromStr>(slot: &mut Option<T>, v: Option<&str>) -> bool {
525515
match v {
@@ -633,6 +623,18 @@ mod parse {
633623
true
634624
}
635625

626+
crate fn parse_debuginfo(slot: &mut DebugInfo, v: Option<&str>) -> bool {
627+
match v {
628+
Some("0") | Some("none") => *slot = DebugInfo::None,
629+
Some("line-directives-only") => *slot = DebugInfo::LineDirectivesOnly,
630+
Some("line-tables-only") => *slot = DebugInfo::LineTablesOnly,
631+
Some("1") | Some("limited") => *slot = DebugInfo::Limited,
632+
Some("2") | Some("full") => *slot = DebugInfo::Full,
633+
_ => return false,
634+
}
635+
true
636+
}
637+
636638
crate fn parse_linker_flavor(slot: &mut Option<LinkerFlavor>, v: Option<&str>) -> bool {
637639
match v.and_then(LinkerFlavor::from_str) {
638640
Some(lf) => *slot = Some(lf),
@@ -905,9 +907,9 @@ options! {
905907
"use Windows Control Flow Guard (default: no)"),
906908
debug_assertions: Option<bool> = (None, parse_opt_bool, [TRACKED],
907909
"explicitly enable the `cfg(debug_assertions)` directive"),
908-
debuginfo: usize = (0, parse_number, [TRACKED],
909-
"debug info emission level (0 = no debug info, 1 = line tables only, \
910-
2 = full debug info with variable and type information; default: 0)"),
910+
debuginfo: DebugInfo = (DebugInfo::None, parse_debuginfo, [TRACKED],
911+
"debug info emission level (0-2, none, line-directives-only, \
912+
line-tables-only, limited, or full; default: 0)"),
911913
default_linker_libraries: bool = (false, parse_bool, [UNTRACKED],
912914
"allow the linker to link its default libraries (default: no)"),
913915
embed_bitcode: bool = (true, parse_bool, [TRACKED],

src/doc/rustc/src/codegen-options/index.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,11 @@ If not specified, debug assertions are automatically enabled only if the
7171
This flag controls the generation of debug information. It takes one of the
7272
following values:
7373

74-
* `0`: no debug info at all (the default).
75-
* `1`: line tables only.
76-
* `2`: full debug info.
74+
* `0` or `none`: no debug info at all (the default).
75+
* `line-directives-only`: line info directives only.
76+
* `line-tables-only`: line tables only.
77+
* `1` or `limited`: debug info without type information.
78+
* `2` or `full`: full debug info.
7779

7880
Note: The [`-g` flag][option-g-debug] is an alias for `-C debuginfo=2`.
7981

src/test/codegen/debug-limited.rs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Verify that the limited debuginfo option emits llvm's FullDebugInfo, but no type info.
2+
//
3+
// ignore-windows
4+
// compile-flags: -C debuginfo=limited
5+
6+
#[repr(C)]
7+
struct StructType {
8+
a: i64,
9+
b: i32
10+
}
11+
12+
extern "C" {
13+
fn creator() -> *mut StructType;
14+
fn save(p: *const StructType);
15+
}
16+
17+
fn main() {
18+
unsafe {
19+
let value: &mut StructType = &mut* creator();
20+
value.a = 7;
21+
save(value as *const StructType)
22+
}
23+
}
24+
25+
// CHECK: !DICompileUnit
26+
// CHECK: emissionKind: FullDebug
27+
// CHECK: !DILocation
28+
// CHECK-NOT: !DIBasicType
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Verify that the only debuginfo generated are the line directives.
2+
//
3+
// ignore-windows
4+
// compile-flags: -C debuginfo=line-directives-only
5+
6+
#[repr(C)]
7+
struct StructType {
8+
a: i64,
9+
b: i32
10+
}
11+
12+
extern "C" {
13+
fn creator() -> *mut StructType;
14+
fn save(p: *const StructType);
15+
}
16+
17+
fn main() {
18+
unsafe {
19+
let value: &mut StructType = &mut* creator();
20+
value.a = 7;
21+
save(value as *const StructType)
22+
}
23+
}
24+
25+
// CHECK: !DICompileUnit
26+
// CHECK: emissionKind: DebugDirectivesOnly
27+
// CHECK: !DILocation
28+
// CHECK-NOT: !DIBasicType
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Verify that the only debuginfo generated are the line tables.
2+
//
3+
// ignore-windows
4+
// compile-flags: -C debuginfo=line-tables-only
5+
6+
#[repr(C)]
7+
struct StructType {
8+
a: i64,
9+
b: i32
10+
}
11+
12+
extern "C" {
13+
fn creator() -> *mut StructType;
14+
fn save(p: *const StructType);
15+
}
16+
17+
fn main() {
18+
unsafe {
19+
let value: &mut StructType = &mut* creator();
20+
value.a = 7;
21+
save(value as *const StructType)
22+
}
23+
}
24+
25+
// CHECK: !DICompileUnit
26+
// CHECK: emissionKind: LineTablesOnly
27+
// CHECK: !DILocation
28+
// CHECK-NOT: !DIBasicType

0 commit comments

Comments
 (0)