Skip to content

Commit 975c185

Browse files
committed
fix compilation on powerpc GNU systems
...which have a ucontext_t but not a PC register. The current stack unwinding implementation does not yet support this architecture. Also fix name of `std.debug.SelfInfo.openSelf` to remove redundancy. Also removed this hook into root providing an "openSelfDebugInfo" function. Sorry, this debugging code is not of sufficient quality to offer a plugin API right now.
1 parent 48d584e commit 975c185

File tree

6 files changed

+51
-41
lines changed

6 files changed

+51
-41
lines changed

lib/std/debug.zig

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ pub fn getSelfDebugInfo() !*SelfInfo {
8888
if (self_debug_info) |*info| {
8989
return info;
9090
} else {
91-
self_debug_info = try SelfInfo.openSelf(getDebugInfoAllocator());
91+
self_debug_info = try SelfInfo.open(getDebugInfoAllocator());
9292
return &self_debug_info.?;
9393
}
9494
}
@@ -573,17 +573,19 @@ pub const StackIterator = struct {
573573
pub fn initWithContext(first_address: ?usize, debug_info: *SelfInfo, context: *posix.ucontext_t) !StackIterator {
574574
// The implementation of DWARF unwinding on aarch64-macos is not complete. However, Apple mandates that
575575
// the frame pointer register is always used, so on this platform we can safely use the FP-based unwinder.
576-
if (builtin.target.isDarwin() and native_arch == .aarch64) {
576+
if (builtin.target.isDarwin() and native_arch == .aarch64)
577577
return init(first_address, context.mcontext.ss.fp);
578-
} else {
578+
579+
if (SelfInfo.supports_unwinding) {
579580
var iterator = init(first_address, null);
580581
iterator.unwind_state = .{
581582
.debug_info = debug_info,
582583
.dwarf_context = try SelfInfo.UnwindContext.init(debug_info.allocator, context),
583584
};
584-
585585
return iterator;
586586
}
587+
588+
return init(first_address, null);
587589
}
588590

589591
pub fn deinit(it: *StackIterator) void {
@@ -725,11 +727,13 @@ pub fn writeCurrentStackTrace(
725727
tty_config: io.tty.Config,
726728
start_addr: ?usize,
727729
) !void {
728-
var context: ThreadContext = undefined;
729-
const has_context = getContext(&context);
730730
if (native_os == .windows) {
731+
var context: ThreadContext = undefined;
732+
assert(getContext(&context));
731733
return writeStackTraceWindows(out_stream, debug_info, tty_config, &context, start_addr);
732734
}
735+
var context: ThreadContext = undefined;
736+
const has_context = getContext(&context);
733737

734738
var it = (if (has_context) blk: {
735739
break :blk StackIterator.initWithContext(start_addr, debug_info, &context) catch null;
@@ -1340,7 +1344,7 @@ test "manage resources correctly" {
13401344
}
13411345

13421346
const writer = std.io.null_writer;
1343-
var di = try SelfInfo.openSelf(testing.allocator);
1347+
var di = try SelfInfo.open(testing.allocator);
13441348
defer di.deinit();
13451349
try printSourceAtAddress(&di, writer, showMyTrace(), io.tty.detectConfig(std.io.getStdErr()));
13461350
}
@@ -1581,5 +1585,9 @@ pub inline fn inValgrind() bool {
15811585
}
15821586

15831587
test {
1588+
_ = &Dwarf;
1589+
_ = &MemoryAccessor;
1590+
_ = &Pdb;
1591+
_ = &SelfInfo;
15841592
_ = &dumpHex;
15851593
}

lib/std/debug/Dwarf.zig

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,3 +2023,27 @@ fn pcRelBase(field_ptr: usize, pc_rel_offset: i64) !usize {
20232023
return std.math.add(usize, field_ptr, @as(usize, @intCast(pc_rel_offset)));
20242024
}
20252025
}
2026+
2027+
pub fn supportsUnwinding(target: std.Target) bool {
2028+
return switch (target.cpu.arch) {
2029+
.x86 => switch (target.os.tag) {
2030+
.linux, .netbsd, .solaris, .illumos => true,
2031+
else => false,
2032+
},
2033+
.x86_64 => switch (target.os.tag) {
2034+
.linux, .netbsd, .freebsd, .openbsd, .macos, .ios, .solaris, .illumos => true,
2035+
else => false,
2036+
},
2037+
.arm => switch (target.os.tag) {
2038+
.linux => true,
2039+
else => false,
2040+
},
2041+
.aarch64 => switch (target.os.tag) {
2042+
.linux, .netbsd, .freebsd, .macos, .ios => true,
2043+
else => false,
2044+
},
2045+
// Unwinding is possible on other targets but this implementation does
2046+
// not support them...yet!
2047+
else => false,
2048+
};
2049+
}

lib/std/debug/Dwarf/abi.zig

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,14 @@ const mem = std.mem;
55
const posix = std.posix;
66
const Arch = std.Target.Cpu.Arch;
77

8-
pub fn supportsUnwinding(target: std.Target) bool {
9-
return switch (target.cpu.arch) {
10-
.x86 => switch (target.os.tag) {
11-
.linux, .netbsd, .solaris, .illumos => true,
12-
else => false,
13-
},
14-
.x86_64 => switch (target.os.tag) {
15-
.linux, .netbsd, .freebsd, .openbsd, .macos, .ios, .solaris, .illumos => true,
16-
else => false,
17-
},
18-
.arm => switch (target.os.tag) {
19-
.linux => true,
20-
else => false,
21-
},
22-
.aarch64 => switch (target.os.tag) {
23-
.linux, .netbsd, .freebsd, .macos, .ios => true,
24-
else => false,
25-
},
26-
else => false,
27-
};
28-
}
29-
30-
pub fn ipRegNum(arch: Arch) u8 {
8+
/// Returns `null` for CPU architectures without an instruction pointer register.
9+
pub fn ipRegNum(arch: Arch) ?u8 {
3110
return switch (arch) {
3211
.x86 => 8,
3312
.x86_64 => 16,
3413
.arm => 15,
3514
.aarch64 => 32,
36-
else => unreachable,
15+
else => null,
3716
};
3817
}
3918

lib/std/debug/Dwarf/expression.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,11 +1190,11 @@ test "DWARF expressions" {
11901190
mem.writeInt(usize, reg_bytes[0..@sizeOf(usize)], 0xee, native_endian);
11911191
(try abi.regValueNative(&thread_context, abi.fpRegNum(native_arch, reg_context), reg_context)).* = 1;
11921192
(try abi.regValueNative(&thread_context, abi.spRegNum(native_arch, reg_context), reg_context)).* = 2;
1193-
(try abi.regValueNative(&thread_context, abi.ipRegNum(native_arch), reg_context)).* = 3;
1193+
(try abi.regValueNative(&thread_context, abi.ipRegNum(native_arch).?, reg_context)).* = 3;
11941194

11951195
try b.writeBreg(writer, abi.fpRegNum(native_arch, reg_context), @as(usize, 100));
11961196
try b.writeBreg(writer, abi.spRegNum(native_arch, reg_context), @as(usize, 200));
1197-
try b.writeBregx(writer, abi.ipRegNum(native_arch), @as(usize, 300));
1197+
try b.writeBregx(writer, abi.ipRegNum(native_arch).?, @as(usize, 300));
11981198
try b.writeRegvalType(writer, @as(u8, 0), @as(usize, 400));
11991199

12001200
_ = try stack_machine.run(program.items, allocator, context, 0);

lib/std/debug/SelfInfo.zig

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,15 @@ allocator: Allocator,
3434
address_map: std.AutoHashMap(usize, *Module),
3535
modules: if (native_os == .windows) std.ArrayListUnmanaged(WindowsModule) else void,
3636

37-
pub const OpenSelfError = error{
37+
pub const OpenError = error{
3838
MissingDebugInfo,
3939
UnsupportedOperatingSystem,
4040
} || @typeInfo(@typeInfo(@TypeOf(SelfInfo.init)).Fn.return_type.?).ErrorUnion.error_set;
4141

42-
pub fn openSelf(allocator: Allocator) OpenSelfError!SelfInfo {
42+
pub fn open(allocator: Allocator) OpenError!SelfInfo {
4343
nosuspend {
4444
if (builtin.strip_debug_info)
4545
return error.MissingDebugInfo;
46-
if (@hasDecl(root, "os") and @hasDecl(root.os, "debug") and @hasDecl(root.os.debug, "openSelfDebugInfo")) {
47-
return root.os.debug.openSelfDebugInfo(allocator);
48-
}
4946
switch (native_os) {
5047
.linux,
5148
.freebsd,
@@ -1721,6 +1718,8 @@ pub const UnwindContext = struct {
17211718
allocator: Allocator,
17221719
thread_context: *std.debug.ThreadContext,
17231720
) !UnwindContext {
1721+
comptime assert(supports_unwinding);
1722+
17241723
const pc = stripInstructionPtrAuthCode(
17251724
(try regValueNative(thread_context, ip_reg_num, null)).*,
17261725
);
@@ -1982,8 +1981,8 @@ fn spRegNum(reg_context: Dwarf.abi.RegisterContext) u8 {
19821981
return Dwarf.abi.spRegNum(native_arch, reg_context);
19831982
}
19841983

1985-
const ip_reg_num = Dwarf.abi.ipRegNum(native_arch);
1986-
const supports_unwinding = Dwarf.abi.supportsUnwinding(builtin.target);
1984+
const ip_reg_num = Dwarf.abi.ipRegNum(native_arch).?;
1985+
pub const supports_unwinding = Dwarf.supportsUnwinding(builtin.target);
19871986

19881987
fn unwindFrameMachODwarf(
19891988
context: *UnwindContext,

test/standalone/coff_dwarf/main.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pub fn main() !void {
99
defer assert(gpa.deinit() == .ok);
1010
const allocator = gpa.allocator();
1111

12-
var debug_info = try std.debug.openSelfDebugInfo(allocator);
12+
var debug_info = try std.debug.SelfInfo.open(allocator);
1313
defer debug_info.deinit();
1414

1515
var add_addr: usize = undefined;

0 commit comments

Comments
 (0)