Skip to content

Commit 6a21875

Browse files
authored
Merge pull request ziglang#21230 from jacobly0/stack-trace
Dwarf: fix self-hosted stack traces
2 parents 31fef6f + 12275cf commit 6a21875

File tree

4 files changed

+542
-87
lines changed

4 files changed

+542
-87
lines changed

ci/x86_64-linux-debug.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ stage3-debug/bin/zig build \
6464

6565
stage3-debug/bin/zig build test docs \
6666
--maxrss 21000000000 \
67-
-Dlldb=$HOME/deps/lldb-zig/Debug-70b8227f1/bin/lldb \
67+
-Dlldb=$HOME/deps/lldb-zig/Debug-befcd57a8/bin/lldb \
6868
-fqemu \
6969
-fwasmtime \
7070
-Dstatic-llvm \

ci/x86_64-linux-release.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ stage3-release/bin/zig build \
6464

6565
stage3-release/bin/zig build test docs \
6666
--maxrss 21000000000 \
67-
-Dlldb=$HOME/deps/lldb-zig/Release-70b8227f1/bin/lldb \
67+
-Dlldb=$HOME/deps/lldb-zig/Release-befcd57a8/bin/lldb \
6868
-fqemu \
6969
-fwasmtime \
7070
-Dstatic-llvm \

lib/std/debug/Dwarf.zig

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -279,10 +279,11 @@ pub const Die = struct {
279279
};
280280
}
281281

282-
fn getAttrRef(self: *const Die, id: u64) !u64 {
282+
fn getAttrRef(self: *const Die, id: u64, unit_offset: u64, unit_len: u64) !u64 {
283283
const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
284284
return switch (form_value.*) {
285-
.ref => |value| value,
285+
.ref => |offset| if (offset < unit_len) unit_offset + offset else bad(),
286+
.ref_addr => |addr| addr,
286287
else => bad(),
287288
};
288289
}
@@ -428,14 +429,14 @@ pub const ExceptionFrameHeader = struct {
428429
};
429430

430431
const fde_entry_header = try EntryHeader.read(&eh_frame_fbr, if (eh_frame_len == null) ma else null, .eh_frame);
431-
if (!self.isValidPtr(u8, @intFromPtr(&fde_entry_header.entry_bytes[fde_entry_header.entry_bytes.len - 1]), ma, eh_frame_len)) return bad();
432+
if (fde_entry_header.entry_bytes.len > 0 and !self.isValidPtr(u8, @intFromPtr(&fde_entry_header.entry_bytes[fde_entry_header.entry_bytes.len - 1]), ma, eh_frame_len)) return bad();
432433
if (fde_entry_header.type != .fde) return bad();
433434

434435
// CIEs always come before FDEs (the offset is a subtraction), so we can assume this memory is readable
435436
const cie_offset = fde_entry_header.type.fde;
436437
try eh_frame_fbr.seekTo(cie_offset);
437438
const cie_entry_header = try EntryHeader.read(&eh_frame_fbr, if (eh_frame_len == null) ma else null, .eh_frame);
438-
if (!self.isValidPtr(u8, @intFromPtr(&cie_entry_header.entry_bytes[cie_entry_header.entry_bytes.len - 1]), ma, eh_frame_len)) return bad();
439+
if (cie_entry_header.entry_bytes.len > 0 and !self.isValidPtr(u8, @intFromPtr(&cie_entry_header.entry_bytes[cie_entry_header.entry_bytes.len - 1]), ma, eh_frame_len)) return bad();
439440
if (cie_entry_header.type != .cie) return bad();
440441

441442
cie.* = try CommonInformationEntry.parse(
@@ -942,27 +943,25 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator) ScanError!void {
942943
defer fbr.pos = after_die_offset;
943944

944945
// Follow the DIE it points to and repeat
945-
const ref_offset = try this_die_obj.getAttrRef(AT.abstract_origin);
946-
if (ref_offset > next_offset) return bad();
947-
try fbr.seekTo(this_unit_offset + ref_offset);
946+
const ref_offset = try this_die_obj.getAttrRef(AT.abstract_origin, this_unit_offset, next_offset);
947+
try fbr.seekTo(ref_offset);
948948
this_die_obj = (try parseDie(
949949
&fbr,
950950
attrs_bufs[2],
951-
abbrev_table,
951+
abbrev_table, // wrong abbrev table for different cu
952952
unit_header.format,
953953
)) orelse return bad();
954954
} else if (this_die_obj.getAttr(AT.specification)) |_| {
955955
const after_die_offset = fbr.pos;
956956
defer fbr.pos = after_die_offset;
957957

958958
// Follow the DIE it points to and repeat
959-
const ref_offset = try this_die_obj.getAttrRef(AT.specification);
960-
if (ref_offset > next_offset) return bad();
961-
try fbr.seekTo(this_unit_offset + ref_offset);
959+
const ref_offset = try this_die_obj.getAttrRef(AT.specification, this_unit_offset, next_offset);
960+
try fbr.seekTo(ref_offset);
962961
this_die_obj = (try parseDie(
963962
&fbr,
964963
attrs_bufs[2],
965-
abbrev_table,
964+
abbrev_table, // wrong abbrev table for different cu
966965
unit_header.format,
967966
)) orelse return bad();
968967
} else {
@@ -1494,7 +1493,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, compile_unit: *CompileUnit) !
14941493
}
14951494
} else {
14961495
const FileEntFmt = struct {
1497-
content_type_code: u8,
1496+
content_type_code: u16,
14981497
form_code: u16,
14991498
};
15001499
{
@@ -1539,7 +1538,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, compile_unit: *CompileUnit) !
15391538
if (file_name_entry_format_count > file_ent_fmt_buf.len) return bad();
15401539
for (file_ent_fmt_buf[0..file_name_entry_format_count]) |*ent_fmt| {
15411540
ent_fmt.* = .{
1542-
.content_type_code = try fbr.readUleb128(u8),
1541+
.content_type_code = try fbr.readUleb128(u16),
15431542
.form_code = try fbr.readUleb128(u16),
15441543
};
15451544
}

0 commit comments

Comments
 (0)