Skip to content

Commit 0504a33

Browse files
jdtatzjyn514
authored andcommitted
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 eb3e9c1 commit 0504a33

File tree

13 files changed

+126
-54
lines changed

13 files changed

+126
-54
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+1-18
Original file line numberDiff line numberDiff line change
@@ -830,24 +830,7 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>(
830830
}
831831
.unwrap_or_default();
832832
let split_name = split_name.to_str().unwrap();
833-
834-
// FIXME(#60020):
835-
//
836-
// This should actually be
837-
//
838-
// let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo);
839-
//
840-
// That is, we should set LLVM's emission kind to `LineTablesOnly` if
841-
// we are compiling with "limited" debuginfo. However, some of the
842-
// existing tools relied on slightly more debuginfo being generated than
843-
// would be the case with `LineTablesOnly`, and we did not want to break
844-
// these tools in a "drive-by fix", without a good idea or plan about
845-
// what limited debuginfo should exactly look like. So for now we keep
846-
// the emission kind as `FullDebug`.
847-
//
848-
// See https://github.com/rust-lang/rust/issues/60020 for details.
849-
let kind = DebugEmissionKind::FullDebug;
850-
assert!(tcx.sess.opts.debuginfo != DebugInfo::None);
833+
let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo);
851834

852835
unsafe {
853836
let compile_unit_file = llvm::LLVMRustDIBuilderCreateFile(

compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
402402
cx: &CodegenCx<'ll, 'tcx>,
403403
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
404404
) -> &'ll DIArray {
405-
if cx.sess().opts.debuginfo == DebugInfo::Limited {
405+
if cx.sess().opts.debuginfo != DebugInfo::Full {
406406
return create_DIArray(DIB(cx), &[]);
407407
}
408408

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -946,15 +946,17 @@ pub mod debuginfo {
946946
NoDebug,
947947
FullDebug,
948948
LineTablesOnly,
949+
DebugDirectivesOnly,
949950
}
950951

951952
impl DebugEmissionKind {
952953
pub fn from_generic(kind: rustc_session::config::DebugInfo) -> Self {
953954
use rustc_session::config::DebugInfo;
954955
match kind {
955956
DebugInfo::None => DebugEmissionKind::NoDebug,
956-
DebugInfo::Limited => DebugEmissionKind::LineTablesOnly,
957-
DebugInfo::Full => DebugEmissionKind::FullDebug,
957+
DebugInfo::LineDirectivesOnly => DebugEmissionKind::DebugDirectivesOnly,
958+
DebugInfo::LineTablesOnly => DebugEmissionKind::LineTablesOnly,
959+
DebugInfo::Limited | DebugInfo::Full => DebugEmissionKind::FullDebug,
958960
}
959961
}
960962
}

compiler/rustc_codegen_ssa/src/back/linker.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1121,9 +1121,12 @@ impl<'a> Linker for EmLinker<'a> {
11211121

11221122
fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) {
11231123
// Preserve names or generate source maps depending on debug info
1124+
// For more information see https://emscripten.org/docs/tools_reference/emcc.html#emcc-g
11241125
self.cmd.arg(match self.sess.opts.debuginfo {
11251126
DebugInfo::None => "-g0",
1126-
DebugInfo::Limited => "--profiling-funcs",
1127+
DebugInfo::Limited | DebugInfo::LineTablesOnly | DebugInfo::LineDirectivesOnly => {
1128+
"--profiling-funcs"
1129+
}
11271130
DebugInfo::Full => "-g",
11281131
});
11291132
}

compiler/rustc_interface/src/tests.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_data_structures::fx::FxHashSet;
55
use rustc_data_structures::profiling::TimePassesFormat;
66
use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
77
use rustc_session::config::rustc_optgroups;
8+
use rustc_session::config::DebugInfo;
89
use rustc_session::config::Input;
910
use rustc_session::config::InstrumentXRay;
1011
use rustc_session::config::TraitSolver;
@@ -574,7 +575,7 @@ fn test_codegen_options_tracking_hash() {
574575
tracked!(code_model, Some(CodeModel::Large));
575576
tracked!(control_flow_guard, CFGuard::Checks);
576577
tracked!(debug_assertions, Some(true));
577-
tracked!(debuginfo, 0xdeadbeef);
578+
tracked!(debuginfo, DebugInfo::Limited);
578579
tracked!(embed_bitcode, false);
579580
tracked!(force_frame_pointers, Some(false));
580581
tracked!(force_unwind_tables, Some(true));

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ enum class LLVMRustDebugEmissionKind {
682682
NoDebug,
683683
FullDebug,
684684
LineTablesOnly,
685+
DebugDirectivesOnly,
685686
};
686687

687688
static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind) {
@@ -692,6 +693,8 @@ static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind)
692693
return DICompileUnit::DebugEmissionKind::FullDebug;
693694
case LLVMRustDebugEmissionKind::LineTablesOnly:
694695
return DICompileUnit::DebugEmissionKind::LineTablesOnly;
696+
case LLVMRustDebugEmissionKind::DebugDirectivesOnly:
697+
return DICompileUnit::DebugEmissionKind::DebugDirectivesOnly;
695698
default:
696699
report_fatal_error("bad DebugEmissionKind.");
697700
}

compiler/rustc_session/src/config.rs

+5-24
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ pub enum SymbolManglingVersion {
260260
#[derive(Clone, Copy, Debug, PartialEq, Hash)]
261261
pub enum DebugInfo {
262262
None,
263+
LineDirectivesOnly,
264+
LineTablesOnly,
263265
Limited,
264266
Full,
265267
}
@@ -1979,11 +1981,7 @@ fn parse_opt_level(
19791981
}
19801982
}
19811983

1982-
fn select_debuginfo(
1983-
matches: &getopts::Matches,
1984-
cg: &CodegenOptions,
1985-
error_format: ErrorOutputType,
1986-
) -> DebugInfo {
1984+
fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInfo {
19871985
let max_g = matches.opt_positions("g").into_iter().max();
19881986
let max_c = matches
19891987
.opt_strs_pos("C")
@@ -1993,24 +1991,7 @@ fn select_debuginfo(
19931991
if let Some("debuginfo") = s.split('=').next() { Some(i) } else { None }
19941992
})
19951993
.max();
1996-
if max_g > max_c {
1997-
DebugInfo::Full
1998-
} else {
1999-
match cg.debuginfo {
2000-
0 => DebugInfo::None,
2001-
1 => DebugInfo::Limited,
2002-
2 => DebugInfo::Full,
2003-
arg => {
2004-
early_error(
2005-
error_format,
2006-
&format!(
2007-
"debug info level needs to be between \
2008-
0-2 (instead was `{arg}`)"
2009-
),
2010-
);
2011-
}
2012-
}
2013-
}
1994+
if max_g > max_c { DebugInfo::Full } else { cg.debuginfo }
20141995
}
20151996

20161997
pub(crate) fn parse_assert_incr_state(
@@ -2498,7 +2479,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
24982479
// to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
24992480
// for more details.
25002481
let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
2501-
let debuginfo = select_debuginfo(matches, &cg, error_format);
2482+
let debuginfo = select_debuginfo(matches, &cg);
25022483

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

compiler/rustc_session/src/options.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ mod desc {
377377
pub const parse_cfguard: &str =
378378
"either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
379379
pub const parse_cfprotection: &str = "`none`|`no`|`n` (default), `branch`, `return`, or `full`|`yes`|`y` (equivalent to `branch` and `return`)";
380+
pub const parse_debuginfo: &str = "either an integer (0, 1, 2), `none`, `line-directives-only`, `line-tables-only`, `limited`, or `full`";
380381
pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`";
381382
pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of();
382383
pub const parse_optimization_fuel: &str = "crate=integer";
@@ -767,6 +768,18 @@ mod parse {
767768
true
768769
}
769770

771+
pub(crate) fn parse_debuginfo(slot: &mut DebugInfo, v: Option<&str>) -> bool {
772+
match v {
773+
Some("0") | Some("none") => *slot = DebugInfo::None,
774+
Some("line-directives-only") => *slot = DebugInfo::LineDirectivesOnly,
775+
Some("line-tables-only") => *slot = DebugInfo::LineTablesOnly,
776+
Some("1") | Some("limited") => *slot = DebugInfo::Limited,
777+
Some("2") | Some("full") => *slot = DebugInfo::Full,
778+
_ => return false,
779+
}
780+
true
781+
}
782+
770783
pub(crate) fn parse_linker_flavor(slot: &mut Option<LinkerFlavorCli>, v: Option<&str>) -> bool {
771784
match v.and_then(LinkerFlavorCli::from_str) {
772785
Some(lf) => *slot = Some(lf),
@@ -1217,9 +1230,9 @@ options! {
12171230
"use Windows Control Flow Guard (default: no)"),
12181231
debug_assertions: Option<bool> = (None, parse_opt_bool, [TRACKED],
12191232
"explicitly enable the `cfg(debug_assertions)` directive"),
1220-
debuginfo: usize = (0, parse_number, [TRACKED],
1221-
"debug info emission level (0 = no debug info, 1 = line tables only, \
1222-
2 = full debug info with variable and type information; default: 0)"),
1233+
debuginfo: DebugInfo = (DebugInfo::None, parse_debuginfo, [TRACKED],
1234+
"debug info emission level (0-2, none, line-directives-only, \
1235+
line-tables-only, limited, or full; default: 0)"),
12231236
default_linker_libraries: bool = (false, parse_bool, [UNTRACKED],
12241237
"allow the linker to link its default libraries (default: no)"),
12251238
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

tests/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

tests/rustdoc-ui/c-help.stdout

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
-C codegen-units=val -- divide crate into N units to optimize in parallel
44
-C control-flow-guard=val -- use Windows Control Flow Guard (default: no)
55
-C debug-assertions=val -- explicitly enable the `cfg(debug_assertions)` directive
6-
-C debuginfo=val -- debug info emission level (0 = no debug info, 1 = line tables only, 2 = full debug info with variable and type information; default: 0)
6+
-C debuginfo=val -- debug info emission level (0-2, none, line-directives-only, line-tables-only, limited, or full; default: 0)
77
-C default-linker-libraries=val -- allow the linker to link its default libraries (default: no)
88
-C embed-bitcode=val -- emit bitcode in rlibs (default: yes)
99
-C extra-filename=val -- extra data to put in each output filename

0 commit comments

Comments
 (0)