From 5d5e67a9661897d3bc0862b27104c651caffd10b Mon Sep 17 00:00:00 2001 From: MaulingMonkey Date: Thu, 13 Jul 2017 10:03:07 -0700 Subject: [PATCH 1/5] Embed any available .natvis files into the pdb. --- src/librustc_trans/back/linker.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index 0b15886083a4e..0afb354185c31 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -475,6 +475,31 @@ impl<'a> Linker for MsvcLinker<'a> { // This will cause the Microsoft linker to generate a PDB file // from the CodeView line tables in the object files. self.cmd.arg("/DEBUG"); + + // This will cause the Microsoft linker to embed .natvis info into the the PDB file + let sysroot = self.sess.sysroot(); + let natvis_dir_path = sysroot.join("lib\\rustlib\\etc"); + if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) { + for entry in natvis_dir { + match entry { + Ok(entry) => { + let path = entry.path(); + if let Some(ext) = path.extension() { + if ext == OsStr::new("natvis") { + if let Some(natvis_path_str) = path.to_str() { + self.cmd.arg(&format!("/NATVIS:{}",natvis_path_str)); + } else { + self.sess.warn(&format!("natvis path not unicode: {:?}", path)); + } + } + } + }, + Err(err) => { + self.sess.warn(&format!("error enumerating natvis directory: {}", err)); + }, + } + } + } } // Currently the compiler doesn't use `dllexport` (an LLVM attribute) to From 8e10c4d55d5a21c879c01c57211579239f08d0b0 Mon Sep 17 00:00:00 2001 From: MaulingMonkey Date: Thu, 13 Jul 2017 10:04:43 -0700 Subject: [PATCH 2/5] Modify type names on MSVC to make strings and slices .natvis compatible. --- src/etc/natvis/intrinsic.natvis | 24 ++++++++++++++++++++++ src/librustc_trans/debuginfo/type_names.rs | 15 ++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 src/etc/natvis/intrinsic.natvis diff --git a/src/etc/natvis/intrinsic.natvis b/src/etc/natvis/intrinsic.natvis new file mode 100644 index 0000000000000..67be9769fb335 --- /dev/null +++ b/src/etc/natvis/intrinsic.natvis @@ -0,0 +1,24 @@ + + + + {data_ptr,[length]} + data_ptr,[length] + + length + + length + data_ptr + + + + + {{ length={length} }} + + length + + length + data_ptr + + + + diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index bfca4fec706ed..9ab5bc4a5a941 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -61,21 +61,27 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push(')'); }, ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => { - output.push('*'); + let is_like_msvc = cx.sess().target.target.options.is_like_msvc; + + if !is_like_msvc {output.push('*');} match mutbl { hir::MutImmutable => output.push_str("const "), hir::MutMutable => output.push_str("mut "), } push_debuginfo_type_name(cx, inner_type, true, output); + if is_like_msvc {output.push('*');} }, ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => { - output.push('&'); + let is_like_msvc = cx.sess().target.target.options.is_like_msvc; + + if !is_like_msvc {output.push('&');} if mutbl == hir::MutMutable { output.push_str("mut "); } push_debuginfo_type_name(cx, inner_type, true, output); + if is_like_msvc {output.push('*');} }, ty::TyArray(inner_type, len) => { output.push('['); @@ -84,9 +90,10 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push(']'); }, ty::TySlice(inner_type) => { - output.push('['); + let is_like_msvc = cx.sess().target.target.options.is_like_msvc; + output.push_str(if is_like_msvc {"slice<"} else {"["}); push_debuginfo_type_name(cx, inner_type, true, output); - output.push(']'); + output.push(if is_like_msvc {'>'} else {']'}); }, ty::TyDynamic(ref trait_data, ..) => { if let Some(principal) = trait_data.principal() { From cfc128cea4d10827be2178bac66dc23888c02092 Mon Sep 17 00:00:00 2001 From: MaulingMonkey Date: Wed, 19 Jul 2017 16:36:09 -0700 Subject: [PATCH 3/5] Expand one-liners, rename is_like_msvc to cpp_like_names and explain. --- src/librustc_trans/debuginfo/type_names.rs | 41 ++++++++++++++++------ 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index 9ab5bc4a5a941..6e36073107b56 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -36,6 +36,10 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>, qualified: bool, output: &mut String) { + // When targeting MSVC, emit C++ style type names for compatability with + // .natvis visualizers (and perhaps other existing native debuggers?) + let cpp_like_names = cx.sess().target.target.options.is_like_msvc; + match t.sty { ty::TyBool => output.push_str("bool"), ty::TyChar => output.push_str("char"), @@ -61,27 +65,33 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push(')'); }, ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => { - let is_like_msvc = cx.sess().target.target.options.is_like_msvc; - - if !is_like_msvc {output.push('*');} + if !cpp_like_names { + output.push('*'); + } match mutbl { hir::MutImmutable => output.push_str("const "), hir::MutMutable => output.push_str("mut "), } push_debuginfo_type_name(cx, inner_type, true, output); - if is_like_msvc {output.push('*');} + + if cpp_like_names { + output.push('*'); + } }, ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => { - let is_like_msvc = cx.sess().target.target.options.is_like_msvc; - - if !is_like_msvc {output.push('&');} + if !cpp_like_names { + output.push('&'); + } if mutbl == hir::MutMutable { output.push_str("mut "); } push_debuginfo_type_name(cx, inner_type, true, output); - if is_like_msvc {output.push('*');} + + if cpp_like_names { + output.push('*'); + } }, ty::TyArray(inner_type, len) => { output.push('['); @@ -90,10 +100,19 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push(']'); }, ty::TySlice(inner_type) => { - let is_like_msvc = cx.sess().target.target.options.is_like_msvc; - output.push_str(if is_like_msvc {"slice<"} else {"["}); + if cpp_like_names { + output.push_str("slice<"); + } else { + output.push('['); + } + push_debuginfo_type_name(cx, inner_type, true, output); - output.push(if is_like_msvc {'>'} else {']'}); + + if cpp_like_names { + output.push('>'); + } else { + output.push(']'); + } }, ty::TyDynamic(ref trait_data, ..) => { if let Some(principal) = trait_data.principal() { From 65b7908e109c05f5808971e6ceaee22eceb7db7d Mon Sep 17 00:00:00 2001 From: MaulingMonkey Date: Thu, 20 Jul 2017 16:09:24 -0700 Subject: [PATCH 4/5] Handle unicode natvis paths, simplify extension check to a single if. --- src/librustc_trans/back/linker.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index 0afb354185c31..d3f2d5923a3bc 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -484,14 +484,10 @@ impl<'a> Linker for MsvcLinker<'a> { match entry { Ok(entry) => { let path = entry.path(); - if let Some(ext) = path.extension() { - if ext == OsStr::new("natvis") { - if let Some(natvis_path_str) = path.to_str() { - self.cmd.arg(&format!("/NATVIS:{}",natvis_path_str)); - } else { - self.sess.warn(&format!("natvis path not unicode: {:?}", path)); - } - } + if path.extension() == Some("natvis".as_ref()) { + let mut arg = OsString::from("/NATVIS:"); + arg.push(path); + self.cmd.arg(arg); } }, Err(err) => { From 90a7cac8c8b1f4ee55c18e4ea21a8834a586c967 Mon Sep 17 00:00:00 2001 From: MaulingMonkey Date: Fri, 21 Jul 2017 03:39:56 -0700 Subject: [PATCH 5/5] *.natvis: Use s8 postfixes to correctly interpret rust strings as UTF-8. --- src/etc/natvis/intrinsic.natvis | 4 ++-- src/etc/natvis/liballoc.natvis | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/etc/natvis/intrinsic.natvis b/src/etc/natvis/intrinsic.natvis index 67be9769fb335..1611d8660ef65 100644 --- a/src/etc/natvis/intrinsic.natvis +++ b/src/etc/natvis/intrinsic.natvis @@ -1,8 +1,8 @@ - {data_ptr,[length]} - data_ptr,[length] + {data_ptr,[length]s8} + data_ptr,[length]s8 length diff --git a/src/etc/natvis/liballoc.natvis b/src/etc/natvis/liballoc.natvis index 1f6d17748ab00..e3d99e34b3579 100644 --- a/src/etc/natvis/liballoc.natvis +++ b/src/etc/natvis/liballoc.natvis @@ -42,8 +42,8 @@ - {*(char**)this,[vec.len]} - *(char**)this,[vec.len] + {*(char**)this,[vec.len]s8} + *(char**)this,[vec.len]s8 vec.len vec.buf.cap