aboutsummaryrefslogtreecommitdiff
path: root/lib/std/debug.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2024-03-18 22:39:59 -0700
committerAndrew Kelley <andrew@ziglang.org>2024-03-19 11:45:09 -0700
commitcd62005f19ff966d2c42de4daeb9a1e4b644bf76 (patch)
tree4bb316708afaf79c971808df792d8fe86274789b /lib/std/debug.zig
parent7057bffc14602add697eb566b83934b7ad3fd81c (diff)
downloadzig-cd62005f19ff966d2c42de4daeb9a1e4b644bf76.tar.gz
zig-cd62005f19ff966d2c42de4daeb9a1e4b644bf76.zip
extract std.posix from std.os
closes #5019
Diffstat (limited to 'lib/std/debug.zig')
-rw-r--r--lib/std/debug.zig117
1 files changed, 57 insertions, 60 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index f190e7fee2..7baa02fe74 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -3,7 +3,7 @@ const builtin = @import("builtin");
const math = std.math;
const mem = std.mem;
const io = std.io;
-const os = std.os;
+const posix = std.posix;
const fs = std.fs;
const testing = std.testing;
const elf = std.elf;
@@ -34,7 +34,7 @@ pub const sys_can_stack_trace = switch (builtin.cpu.arch) {
// "Non-Emscripten WebAssembly hasn't implemented __builtin_return_address".
.wasm32,
.wasm64,
- => builtin.os.tag == .emscripten,
+ => native_os == .emscripten,
// `@returnAddress()` is unsupported in LLVM 13.
.bpfel,
@@ -192,8 +192,8 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
}
}
-pub const have_ucontext = @hasDecl(os.system, "ucontext_t") and
- (builtin.os.tag != .linux or switch (builtin.cpu.arch) {
+pub const have_ucontext = @hasDecl(posix.system, "ucontext_t") and
+ (native_os != .linux or switch (builtin.cpu.arch) {
.mips, .mipsel, .mips64, .mips64el, .riscv64 => false,
else => true,
});
@@ -203,9 +203,9 @@ pub const have_ucontext = @hasDecl(os.system, "ucontext_t") and
/// use internal pointers within this structure. To make a copy, use `copyContext`.
pub const ThreadContext = blk: {
if (native_os == .windows) {
- break :blk std.os.windows.CONTEXT;
+ break :blk windows.CONTEXT;
} else if (have_ucontext) {
- break :blk os.ucontext_t;
+ break :blk posix.ucontext_t;
} else {
break :blk void;
}
@@ -228,9 +228,9 @@ pub fn relocateContext(context: *ThreadContext) void {
};
}
-pub const have_getcontext = @hasDecl(os.system, "getcontext") and
- builtin.os.tag != .openbsd and
- (builtin.os.tag != .linux or switch (builtin.cpu.arch) {
+pub const have_getcontext = @hasDecl(posix.system, "getcontext") and
+ native_os != .openbsd and
+ (native_os != .linux or switch (builtin.cpu.arch) {
.x86,
.x86_64,
=> true,
@@ -249,7 +249,7 @@ pub inline fn getContext(context: *ThreadContext) bool {
return true;
}
- const result = have_getcontext and os.system.getcontext(context) == 0;
+ const result = have_getcontext and posix.system.getcontext(context) == 0;
if (native_os == .macos) {
assert(context.mcsize == @sizeOf(std.c.mcontext_t));
@@ -470,12 +470,12 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize
const stderr = io.getStdErr().writer();
if (builtin.single_threaded) {
- stderr.print("panic: ", .{}) catch os.abort();
+ stderr.print("panic: ", .{}) catch posix.abort();
} else {
const current_thread_id = std.Thread.getCurrentId();
- stderr.print("thread {} panic: ", .{current_thread_id}) catch os.abort();
+ stderr.print("thread {} panic: ", .{current_thread_id}) catch posix.abort();
}
- stderr.print("{s}\n", .{msg}) catch os.abort();
+ stderr.print("{s}\n", .{msg}) catch posix.abort();
if (trace) |t| {
dumpStackTrace(t.*);
}
@@ -491,14 +491,14 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize
// we're still holding the mutex but that's fine as we're going to
// call abort()
const stderr = io.getStdErr().writer();
- stderr.print("Panicked during a panic. Aborting.\n", .{}) catch os.abort();
+ stderr.print("Panicked during a panic. Aborting.\n", .{}) catch posix.abort();
},
else => {
// Panicked while printing "Panicked during a panic."
},
};
- os.abort();
+ posix.abort();
}
/// Must be called only after adding 1 to `panicking`. There are three callsites.
@@ -584,7 +584,7 @@ pub const StackIterator = struct {
};
}
- pub fn initWithContext(first_address: ?usize, debug_info: *DebugInfo, context: *const os.ucontext_t) !StackIterator {
+ pub fn initWithContext(first_address: ?usize, debug_info: *DebugInfo, context: *const posix.ucontext_t) !StackIterator {
// The implementation of DWARF unwinding on aarch64-macos is not complete. However, Apple mandates that
// the frame pointer register is always used, so on this platform we can safely use the FP-based unwinder.
if (comptime builtin.target.isDarwin() and native_arch == .aarch64) {
@@ -668,12 +668,11 @@ pub const StackIterator = struct {
const aligned_memory = @as([*]align(mem.page_size) u8, @ptrFromInt(aligned_address))[0..mem.page_size];
if (native_os == .windows) {
- const w = os.windows;
- var memory_info: w.MEMORY_BASIC_INFORMATION = undefined;
+ var memory_info: windows.MEMORY_BASIC_INFORMATION = undefined;
// The only error this function can throw is ERROR_INVALID_PARAMETER.
// supply an address that invalid i'll be thrown.
- const rc = w.VirtualQuery(aligned_memory, &memory_info, aligned_memory.len) catch {
+ const rc = windows.VirtualQuery(aligned_memory, &memory_info, aligned_memory.len) catch {
return false;
};
@@ -683,17 +682,15 @@ pub const StackIterator = struct {
}
// Free pages cannot be read, they are unmapped
- if (memory_info.State == w.MEM_FREE) {
+ if (memory_info.State == windows.MEM_FREE) {
return false;
}
return true;
- } else if (@hasDecl(os.system, "msync") and native_os != .wasi and native_os != .emscripten) {
- os.msync(aligned_memory, os.MSF.ASYNC) catch |err| {
+ } else if (@hasDecl(posix.system, "msync") and native_os != .wasi and native_os != .emscripten) {
+ posix.msync(aligned_memory, posix.MSF.ASYNC) catch |err| {
switch (err) {
- os.MSyncError.UnmappedMemory => {
- return false;
- },
+ error.UnmappedMemory => return false,
else => unreachable,
}
};
@@ -1296,7 +1293,7 @@ pub fn readElfDebugInfo(
}
var cwd_buf: [fs.MAX_PATH_BYTES]u8 = undefined;
- const cwd_path = os.realpath(".", &cwd_buf) catch break :blk;
+ const cwd_path = posix.realpath(".", &cwd_buf) catch break :blk;
// <global debug directory>/<absolute folder of current binary>/<gnu_debuglink>
for (global_debug_directories) |global_directory| {
@@ -1651,15 +1648,15 @@ fn mapWholeFile(file: File) ![]align(mem.page_size) const u8 {
defer file.close();
const file_len = math.cast(usize, try file.getEndPos()) orelse math.maxInt(usize);
- const mapped_mem = try os.mmap(
+ const mapped_mem = try posix.mmap(
null,
file_len,
- os.PROT.READ,
+ posix.PROT.READ,
.{ .TYPE = .SHARED },
file.handle,
0,
);
- errdefer os.munmap(mapped_mem);
+ errdefer posix.munmap(mapped_mem);
return mapped_mem;
}
@@ -1997,8 +1994,8 @@ pub const DebugInfo = struct {
} = .{ .address = address };
const CtxTy = @TypeOf(ctx);
- if (os.dl_iterate_phdr(&ctx, error{Found}, struct {
- fn callback(info: *os.dl_phdr_info, size: usize, context: *CtxTy) !void {
+ if (posix.dl_iterate_phdr(&ctx, error{Found}, struct {
+ fn callback(info: *posix.dl_phdr_info, size: usize, context: *CtxTy) !void {
_ = size;
if (context.address < info.dlpi_addr) return;
const phdrs = info.dlpi_phdr[0..info.dlpi_phnum];
@@ -2036,8 +2033,8 @@ pub const DebugInfo = struct {
} = .{ .address = address };
const CtxTy = @TypeOf(ctx);
- if (os.dl_iterate_phdr(&ctx, error{Found}, struct {
- fn callback(info: *os.dl_phdr_info, size: usize, context: *CtxTy) !void {
+ if (posix.dl_iterate_phdr(&ctx, error{Found}, struct {
+ fn callback(info: *posix.dl_phdr_info, size: usize, context: *CtxTy) !void {
_ = size;
// The base address is too high
if (context.address < info.dlpi_addr)
@@ -2159,7 +2156,7 @@ pub const ModuleDebugInfo = switch (native_os) {
}
self.ofiles.deinit();
allocator.free(self.symbols);
- os.munmap(self.mapped_memory);
+ posix.munmap(self.mapped_memory);
}
fn loadOFile(self: *@This(), allocator: mem.Allocator, o_file_path: []const u8) !*OFileInfo {
@@ -2433,8 +2430,8 @@ pub const ModuleDebugInfo = switch (native_os) {
pub fn deinit(self: *@This(), allocator: mem.Allocator) void {
self.dwarf.deinit(allocator);
- os.munmap(self.mapped_memory);
- if (self.external_mapped_memory) |m| os.munmap(m);
+ posix.munmap(self.mapped_memory);
+ if (self.external_mapped_memory) |m| posix.munmap(m);
}
pub fn getSymbolAtAddress(self: *@This(), allocator: mem.Allocator, address: usize) !SymbolInfo {
@@ -2514,7 +2511,7 @@ pub const have_segfault_handling_support = switch (native_os) {
.windows,
=> true,
- .freebsd, .openbsd => @hasDecl(os.system, "ucontext_t"),
+ .freebsd, .openbsd => @hasDecl(std.c, "ucontext_t"),
else => false,
};
@@ -2529,11 +2526,11 @@ pub fn maybeEnableSegfaultHandler() void {
var windows_segfault_handle: ?windows.HANDLE = null;
-pub fn updateSegfaultHandler(act: ?*const os.Sigaction) error{OperationNotSupported}!void {
- try os.sigaction(os.SIG.SEGV, act, null);
- try os.sigaction(os.SIG.ILL, act, null);
- try os.sigaction(os.SIG.BUS, act, null);
- try os.sigaction(os.SIG.FPE, act, null);
+pub fn updateSegfaultHandler(act: ?*const posix.Sigaction) error{OperationNotSupported}!void {
+ try posix.sigaction(posix.SIG.SEGV, act, null);
+ try posix.sigaction(posix.SIG.ILL, act, null);
+ try posix.sigaction(posix.SIG.BUS, act, null);
+ try posix.sigaction(posix.SIG.FPE, act, null);
}
/// Attaches a global SIGSEGV handler which calls `@panic("segmentation fault");`
@@ -2545,10 +2542,10 @@ pub fn attachSegfaultHandler() void {
windows_segfault_handle = windows.kernel32.AddVectoredExceptionHandler(0, handleSegfaultWindows);
return;
}
- var act = os.Sigaction{
+ var act = posix.Sigaction{
.handler = .{ .sigaction = handleSegfaultPosix },
- .mask = os.empty_sigset,
- .flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
+ .mask = posix.empty_sigset,
+ .flags = (posix.SA.SIGINFO | posix.SA.RESTART | posix.SA.RESETHAND),
};
updateSegfaultHandler(&act) catch {
@@ -2564,16 +2561,16 @@ fn resetSegfaultHandler() void {
}
return;
}
- var act = os.Sigaction{
- .handler = .{ .handler = os.SIG.DFL },
- .mask = os.empty_sigset,
+ var act = posix.Sigaction{
+ .handler = .{ .handler = posix.SIG.DFL },
+ .mask = posix.empty_sigset,
.flags = 0,
};
// To avoid a double-panic, do nothing if an error happens here.
updateSegfaultHandler(&act) catch {};
}
-fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) noreturn {
+fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) noreturn {
// Reset to the default handler so that if a segfault happens in this handler it will crash
// the process. Also when this handler returns, the original instruction will be repeated
// and the resulting segfault will crash the process rather than continually dump stack traces.
@@ -2612,13 +2609,13 @@ fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const any
// We cannot allow the signal handler to return because when it runs the original instruction
// again, the memory may be mapped and undefined behavior would occur rather than repeating
// the segfault. So we simply abort here.
- os.abort();
+ posix.abort();
}
fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*const anyopaque) void {
const stderr = io.getStdErr().writer();
_ = switch (sig) {
- os.SIG.SEGV => if (native_arch == .x86_64 and native_os == .linux and code == 128) // SI_KERNEL
+ posix.SIG.SEGV => if (native_arch == .x86_64 and native_os == .linux and code == 128) // SI_KERNEL
// x86_64 doesn't have a full 64-bit virtual address space.
// Addresses outside of that address space are non-canonical
// and the CPU won't provide the faulting address to us.
@@ -2629,11 +2626,11 @@ fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*const anyo
stderr.print("General protection exception (no address available)\n", .{})
else
stderr.print("Segmentation fault at address 0x{x}\n", .{addr}),
- os.SIG.ILL => stderr.print("Illegal instruction at address 0x{x}\n", .{addr}),
- os.SIG.BUS => stderr.print("Bus error at address 0x{x}\n", .{addr}),
- os.SIG.FPE => stderr.print("Arithmetic exception at address 0x{x}\n", .{addr}),
+ posix.SIG.ILL => stderr.print("Illegal instruction at address 0x{x}\n", .{addr}),
+ posix.SIG.BUS => stderr.print("Bus error at address 0x{x}\n", .{addr}),
+ posix.SIG.FPE => stderr.print("Arithmetic exception at address 0x{x}\n", .{addr}),
else => unreachable,
- } catch os.abort();
+ } catch posix.abort();
switch (native_arch) {
.x86,
@@ -2641,7 +2638,7 @@ fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*const anyo
.arm,
.aarch64,
=> {
- const ctx: *const os.ucontext_t = @ptrCast(@alignCast(ctx_ptr));
+ const ctx: *const posix.ucontext_t = @ptrCast(@alignCast(ctx_ptr));
dumpStackTraceFromBase(ctx);
},
else => {},
@@ -2684,7 +2681,7 @@ fn handleSegfaultWindowsExtra(
dumpSegfaultInfoWindows(info, msg, label);
},
};
- os.abort();
+ posix.abort();
} else {
switch (msg) {
0 => panicImpl(null, exception_address, "{s}", label.?),
@@ -2707,7 +2704,7 @@ fn dumpSegfaultInfoWindows(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[
1 => stderr.print("Segmentation fault at address 0x{x}\n", .{info.ExceptionRecord.ExceptionInformation[1]}),
2 => stderr.print("Illegal instruction at address 0x{x}\n", .{info.ContextRecord.getRegs().ip}),
else => unreachable,
- } catch os.abort();
+ } catch posix.abort();
dumpStackTraceFromBase(info.ContextRecord);
}
@@ -2722,9 +2719,9 @@ pub fn dumpStackPointerAddr(prefix: []const u8) void {
test "manage resources correctly" {
if (builtin.strip_debug_info) return error.SkipZigTest;
- if (builtin.os.tag == .wasi) return error.SkipZigTest;
+ if (native_os == .wasi) return error.SkipZigTest;
- if (builtin.os.tag == .windows) {
+ if (native_os == .windows) {
// https://github.com/ziglang/zig/issues/13963
return error.SkipZigTest;
}