Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define apicheck function to use a Zig panic #71

Open
natecraddock opened this issue Mar 20, 2024 · 2 comments
Open

Define apicheck function to use a Zig panic #71

natecraddock opened this issue Mar 20, 2024 · 2 comments

Comments

@natecraddock
Copy link
Owner

From a quick glance at the Lua sources, it may be possible to override the use of assert.h for the API check with a custom function. If so, this would make api checks much more easy to debug with zig panics and stack traces.

@robbielyman
Copy link
Collaborator

this is doable from consumer code:

pub fn main() void {
    // ...
    var act: std.posix.Sigaction = .{
        .handler = .{ .handler = handleAbrt },
        .mask = switch (builtin.os.tag) {
            .macos => 0,
            .linux => std.posix.empty_sigset,
            else => @compileError("os not supported"),
        },
        .flags = 0,
    };
    std.posix.sigaction(std.posix.SIG.ABRT, &act, null) catch {}; // if it doesn't work, we just crash the old way lol
    // ...
}

fn handleAbrt(_: c_int) callconv(.C) noreturn {
    @call(.always_inline, std.debug.panic, .{ "assertion failed!!", .{} });
}

@robbielyman
Copy link
Collaborator

here's a slightly better solution (zig 0.13, tested only on macOS so far):

pub fn main() void {
    // ...
    const act: if (builtin.mode == .Debug) std.posix.Sigaction = if (builtin.mode == .Debug) .{
        .handler = .{
            .handler = struct {
                fn handleAbrt(_: c_int) callconv(.C) noreturn {
                    std.debug.dumpCurrentStackTrace(@returnAddress());
                    std.process.exit(1);
                }
            }.handleAbrt,
         },
         .mask = if (builtin.os.tag == .linux) std.posix.empty_sigset else 0,
         .flags = 0,
     };
     if (builtin.mode == .Debug) try std.posix.sigaction(std.posix.SIG.ABRT, &act, null);
     // ...
}

this has the advantage that a stack trace is dumped in addition to the Lua library's assertion message. one disadvantage is that if other code (like for example std.debug.panicImpl) calls abort, you might see two stack traces. to guard against this, in seamstress v2 i put the stack trace dump inside a conditional which should only succeed if SIGABRT is raised by something other than std.debug.panicImpl

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants