Skip to content

Commit 312563f

Browse files
committed
Use walk_chain for function span too
This is a correctness fix
1 parent 259b21f commit 312563f

File tree

1 file changed

+40
-45
lines changed

1 file changed

+40
-45
lines changed

src/debuginfo/line_info.rs

Lines changed: 40 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::path::{Component, Path};
55

66
use crate::prelude::*;
77

8+
use rustc_data_structures::sync::Lrc;
89
use rustc_span::{
910
FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm,
1011
};
@@ -47,9 +48,33 @@ fn osstr_as_utf8_bytes(path: &OsStr) -> &[u8] {
4748
}
4849
}
4950

50-
pub(crate) const MD5_LEN: usize = 16;
51+
fn get_span_loc(tcx: TyCtxt<'_>, function_span: Span, span: Span) -> (Lrc<SourceFile>, u64, u64) {
52+
// Based on https://github.com/rust-lang/rust/blob/e369d87b015a84653343032833d65d0545fd3f26/src/librustc_codegen_ssa/mir/mod.rs#L116-L131
53+
// In order to have a good line stepping behavior in debugger, we overwrite debug
54+
// locations of macro expansions with that of the outermost expansion site
55+
// (unless the crate is being compiled with `-Z debug-macros`).
56+
let span = if !span.from_expansion() || tcx.sess.opts.unstable_opts.debug_macros {
57+
span
58+
} else {
59+
// Walk up the macro expansion chain until we reach a non-expanded span.
60+
// We also stop at the function body level because no line stepping can occur
61+
// at the level above that.
62+
rustc_span::hygiene::walk_chain(span, function_span.ctxt())
63+
};
64+
65+
match tcx.sess.source_map().lookup_line(span.lo()) {
66+
Ok(SourceFileAndLine { sf: file, line }) => {
67+
let line_pos = file.line_begin_pos(span.lo());
68+
69+
(file, u64::try_from(line).unwrap() + 1, u64::from((span.lo() - line_pos).to_u32()) + 1)
70+
}
71+
Err(file) => (file, 0, 0),
72+
}
73+
}
74+
75+
const MD5_LEN: usize = 16;
5176

52-
pub(crate) fn make_file_info(hash: SourceFileHash) -> Option<FileInfo> {
77+
fn make_file_info(hash: SourceFileHash) -> Option<FileInfo> {
5378
if hash.kind == SourceFileHashAlgorithm::Md5 {
5479
let mut buf = [0u8; MD5_LEN];
5580
buf.copy_from_slice(hash.hash_bytes());
@@ -97,22 +122,6 @@ fn line_program_add_file(
97122
}
98123

99124
impl DebugContext {
100-
fn emit_location(&mut self, tcx: TyCtxt<'_>, entry_id: UnitEntryId, span: Span) {
101-
let loc = tcx.sess.source_map().lookup_char_pos(span.lo());
102-
103-
let file_id = line_program_add_file(
104-
&mut self.dwarf.unit.line_program,
105-
&mut self.dwarf.line_strings,
106-
&loc.file,
107-
);
108-
109-
let entry = self.dwarf.unit.get_mut(entry_id);
110-
111-
entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id)));
112-
entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(loc.line as u64));
113-
entry.set(gimli::DW_AT_decl_column, AttributeValue::Udata(loc.col.to_usize() as u64));
114-
}
115-
116125
pub(super) fn create_debug_lines(
117126
&mut self,
118127
tcx: TyCtxt<'_>,
@@ -136,31 +145,7 @@ impl DebugContext {
136145
}
137146
last_span = Some(span);
138147

139-
// Based on https://github.com/rust-lang/rust/blob/e369d87b015a84653343032833d65d0545fd3f26/src/librustc_codegen_ssa/mir/mod.rs#L116-L131
140-
// In order to have a good line stepping behavior in debugger, we overwrite debug
141-
// locations of macro expansions with that of the outermost expansion site
142-
// (unless the crate is being compiled with `-Z debug-macros`).
143-
let span = if !span.from_expansion() || tcx.sess.opts.unstable_opts.debug_macros {
144-
span
145-
} else {
146-
// Walk up the macro expansion chain until we reach a non-expanded span.
147-
// We also stop at the function body level because no line stepping can occur
148-
// at the level above that.
149-
rustc_span::hygiene::walk_chain(span, function_span.ctxt())
150-
};
151-
152-
let (file, line, col) = match tcx.sess.source_map().lookup_line(span.lo()) {
153-
Ok(SourceFileAndLine { sf: file, line }) => {
154-
let line_pos = file.line_begin_pos(span.lo());
155-
156-
(
157-
file,
158-
u64::try_from(line).unwrap() + 1,
159-
u64::from((span.lo() - line_pos).to_u32()) + 1,
160-
)
161-
}
162-
Err(file) => (file, 0, 0),
163-
};
148+
let (file, line, col) = get_span_loc(tcx, function_span, span);
164149

165150
// line_program_add_file is very slow.
166151
// Optimize for the common case of the current file not being changed.
@@ -204,14 +189,24 @@ impl DebugContext {
204189

205190
assert_ne!(func_end, 0);
206191

192+
let (function_file, function_line, function_col) =
193+
get_span_loc(tcx, function_span, function_span);
194+
195+
let function_file_id = line_program_add_file(
196+
&mut self.dwarf.unit.line_program,
197+
&mut self.dwarf.line_strings,
198+
&function_file,
199+
);
200+
207201
let entry = self.dwarf.unit.get_mut(entry_id);
208202
entry.set(
209203
gimli::DW_AT_low_pc,
210204
AttributeValue::Address(Address::Symbol { symbol, addend: 0 }),
211205
);
212206
entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end)));
213-
214-
self.emit_location(tcx, entry_id, function_span);
207+
entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(function_file_id)));
208+
entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(function_line));
209+
entry.set(gimli::DW_AT_decl_column, AttributeValue::Udata(function_col));
215210

216211
func_end
217212
}

0 commit comments

Comments
 (0)