Skip to content

Commit b1bef7e

Browse files
[Zig 0.16.X+] fix SDL3 example for Zig 0.16.X and add panic handling back in (no stack trace support) (#69)
- fix SDL3 example for Zig 0.16.X - add panic handling back in (no stack trace support) for Zig 0.16.X Fixes #68
1 parent aa7d68d commit b1bef7e

6 files changed

Lines changed: 104 additions & 23 deletions

File tree

build.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ pub fn build(b: *std.Build) void {
7676
.target = target,
7777
.optimize = optimize,
7878
});
79+
zig016.addImport("ndk", ndk_module);
80+
zig016.addImport("android_builtin", android_builtin_module);
7981
android_module.addImport("zig016", zig016);
8082
}
8183

examples/minimal/src/minimal.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ pub const std_options: std.Options = if (builtin.abi.isAndroid())
1212
else
1313
.{};
1414

15-
/// Deprecated: Zig 0.15.2 and lower only, Custom panic handler for Android
16-
pub const panic = if (builtin.abi.isAndroid() and builtin.zig_version.major == 0 and builtin.zig_version.minor <= 15)
15+
/// Custom panic handler for Android
16+
pub const panic = if (builtin.abi.isAndroid())
1717
android.panic
1818
else
1919
std.debug.FullPanic(std.debug.defaultPanic);

examples/raylib/src/main.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ pub fn main() !void {
1919
}
2020
}
2121

22-
/// Deprecated: Zig 0.15.2 and lower only, Custom panic handler for Android
23-
pub const panic = if (builtin.abi.isAndroid() and builtin.zig_version.major == 0 and builtin.zig_version.minor <= 15)
22+
/// Custom panic handler for Android
23+
pub const panic = if (builtin.abi.isAndroid())
2424
android.panic
2525
else
2626
std.debug.FullPanic(std.debug.defaultPanic);

examples/sdl2/src/sdl-zig-demo.zig

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ pub const std_options: std.Options = if (builtin.abi.isAndroid())
1414
else
1515
.{};
1616

17-
/// Deprecated: Zig 0.15.2 and lower only, Custom panic handler for Android
18-
pub const panic = if (builtin.abi.isAndroid() and builtin.zig_version.major == 0 and builtin.zig_version.minor <= 15)
17+
// Custom panic handler for Android
18+
pub const panic = if (builtin.abi.isAndroid())
1919
android.panic
2020
else
2121
std.debug.FullPanic(std.debug.defaultPanic);
@@ -28,24 +28,23 @@ comptime {
2828

2929
/// This needs to be exported for Android builds
3030
fn SDL_main() callconv(.c) void {
31-
if (comptime builtin.abi.isAndroid()) {
32-
if (builtin.zig_version.major == 0 and builtin.zig_version.minor <= 14) {
33-
_ = std.start.callMain();
34-
} else if (builtin.zig_version.major == 0 and builtin.zig_version.minor <= 15) {
35-
main() catch |err| {
36-
log.err("{s}", .{@errorName(err)});
37-
if (@errorReturnTrace()) |trace| {
38-
if (builtin.zig_version.major == 0 and builtin.zig_version.minor <= 15) {
39-
std.debug.dumpStackTrace(trace.*);
40-
} else {
41-
std.debug.dumpStackTrace(trace);
42-
}
43-
}
44-
};
45-
}
46-
} else {
31+
if (!comptime builtin.abi.isAndroid()) {
4732
@compileError("SDL_main should not be called outside of Android builds");
4833
}
34+
if (builtin.zig_version.major == 0 and builtin.zig_version.minor <= 14) {
35+
_ = std.start.callMain();
36+
return;
37+
}
38+
main() catch |err| {
39+
log.err("{s}", .{@errorName(err)});
40+
if (@errorReturnTrace()) |trace| {
41+
if (builtin.zig_version.major == 0 and builtin.zig_version.minor <= 15) {
42+
std.debug.dumpStackTrace(trace.*);
43+
} else {
44+
std.debug.dumpStackTrace(trace);
45+
}
46+
}
47+
};
4948
}
5049

5150
pub fn main() !void {

src/android/android.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const Level = ndk.Level;
1313
pub const panic = if (builtin.zig_version.major == 0 and builtin.zig_version.minor <= 15)
1414
std.debug.FullPanic(@import("Zig015_Panic.zig").panic)
1515
else
16-
@compileError("Android panic handler is no longer maintained as of Zig 0.16.x-dev");
16+
std.debug.FullPanic(zig016.panic);
1717

1818
/// Alternate log function implementation that calls __android_log_write so that you can see the logging via "adb logcat"
1919
pub const logFn = if (builtin.zig_version.major == 0 and builtin.zig_version.minor <= 14)

src/android/zig016/zig016.zig

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
//! Seperate module for Zig 0.16.X-dev functionality as @Type() comptime directive was removed
22

33
const std = @import("std");
4+
const builtin = @import("builtin");
5+
const ndk = @import("ndk");
6+
7+
const android_builtin = @import("android_builtin");
8+
const package_name: ?[*:0]const u8 = if (android_builtin.package_name.len > 0) android_builtin.package_name else null;
49

510
const LogFunction = fn (comptime message_level: std.log.Level, comptime scope: @EnumLiteral(), comptime format: []const u8, args: anytype) void;
611

@@ -20,3 +25,78 @@ pub fn wrapLogFn(comptime logFn: fn (
2025
}
2126
}.standardLogFn;
2227
}
28+
29+
pub fn panic(message: []const u8, first_trace_addr: ?usize) noreturn {
30+
@branchHint(.cold);
31+
if (comptime !builtin.abi.isAndroid()) @compileError("do not use Android panic for non-Android builds");
32+
33+
const android_log_level: c_int = @intFromEnum(ndk.Level.fatal);
34+
35+
trace: {
36+
_ = ndk.__android_log_print(android_log_level, package_name, "panic: %.*s", message.len, message.ptr);
37+
38+
if (@errorReturnTrace()) |t| if (t.index > 0) {
39+
logFatal("error return context:");
40+
writeStackTrace(t) catch break :trace;
41+
logFatal("\nstack trace:\n");
42+
};
43+
if (!std.options.allow_stack_tracing) {
44+
logFatal("Cannot print stack trace: stack tracing is disabled");
45+
return;
46+
} else {
47+
_ = ndk.__android_log_print(android_log_level, package_name, " at address: 0x%X", first_trace_addr orelse @returnAddress());
48+
logFatal(" (stack trace printing not supported in Zig 0.16.X+ for Android SDK)");
49+
}
50+
}
51+
52+
@trap();
53+
}
54+
55+
/// Write a previously captured stack trace to `writer`, annotated with source locations.
56+
pub fn writeStackTrace(st: *const std.builtin.StackTrace) !void {
57+
if (!std.options.allow_stack_tracing) {
58+
logFatal("Cannot print stack trace: stack tracing is disabled");
59+
return;
60+
}
61+
62+
// Fetch `st.index` straight away. Aside from avoiding redundant loads, this prevents issues if
63+
// `st` is `@errorReturnTrace()` and errors are encountered while writing the stack trace.
64+
const n_frames = st.index;
65+
if (n_frames == 0) return logFatal("(empty stack trace)");
66+
67+
const captured_frames = @min(n_frames, st.instruction_addresses.len);
68+
logFatal("(stack trace support unimplemented for Zig 0.16.X+)");
69+
70+
// const di_gpa = std.debug.getDebugInfoAllocator();
71+
// const di = std.debug.getSelfDebugInfo() catch |err| switch (err) {
72+
// error.UnsupportedTarget => {
73+
// logFatal("Cannot print stack trace: debug info unavailable for target\n\n");
74+
// return;
75+
// },
76+
// };
77+
// const io = std.Options.debug_io;
78+
//
79+
// for (st.instruction_addresses[0..captured_frames]) |ret_addr| {
80+
// // `ret_addr` is the return address, which is *after* the function call.
81+
// // Subtract 1 to get an address *in* the function call for a better source location.
82+
// try printSourceAtAddress(di_gpa, io, di, t, ret_addr -| StackIterator.ra_call_offset);
83+
// }
84+
if (n_frames > captured_frames) {
85+
_ = ndk.__android_log_print(
86+
@intFromEnum(ndk.Level.fatal),
87+
package_name,
88+
"(%d additional stack frames skipped...)",
89+
n_frames - captured_frames,
90+
);
91+
}
92+
}
93+
94+
inline fn logFatal(text: []const u8) void {
95+
_ = ndk.__android_log_print(
96+
@intFromEnum(ndk.Level.fatal),
97+
package_name,
98+
"%.*s",
99+
text.len,
100+
text.ptr,
101+
);
102+
}

0 commit comments

Comments
 (0)