Skip to content

Commit 43db461

Browse files
[DWARF] Fix "simulated" DWARF (#10681)
* Add a test Relying on the implementation detail of LLVM not adding DWARF for module-level inline asm is a bit ugly, but it is simpler than twisting the "build system" we now have for C to build an intermediate object without "-g". * Fix simulated DWARF We need to record the correct ranges for the CU and include an offset zero entry in the line table, otherwise LLDB won't class our functions as "having debug info".
1 parent 5614b80 commit 43db461

File tree

3 files changed

+60
-20
lines changed

3 files changed

+60
-20
lines changed

crates/cranelift/src/debug/transform/simulate.rs

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,32 @@ fn generate_line_info(
6969

7070
for (symbol, map) in maps {
7171
let base_addr = map.offset;
72-
out_program.begin_sequence(Some(write::Address::Symbol { symbol, addend: 0 }));
72+
out_program.begin_sequence(Some(write::Address::Symbol {
73+
symbol,
74+
addend: base_addr as i64,
75+
}));
76+
77+
// Always emit a row for offset zero - debuggers expect this.
78+
out_program.row().address_offset = 0;
79+
out_program.row().file = file_index;
80+
out_program.row().line = 0; // Special line number for non-user code.
81+
out_program.row().discriminator = 1;
82+
out_program.row().is_statement = true;
83+
out_program.generate_row();
84+
85+
let mut is_prologue_end = true;
7386
for addr_map in map.addresses.iter() {
7487
let address_offset = (addr_map.generated - base_addr) as u64;
7588
out_program.row().address_offset = address_offset;
76-
out_program.row().op_index = 0;
77-
out_program.row().file = file_index;
7889
let wasm_offset = w.code_section_offset + addr_map.wasm;
7990
out_program.row().line = wasm_offset;
80-
out_program.row().column = 0;
8191
out_program.row().discriminator = 1;
82-
out_program.row().is_statement = true;
83-
out_program.row().basic_block = false;
84-
out_program.row().prologue_end = false;
85-
out_program.row().epilogue_begin = false;
86-
out_program.row().isa = 0;
92+
out_program.row().prologue_end = is_prologue_end;
8793
out_program.generate_row();
94+
95+
is_prologue_end = false;
8896
}
89-
let end_addr = (map.offset + map.len - 1) as u64;
97+
let end_addr = (base_addr + map.len - 1) as u64;
9098
out_program.end_sequence(end_addr);
9199
}
92100

@@ -345,6 +353,7 @@ pub fn generate_simulated_dwarf(
345353
};
346354

347355
let wasm_types = add_wasm_types(unit, root_id, out_strings);
356+
let mut unit_ranges = vec![];
348357
for (module, index) in compilation.indexes().collect::<Vec<_>>() {
349358
let (symbol, _) = compilation.function(module, index);
350359
if translated.contains(&symbol) {
@@ -353,21 +362,22 @@ pub fn generate_simulated_dwarf(
353362

354363
let addr_tr = &addr_tr[module];
355364
let map = &addr_tr.map()[index];
356-
let start = map.offset as u64;
357-
let end = start + map.len as u64;
358365
let die_id = unit.add(root_id, gimli::DW_TAG_subprogram);
359366
let die = unit.get_mut(die_id);
360-
die.set(
361-
gimli::DW_AT_low_pc,
362-
write::AttributeValue::Address(write::Address::Symbol {
363-
symbol,
364-
addend: start as i64,
365-
}),
366-
);
367+
let low_pc = write::Address::Symbol {
368+
symbol,
369+
addend: map.offset as i64,
370+
};
371+
let code_length = map.len as u64;
372+
die.set(gimli::DW_AT_low_pc, write::AttributeValue::Address(low_pc));
367373
die.set(
368374
gimli::DW_AT_high_pc,
369-
write::AttributeValue::Udata(end - start),
375+
write::AttributeValue::Udata(code_length),
370376
);
377+
unit_ranges.push(write::Range::StartLength {
378+
begin: low_pc,
379+
length: code_length,
380+
});
371381

372382
let translation = &compilation.translations[module];
373383
let func_index = translation.module.func_index(index);
@@ -412,6 +422,11 @@ pub fn generate_simulated_dwarf(
412422
isa,
413423
)?;
414424
}
425+
let unit_ranges_id = unit.ranges.add(write::RangeList(unit_ranges));
426+
unit.get_mut(root_id).set(
427+
gimli::DW_AT_ranges,
428+
write::AttributeValue::RangeListRef(unit_ranges_id),
429+
);
415430

416431
Ok(())
417432
}

crates/test-programs/src/bin/dwarf_generic.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,26 @@ int TestInstanceMethod() {
6363
return 0;
6464
}
6565

66+
__asm("FunctionWithoutWasmDWARF:\n"
67+
".global FunctionWithoutWasmDWARF\n"
68+
".functype FunctionWithoutWasmDWARF (i32, i32) -> (i32)\n"
69+
"local.get 0\n"
70+
"local.get 1\n"
71+
"i32.div_u\n"
72+
"end_function\n");
73+
extern "C" int FunctionWithoutWasmDWARF(int a, int b);
74+
75+
int TestFunctionWithoutWasmDWARF() {
76+
debug_break();
77+
int x = FunctionWithoutWasmDWARF(9, 10);
78+
return x == 0 ? 0 : 4;
79+
}
80+
6681
int main() {
6782
int exitCode = 0;
6883
exitCode += TestClassDefinitionSpreadAcrossCompileUnits();
6984
exitCode += TestInheritance();
7085
exitCode += TestInstanceMethod();
86+
exitCode += TestFunctionWithoutWasmDWARF();
7187
return exitCode;
7288
}

tests/all/debug/lldb.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,12 @@ c
206206
p __this->BaseValue + __this->DerivedValue
207207
c
208208
p __this->BaseValue + __this->DerivedValue
209+
c
210+
f
211+
n
212+
s
213+
v var0
214+
v var1
209215
c"#,
210216
)?;
211217

@@ -227,6 +233,9 @@ check: stop reason = breakpoint 1.1
227233
check: 7
228234
check: stop reason = breakpoint 1.1
229235
check: 8
236+
check: stop reason = breakpoint 1.1
237+
check: 9
238+
check: 10
230239
check: exited with status = 0
231240
"#,
232241
)?;

0 commit comments

Comments
 (0)