Skip to content

Instantly share code, notes, and snippets.

@andrewrk
Created February 20, 2023 16:20
Show Gist options
  • Star 26 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andrewrk/752a1f4db1a3327ee21f684cc87026e7 to your computer and use it in GitHub Desktop.
Save andrewrk/752a1f4db1a3327ee21f684cc87026e7 to your computer and use it in GitHub Desktop.
sprinkling a little zig into a C project to help with debugging
const std = @import("std");
pub fn build(b: *std.Build) void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b.standardTargetOptions(.{});
// Standard optimization options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
// set a preferred release mode, allowing the user to decide how to optimize.
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "example",
.target = target,
.optimize = optimize,
// In this case the main source file is merely a path, however, in more
// complicated build scripts, this could be a generated file.
.root_source_file = .{ .path = "helper.zig" },
});
exe.addCSourceFiles(&.{"foo.c"}, &.{"-std=c99"});
exe.linkLibC();
// This declares intent for the executable to be installed into the
// standard location when the user invokes the "install" step (the default
// step when running `zig build`).
exe.install();
}
static void bar() {
char *ptr = 0;
*ptr = 1;
}
void setup_debug_handlers(void);
int main(int argc, char **argv) {
setup_debug_handlers();
bar();
return 0;
}
const std = @import("std");
export fn setup_debug_handlers() void {
std.debug.maybeEnableSegfaultHandler();
}
export fn dump_stack_trace() void {
std.debug.dumpCurrentStackTrace(@returnAddress());
}
/// Communicate to zig that main() will be provided elsewhere.
pub const _start = {};
andy@ark ~/t/abc> zig build
andy@ark ~/t/abc> ./zig-out/bin/example
Illegal instruction at address 0x20bc5e
/home/andy/tmp/abc/foo.c:3:10: 0x20bc5e in bar (/home/andy/tmp/abc/foo.c)
*ptr = 1;
^
/home/andy/tmp/abc/foo.c:10:5: 0x20bc2f in main (/home/andy/tmp/abc/foo.c)
bar();
^
???:?:?: 0x7fdea03da24d in ??? (???)
???:?:?: 0x0 in ??? (???)
fish: Job 1, './zig-out/bin/example' terminated by signal SIGABRT (Abort)
@GavinRay97
Copy link

Wow, brilliant, thanks a bunch! 🙏

@franciscod
Copy link

Is there any way of having this kind of stacktrace when crosscompiling to windows and then running via wine? I can't get it to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment