Commit d97954a8ea
Changed files (6)
test
standalone
test/standalone/stack_iterator/build.zig
@@ -1,167 +0,0 @@
-const std = @import("std");
-const builtin = @import("builtin");
-
-pub fn build(b: *std.Build) void {
- const test_step = b.step("test", "Test it");
- b.default_step = test_step;
-
- const target = b.standardTargetOptions(.{});
- const optimize = b.standardOptimizeOption(.{});
-
- if (target.result.cpu.arch.isRISCV() and target.result.os.tag == .linux) {
- // https://github.com/ziglang/zig/issues/24310
- return;
- }
-
- // Unwinding with a frame pointer
- //
- // getcontext version: zig std
- //
- // Unwind info type:
- // - ELF: DWARF .debug_frame
- // - MachO: __unwind_info encodings:
- // - x86_64: RBP_FRAME
- // - aarch64: FRAME, DWARF
- {
- const exe = b.addExecutable(.{
- .name = "unwind_fp",
- .root_module = b.createModule(.{
- .root_source_file = b.path("unwind.zig"),
- .target = target,
- .optimize = optimize,
- .unwind_tables = if (target.result.os.tag.isDarwin()) .async else null,
- .omit_frame_pointer = false,
- }),
- });
-
- const run_cmd = b.addRunArtifact(exe);
- test_step.dependOn(&run_cmd.step);
- }
-
- // Unwinding without a frame pointer
- //
- // getcontext version: zig std
- //
- // Unwind info type:
- // - ELF: DWARF .eh_frame_hdr + .eh_frame
- // - MachO: __unwind_info encodings:
- // - x86_64: STACK_IMMD, STACK_IND
- // - aarch64: FRAMELESS, DWARF
- {
- const exe = b.addExecutable(.{
- .name = "unwind_nofp",
- .root_module = b.createModule(.{
- .root_source_file = b.path("unwind.zig"),
- .target = target,
- .optimize = optimize,
- .unwind_tables = .async,
- .omit_frame_pointer = true,
- }),
- // self-hosted lacks omit_frame_pointer support
- .use_llvm = true,
- });
-
- if (builtin.os.tag != .freebsd) {
- const run_cmd = b.addRunArtifact(exe);
- test_step.dependOn(&run_cmd.step);
- } else {
- test_step.dependOn(&exe.step);
- }
- }
-
- // https://github.com/ziglang/zig/issues/24522
- //// Unwinding through a C shared library without a frame pointer (libc)
- ////
- //// getcontext version: libc
- ////
- //// Unwind info type:
- //// - ELF: DWARF .eh_frame + .debug_frame
- //// - MachO: __unwind_info encodings:
- //// - x86_64: STACK_IMMD, STACK_IND
- //// - aarch64: FRAMELESS, DWARF
- //{
- // const c_shared_lib = b.addLibrary(.{
- // .linkage = .dynamic,
- // .name = "c_shared_lib",
- // .root_module = b.createModule(.{
- // .root_source_file = null,
- // .target = target,
- // .optimize = optimize,
- // .link_libc = true,
- // .strip = false,
- // }),
- // });
-
- // if (target.result.os.tag == .windows)
- // c_shared_lib.root_module.addCMacro("LIB_API", "__declspec(dllexport)");
-
- // c_shared_lib.root_module.addCSourceFile(.{
- // .file = b.path("shared_lib.c"),
- // .flags = &.{"-fomit-frame-pointer"},
- // });
-
- // const exe = b.addExecutable(.{
- // .name = "shared_lib_unwind",
- // .root_module = b.createModule(.{
- // .root_source_file = b.path("shared_lib_unwind.zig"),
- // .target = target,
- // .optimize = optimize,
- // .unwind_tables = if (target.result.os.tag.isDarwin()) .async else null,
- // .omit_frame_pointer = true,
- // }),
- // // zig objcopy doesn't support incremental binaries
- // .use_llvm = true,
- // });
-
- // exe.root_module.linkLibrary(c_shared_lib);
-
- // const run_cmd = b.addRunArtifact(exe);
- // test_step.dependOn(&run_cmd.step);
-
- // // Separate debug info ELF file
- // if (target.result.ofmt == .elf) {
- // const filename = b.fmt("{s}_stripped", .{exe.out_filename});
- // const stripped_exe = b.addObjCopy(exe.getEmittedBin(), .{
- // .basename = filename, // set the name for the debuglink
- // .compress_debug = true,
- // .strip = .debug,
- // .extract_to_separate_file = true,
- // });
-
- // const run_stripped = std.Build.Step.Run.create(b, b.fmt("run {s}", .{filename}));
- // run_stripped.addFileArg(stripped_exe.getOutput());
- // test_step.dependOn(&run_stripped.step);
- // }
- //}
-
- // Unwinding without libc/posix
- //
- // No "getcontext" or "ucontext_t"
- const no_os_targets = [_]std.Target.Os.Tag{ .freestanding, .other };
- inline for (no_os_targets) |os_tag| {
- const exe = b.addExecutable(.{
- .name = "unwind_freestanding",
- .root_module = b.createModule(.{
- .root_source_file = b.path("unwind_freestanding.zig"),
- .target = b.resolveTargetQuery(.{
- .cpu_arch = .x86_64,
- .os_tag = os_tag,
- }),
- .optimize = optimize,
- .unwind_tables = null,
- .omit_frame_pointer = false,
- }),
- // self-hosted lacks omit_frame_pointer support
- .use_llvm = true,
- });
-
- // This "freestanding" binary is runnable because it invokes the
- // Linux exit syscall directly.
- if (builtin.os.tag == .linux and builtin.cpu.arch == .x86_64) {
- const run_cmd = b.addRunArtifact(exe);
- test_step.dependOn(&run_cmd.step);
- } else {
- test_step.dependOn(&exe.step);
- }
- }
-}
test/standalone/stack_iterator/unwind.zig
@@ -1,101 +0,0 @@
-const std = @import("std");
-const builtin = @import("builtin");
-const fatal = std.process.fatal;
-
-noinline fn frame3(expected: *[4]usize, addr_buf: *[4]usize) std.builtin.StackTrace {
- expected[0] = @returnAddress();
- return std.debug.captureCurrentStackTrace(.{
- .first_address = @returnAddress(),
- .allow_unsafe_unwind = true,
- }, addr_buf);
-}
-
-noinline fn frame2(expected: *[4]usize, addr_buf: *[4]usize) std.builtin.StackTrace {
- // Exercise different __unwind_info / DWARF CFI encodings by forcing some registers to be restored
- if (builtin.target.ofmt != .c) {
- switch (builtin.target.cpu.arch) {
- .x86 => {
- if (builtin.omit_frame_pointer) {
- asm volatile (
- \\movl $3, %%ebx
- \\movl $1, %%ecx
- \\movl $2, %%edx
- \\movl $7, %%edi
- \\movl $6, %%esi
- \\movl $5, %%ebp
- ::: .{ .ebx = true, .ecx = true, .edx = true, .edi = true, .esi = true, .ebp = true });
- } else {
- asm volatile (
- \\movl $3, %%ebx
- \\movl $1, %%ecx
- \\movl $2, %%edx
- \\movl $7, %%edi
- \\movl $6, %%esi
- ::: .{ .ebx = true, .ecx = true, .edx = true, .edi = true, .esi = true });
- }
- },
- .x86_64 => {
- if (builtin.omit_frame_pointer) {
- asm volatile (
- \\movq $3, %%rbx
- \\movq $12, %%r12
- \\movq $13, %%r13
- \\movq $14, %%r14
- \\movq $15, %%r15
- \\movq $6, %%rbp
- ::: .{ .rbx = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .rbp = true });
- } else {
- asm volatile (
- \\movq $3, %%rbx
- \\movq $12, %%r12
- \\movq $13, %%r13
- \\movq $14, %%r14
- \\movq $15, %%r15
- ::: .{ .rbx = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true });
- }
- },
- else => {},
- }
- }
-
- expected[1] = @returnAddress();
- return frame3(expected, addr_buf);
-}
-
-noinline fn frame1(expected: *[4]usize, addr_buf: *[4]usize) std.builtin.StackTrace {
- expected[2] = @returnAddress();
-
- // Use a stack frame that is too big to encode in __unwind_info's stack-immediate encoding
- // to exercise the stack-indirect encoding path
- var pad: [std.math.maxInt(u8) * @sizeOf(usize) + 1]u8 = undefined;
- _ = std.mem.doNotOptimizeAway(&pad);
-
- return frame2(expected, addr_buf);
-}
-
-noinline fn frame0(expected: *[4]usize, addr_buf: *[4]usize) std.builtin.StackTrace {
- expected[3] = @returnAddress();
- return frame1(expected, addr_buf);
-}
-
-pub fn main() void {
- if (std.debug.cpu_context.Native == noreturn and builtin.omit_frame_pointer) {
- // Stack unwinding is impossible.
- return;
- }
-
- var expected: [4]usize = undefined;
- var addr_buf: [4]usize = undefined;
- const trace = frame0(&expected, &addr_buf);
- // There may be *more* than 4 frames (due to the caller of `main`); that's okay.
- if (trace.index < 4) {
- fatal("expected at least 4 frames, got '{d}':\n{f}", .{ trace.index, &trace });
- }
- if (!std.mem.eql(usize, trace.instruction_addresses, &expected)) {
- const expected_trace: std.builtin.StackTrace = .{
- .index = 4,
- .instruction_addresses = &expected,
- };
- fatal("expected trace:\n{f}\nactual trace:\n{f}", .{ &expected_trace, &trace });
- }
-}
test/standalone/stack_iterator/unwind_freestanding.zig
@@ -1,66 +0,0 @@
-//! Test StackIterator on 'freestanding' target. Based on unwind.zig.
-
-const std = @import("std");
-
-noinline fn frame3(expected: *[4]usize, addr_buf: *[4]usize) std.builtin.StackTrace {
- expected[0] = @returnAddress();
- return std.debug.captureCurrentStackTrace(.{
- .first_address = @returnAddress(),
- .allow_unsafe_unwind = true,
- }, addr_buf);
-}
-
-noinline fn frame2(expected: *[4]usize, addr_buf: *[4]usize) std.builtin.StackTrace {
- expected[1] = @returnAddress();
- return frame3(expected, addr_buf);
-}
-
-noinline fn frame1(expected: *[4]usize, addr_buf: *[4]usize) std.builtin.StackTrace {
- expected[2] = @returnAddress();
-
- // Use a stack frame that is too big to encode in __unwind_info's stack-immediate encoding
- // to exercise the stack-indirect encoding path
- var pad: [std.math.maxInt(u8) * @sizeOf(usize) + 1]u8 = undefined;
- _ = std.mem.doNotOptimizeAway(&pad);
-
- return frame2(expected, addr_buf);
-}
-
-noinline fn frame0(expected: *[4]usize, addr_buf: *[4]usize) std.builtin.StackTrace {
- expected[3] = @returnAddress();
- return frame1(expected, addr_buf);
-}
-
-/// No-OS entrypoint
-export fn _start() callconv(.withStackAlign(.c, 1)) noreturn {
- var expected: [4]usize = undefined;
- var addr_buf: [4]usize = undefined;
- const trace = frame0(&expected, &addr_buf);
-
- // Since we can't print from this freestanding test, we'll just use the exit
- // code to communicate error conditions.
-
- // Unlike `unwind.zig`, we can expect *exactly* 4 frames, as we are the
- // actual entry point and the frame pointer will be 0 on entry.
- if (trace.index != 4) exit(1);
- if (trace.instruction_addresses[0] != expected[0]) exit(2);
- if (trace.instruction_addresses[1] != expected[1]) exit(3);
- if (trace.instruction_addresses[2] != expected[2]) exit(4);
- if (trace.instruction_addresses[3] != expected[3]) exit(5);
-
- exit(0);
-}
-
-fn exit(code: u8) noreturn {
- // We are intentionally compiling with the target OS being "freestanding" to
- // exercise std.debug, but we still need to exit the process somehow; so do
- // the appropriate x86_64-linux syscall.
- asm volatile (
- \\movl $60, %%eax
- \\syscall
- :
- : [code] "{edi}" (code),
- : .{ .edi = true, .eax = true });
-
- unreachable;
-}
test/standalone/build.zig.zon
@@ -163,9 +163,6 @@
.zerolength_check = .{
.path = "zerolength_check",
},
- .stack_iterator = .{
- .path = "stack_iterator",
- },
.coff_dwarf = .{
.path = "coff_dwarf",
},