about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-04-04 20:01:05 +0000
committerbors <bors@rust-lang.org>2023-04-04 20:01:05 +0000
commit700938c0781c9f135244bb1ec846fe1a5e03ae7d (patch)
treea6102fb38baefba5b9d607827ac691a4c67e03df
parent540a50df0fb23127edf0b35b0e497748e24bba1a (diff)
parent92b759137178c732ea541134cede507b606e0a0d (diff)
downloadrust-700938c0781c9f135244bb1ec846fe1a5e03ae7d.tar.gz
rust-700938c0781c9f135244bb1ec846fe1a5e03ae7d.zip
Auto merge of #109808 - jyn514:debuginfo-options, r=michaelwoerister
Extend -Cdebuginfo with new options and named aliases

This is a rebase of https://github.com/rust-lang/rust/pull/83947, along with my best guess at what the new options mean. I tried to follow the LLVM source code to get a better idea but ran into quite a lot of trouble (https://rust-lang.zulipchat.com/#narrow/stream/187780-t-compiler.2Fwg-llvm/topic/go-to-definition.20in.20src.2Fllvm-project.3F). The description for the original PR follows below.

Note that the changes in this PR have already been through FCP: https://github.com/rust-lang/rust/pull/83947#issuecomment-878384979

Closes https://github.com/rust-lang/rust/pull/109311. Helps with https://github.com/rust-lang/rust/pull/104968.
r? `@michaelwoerister` cc `@cuviper`

---

The -Cdebuginfo=1 option was never line tables only and can't be due to backwards compatibility issues. This was clarified and an option for emitting line tables only was added. Additionally an option for emitting line info directives only was added, which is needed for some targets, i.e. nvptx. The debug info options should now behave similarly to clang's debug info options.

Fix https://github.com/rust-lang/rust/issues/60020
Fix https://github.com/rust-lang/rust/issues/64405
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs19
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs16
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs5
-rw-r--r--compiler/rustc_interface/src/tests.rs3
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp3
-rw-r--r--compiler/rustc_session/src/config.rs29
-rw-r--r--compiler/rustc_session/src/options.rs19
-rw-r--r--src/doc/rustc/src/codegen-options/index.md8
-rw-r--r--tests/codegen/debug-limited.rs27
-rw-r--r--tests/codegen/debug-line-directives-only.rs27
-rw-r--r--tests/codegen/debug-line-tables-only.rs27
-rw-r--r--tests/rustdoc-ui/c-help.stdout2
13 files changed, 133 insertions, 54 deletions
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index e2a592d851a..4bf6762d1f6 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -830,24 +830,7 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>(
     }
     .unwrap_or_default();
     let split_name = split_name.to_str().unwrap();
-
-    // FIXME(#60020):
-    //
-    //    This should actually be
-    //
-    //        let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo);
-    //
-    //    That is, we should set LLVM's emission kind to `LineTablesOnly` if
-    //    we are compiling with "limited" debuginfo. However, some of the
-    //    existing tools relied on slightly more debuginfo being generated than
-    //    would be the case with `LineTablesOnly`, and we did not want to break
-    //    these tools in a "drive-by fix", without a good idea or plan about
-    //    what limited debuginfo should exactly look like. So for now we keep
-    //    the emission kind as `FullDebug`.
-    //
-    //    See https://github.com/rust-lang/rust/issues/60020 for details.
-    let kind = DebugEmissionKind::FullDebug;
-    assert!(tcx.sess.opts.debuginfo != DebugInfo::None);
+    let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo);
 
     unsafe {
         let compile_unit_file = llvm::LLVMRustDIBuilderCreateFile(
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 5392534cfcb..41a75c9d775 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -402,7 +402,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             cx: &CodegenCx<'ll, 'tcx>,
             fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
         ) -> &'ll DIArray {
-            if cx.sess().opts.debuginfo == DebugInfo::Limited {
+            if cx.sess().opts.debuginfo != DebugInfo::Full {
                 return create_DIArray(DIB(cx), &[]);
             }
 
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 0d63e634ad8..556c6602ff4 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -946,15 +946,27 @@ pub mod debuginfo {
         NoDebug,
         FullDebug,
         LineTablesOnly,
+        DebugDirectivesOnly,
     }
 
     impl DebugEmissionKind {
         pub fn from_generic(kind: rustc_session::config::DebugInfo) -> Self {
+            // We should be setting LLVM's emission kind to `LineTablesOnly` if
+            // we are compiling with "limited" debuginfo. However, some of the
+            // existing tools relied on slightly more debuginfo being generated than
+            // would be the case with `LineTablesOnly`, and we did not want to break
+            // these tools in a "drive-by fix", without a good idea or plan about
+            // what limited debuginfo should exactly look like. So for now we are
+            // instead adding a new debuginfo option "line-tables-only" so as to
+            // not break anything and to allow users to have 'limited' debug info.
+            //
+            // See https://github.com/rust-lang/rust/issues/60020 for details.
             use rustc_session::config::DebugInfo;
             match kind {
                 DebugInfo::None => DebugEmissionKind::NoDebug,
-                DebugInfo::Limited => DebugEmissionKind::LineTablesOnly,
-                DebugInfo::Full => DebugEmissionKind::FullDebug,
+                DebugInfo::LineDirectivesOnly => DebugEmissionKind::DebugDirectivesOnly,
+                DebugInfo::LineTablesOnly => DebugEmissionKind::LineTablesOnly,
+                DebugInfo::Limited | DebugInfo::Full => DebugEmissionKind::FullDebug,
             }
         }
     }
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 69bb00f804d..65dfc325a11 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -1121,9 +1121,12 @@ impl<'a> Linker for EmLinker<'a> {
 
     fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) {
         // Preserve names or generate source maps depending on debug info
+        // For more information see https://emscripten.org/docs/tools_reference/emcc.html#emcc-g
         self.cmd.arg(match self.sess.opts.debuginfo {
             DebugInfo::None => "-g0",
-            DebugInfo::Limited => "--profiling-funcs",
+            DebugInfo::Limited | DebugInfo::LineTablesOnly | DebugInfo::LineDirectivesOnly => {
+                "--profiling-funcs"
+            }
             DebugInfo::Full => "-g",
         });
     }
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index eb5990507fb..10dfd32d418 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -5,6 +5,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::profiling::TimePassesFormat;
 use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
 use rustc_session::config::rustc_optgroups;
+use rustc_session::config::DebugInfo;
 use rustc_session::config::Input;
 use rustc_session::config::InstrumentXRay;
 use rustc_session::config::TraitSolver;
@@ -574,7 +575,7 @@ fn test_codegen_options_tracking_hash() {
     tracked!(code_model, Some(CodeModel::Large));
     tracked!(control_flow_guard, CFGuard::Checks);
     tracked!(debug_assertions, Some(true));
-    tracked!(debuginfo, 0xdeadbeef);
+    tracked!(debuginfo, DebugInfo::Limited);
     tracked!(embed_bitcode, false);
     tracked!(force_frame_pointers, Some(false));
     tracked!(force_unwind_tables, Some(true));
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index e3493caaaf7..6a2fd5aa6e6 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -682,6 +682,7 @@ enum class LLVMRustDebugEmissionKind {
   NoDebug,
   FullDebug,
   LineTablesOnly,
+  DebugDirectivesOnly,
 };
 
 static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind) {
@@ -692,6 +693,8 @@ static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind)
     return DICompileUnit::DebugEmissionKind::FullDebug;
   case LLVMRustDebugEmissionKind::LineTablesOnly:
     return DICompileUnit::DebugEmissionKind::LineTablesOnly;
+  case LLVMRustDebugEmissionKind::DebugDirectivesOnly:
+    return DICompileUnit::DebugEmissionKind::DebugDirectivesOnly;
   default:
     report_fatal_error("bad DebugEmissionKind.");
   }
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 485c3f55462..1d8fedb8bd7 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -260,6 +260,8 @@ pub enum SymbolManglingVersion {
 #[derive(Clone, Copy, Debug, PartialEq, Hash)]
 pub enum DebugInfo {
     None,
+    LineDirectivesOnly,
+    LineTablesOnly,
     Limited,
     Full,
 }
@@ -1979,11 +1981,7 @@ fn parse_opt_level(
     }
 }
 
-fn select_debuginfo(
-    matches: &getopts::Matches,
-    cg: &CodegenOptions,
-    error_format: ErrorOutputType,
-) -> DebugInfo {
+fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInfo {
     let max_g = matches.opt_positions("g").into_iter().max();
     let max_c = matches
         .opt_strs_pos("C")
@@ -1993,24 +1991,7 @@ fn select_debuginfo(
             if let Some("debuginfo") = s.split('=').next() { Some(i) } else { None }
         })
         .max();
-    if max_g > max_c {
-        DebugInfo::Full
-    } else {
-        match cg.debuginfo {
-            0 => DebugInfo::None,
-            1 => DebugInfo::Limited,
-            2 => DebugInfo::Full,
-            arg => {
-                early_error(
-                    error_format,
-                    &format!(
-                        "debug info level needs to be between \
-                         0-2 (instead was `{arg}`)"
-                    ),
-                );
-            }
-        }
-    }
+    if max_g > max_c { DebugInfo::Full } else { cg.debuginfo }
 }
 
 pub(crate) fn parse_assert_incr_state(
@@ -2498,7 +2479,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     // to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
     // for more details.
     let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
-    let debuginfo = select_debuginfo(matches, &cg, error_format);
+    let debuginfo = select_debuginfo(matches, &cg);
 
     let mut search_paths = vec![];
     for s in &matches.opt_strs("L") {
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index be5d4fca7a0..631dd0a2146 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -377,6 +377,7 @@ mod desc {
     pub const parse_cfguard: &str =
         "either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
     pub const parse_cfprotection: &str = "`none`|`no`|`n` (default), `branch`, `return`, or `full`|`yes`|`y` (equivalent to `branch` and `return`)";
+    pub const parse_debuginfo: &str = "either an integer (0, 1, 2), `none`, `line-directives-only`, `line-tables-only`, `limited`, or `full`";
     pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`";
     pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of();
     pub const parse_optimization_fuel: &str = "crate=integer";
@@ -767,6 +768,18 @@ mod parse {
         true
     }
 
+    pub(crate) fn parse_debuginfo(slot: &mut DebugInfo, v: Option<&str>) -> bool {
+        match v {
+            Some("0") | Some("none") => *slot = DebugInfo::None,
+            Some("line-directives-only") => *slot = DebugInfo::LineDirectivesOnly,
+            Some("line-tables-only") => *slot = DebugInfo::LineTablesOnly,
+            Some("1") | Some("limited") => *slot = DebugInfo::Limited,
+            Some("2") | Some("full") => *slot = DebugInfo::Full,
+            _ => return false,
+        }
+        true
+    }
+
     pub(crate) fn parse_linker_flavor(slot: &mut Option<LinkerFlavorCli>, v: Option<&str>) -> bool {
         match v.and_then(LinkerFlavorCli::from_str) {
             Some(lf) => *slot = Some(lf),
@@ -1217,9 +1230,9 @@ options! {
         "use Windows Control Flow Guard (default: no)"),
     debug_assertions: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "explicitly enable the `cfg(debug_assertions)` directive"),
-    debuginfo: usize = (0, parse_number, [TRACKED],
-        "debug info emission level (0 = no debug info, 1 = line tables only, \
-        2 = full debug info with variable and type information; default: 0)"),
+    debuginfo: DebugInfo = (DebugInfo::None, parse_debuginfo, [TRACKED],
+        "debug info emission level (0-2, none, line-directives-only, \
+        line-tables-only, limited, or full; default: 0)"),
     default_linker_libraries: bool = (false, parse_bool, [UNTRACKED],
         "allow the linker to link its default libraries (default: no)"),
     embed_bitcode: bool = (true, parse_bool, [TRACKED],
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index c7f120dafea..62347f169a5 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -71,9 +71,11 @@ If not specified, debug assertions are automatically enabled only if the
 This flag controls the generation of debug information. It takes one of the
 following values:
 
-* `0`: no debug info at all (the default).
-* `1`: line tables only.
-* `2`: full debug info.
+* `0` or `none`: no debug info at all (the default).
+* `line-directives-only`: line info directives only. For the nvptx* targets this enables [profiling](https://reviews.llvm.org/D46061). For other use cases, `line-tables-only` is the better, more compatible choice.
+* `line-tables-only`: line tables only. Generates the minimal amount of debug info for backtraces with filename/line number info, but not anything else, i.e. no variable or function parameter info.
+* `1` or `limited`: debug info without type or variable-level information.
+* `2` or `full`: full debug info.
 
 Note: The [`-g` flag][option-g-debug] is an alias for `-C debuginfo=2`.
 
diff --git a/tests/codegen/debug-limited.rs b/tests/codegen/debug-limited.rs
new file mode 100644
index 00000000000..48d676887fd
--- /dev/null
+++ b/tests/codegen/debug-limited.rs
@@ -0,0 +1,27 @@
+// Verify that the limited debuginfo option emits llvm's FullDebugInfo, but no type info.
+//
+// compile-flags: -C debuginfo=limited
+
+#[repr(C)]
+struct StructType {
+    a: i64,
+    b: i32,
+}
+
+extern "C" {
+    fn creator() -> *mut StructType;
+    fn save(p: *const StructType);
+}
+
+fn main() {
+    unsafe {
+        let value: &mut StructType = &mut *creator();
+        value.a = 7;
+        save(value as *const StructType)
+    }
+}
+
+// CHECK: !DICompileUnit
+// CHECK: emissionKind: FullDebug
+// CHECK: !DILocation
+// CHECK-NOT: !DIBasicType
diff --git a/tests/codegen/debug-line-directives-only.rs b/tests/codegen/debug-line-directives-only.rs
new file mode 100644
index 00000000000..750bdd49de0
--- /dev/null
+++ b/tests/codegen/debug-line-directives-only.rs
@@ -0,0 +1,27 @@
+// Verify that the only debuginfo generated are the line directives.
+//
+// compile-flags: -C debuginfo=line-directives-only
+
+#[repr(C)]
+struct StructType {
+    a: i64,
+    b: i32,
+}
+
+extern "C" {
+    fn creator() -> *mut StructType;
+    fn save(p: *const StructType);
+}
+
+fn main() {
+    unsafe {
+        let value: &mut StructType = &mut *creator();
+        value.a = 7;
+        save(value as *const StructType)
+    }
+}
+
+// CHECK: !DICompileUnit
+// CHECK: emissionKind: DebugDirectivesOnly
+// CHECK: !DILocation
+// CHECK-NOT: !DIBasicType
diff --git a/tests/codegen/debug-line-tables-only.rs b/tests/codegen/debug-line-tables-only.rs
new file mode 100644
index 00000000000..3ed165a6f69
--- /dev/null
+++ b/tests/codegen/debug-line-tables-only.rs
@@ -0,0 +1,27 @@
+// Verify that the only debuginfo generated are the line tables.
+//
+// compile-flags: -C debuginfo=line-tables-only
+
+#[repr(C)]
+struct StructType {
+    a: i64,
+    b: i32,
+}
+
+extern "C" {
+    fn creator() -> *mut StructType;
+    fn save(p: *const StructType);
+}
+
+fn main() {
+    unsafe {
+        let value: &mut StructType = &mut *creator();
+        value.a = 7;
+        save(value as *const StructType)
+    }
+}
+
+// CHECK: !DICompileUnit
+// CHECK: emissionKind: LineTablesOnly
+// CHECK: !DILocation
+// CHECK-NOT: !DIBasicType
diff --git a/tests/rustdoc-ui/c-help.stdout b/tests/rustdoc-ui/c-help.stdout
index 75b2e2a2a43..0bd2d73efee 100644
--- a/tests/rustdoc-ui/c-help.stdout
+++ b/tests/rustdoc-ui/c-help.stdout
@@ -3,7 +3,7 @@
     -C            codegen-units=val -- divide crate into N units to optimize in parallel
     -C       control-flow-guard=val -- use Windows Control Flow Guard (default: no)
     -C         debug-assertions=val -- explicitly enable the `cfg(debug_assertions)` directive
-    -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)
+    -C                debuginfo=val -- debug info emission level (0-2, none, line-directives-only, line-tables-only, limited, or full; default: 0)
     -C default-linker-libraries=val -- allow the linker to link its default libraries (default: no)
     -C            embed-bitcode=val -- emit bitcode in rlibs (default: yes)
     -C           extra-filename=val -- extra data to put in each output filename