Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ pub fn build(b: *std.Build) void {
.target = target,
.optimize = optimize,
});
zig016.addImport("ndk", ndk_module);
zig016.addImport("android_builtin", android_builtin_module);
android_module.addImport("zig016", zig016);
}

Expand Down
4 changes: 2 additions & 2 deletions examples/minimal/src/minimal.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ pub const std_options: std.Options = if (builtin.abi.isAndroid())
else
.{};

/// Deprecated: Zig 0.15.2 and lower only, Custom panic handler for Android
pub const panic = if (builtin.abi.isAndroid() and builtin.zig_version.major == 0 and builtin.zig_version.minor <= 15)
/// Custom panic handler for Android
pub const panic = if (builtin.abi.isAndroid())
android.panic
else
std.debug.FullPanic(std.debug.defaultPanic);
Expand Down
4 changes: 2 additions & 2 deletions examples/raylib/src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ pub fn main() !void {
}
}

/// Deprecated: Zig 0.15.2 and lower only, Custom panic handler for Android
pub const panic = if (builtin.abi.isAndroid() and builtin.zig_version.major == 0 and builtin.zig_version.minor <= 15)
/// Custom panic handler for Android
pub const panic = if (builtin.abi.isAndroid())
android.panic
else
std.debug.FullPanic(std.debug.defaultPanic);
Expand Down
35 changes: 17 additions & 18 deletions examples/sdl2/src/sdl-zig-demo.zig
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ pub const std_options: std.Options = if (builtin.abi.isAndroid())
else
.{};

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

/// This needs to be exported for Android builds
fn SDL_main() callconv(.c) void {
if (comptime builtin.abi.isAndroid()) {
if (builtin.zig_version.major == 0 and builtin.zig_version.minor <= 14) {
_ = std.start.callMain();
} else if (builtin.zig_version.major == 0 and builtin.zig_version.minor <= 15) {
main() catch |err| {
log.err("{s}", .{@errorName(err)});
if (@errorReturnTrace()) |trace| {
if (builtin.zig_version.major == 0 and builtin.zig_version.minor <= 15) {
std.debug.dumpStackTrace(trace.*);
} else {
std.debug.dumpStackTrace(trace);
}
}
};
}
} else {
if (!comptime builtin.abi.isAndroid()) {
@compileError("SDL_main should not be called outside of Android builds");
}
if (builtin.zig_version.major == 0 and builtin.zig_version.minor <= 14) {
_ = std.start.callMain();
return;
}
main() catch |err| {
log.err("{s}", .{@errorName(err)});
if (@errorReturnTrace()) |trace| {
if (builtin.zig_version.major == 0 and builtin.zig_version.minor <= 15) {
std.debug.dumpStackTrace(trace.*);
} else {
std.debug.dumpStackTrace(trace);
}
}
};
}

pub fn main() !void {
Expand Down
2 changes: 1 addition & 1 deletion src/android/android.zig
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const Level = ndk.Level;
pub const panic = if (builtin.zig_version.major == 0 and builtin.zig_version.minor <= 15)
std.debug.FullPanic(@import("Zig015_Panic.zig").panic)
else
@compileError("Android panic handler is no longer maintained as of Zig 0.16.x-dev");
std.debug.FullPanic(zig016.panic);

/// Alternate log function implementation that calls __android_log_write so that you can see the logging via "adb logcat"
pub const logFn = if (builtin.zig_version.major == 0 and builtin.zig_version.minor <= 14)
Expand Down
80 changes: 80 additions & 0 deletions src/android/zig016/zig016.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
//! Seperate module for Zig 0.16.X-dev functionality as @Type() comptime directive was removed

const std = @import("std");
const builtin = @import("builtin");
const ndk = @import("ndk");

const android_builtin = @import("android_builtin");
const package_name: ?[*:0]const u8 = if (android_builtin.package_name.len > 0) android_builtin.package_name else null;

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

Expand All @@ -20,3 +25,78 @@ pub fn wrapLogFn(comptime logFn: fn (
}
}.standardLogFn;
}

pub fn panic(message: []const u8, first_trace_addr: ?usize) noreturn {
@branchHint(.cold);
if (comptime !builtin.abi.isAndroid()) @compileError("do not use Android panic for non-Android builds");

const android_log_level: c_int = @intFromEnum(ndk.Level.fatal);

trace: {
_ = ndk.__android_log_print(android_log_level, package_name, "panic: %.*s", message.len, message.ptr);

if (@errorReturnTrace()) |t| if (t.index > 0) {
logFatal("error return context:");
writeStackTrace(t) catch break :trace;
logFatal("\nstack trace:\n");
};
if (!std.options.allow_stack_tracing) {
logFatal("Cannot print stack trace: stack tracing is disabled");
return;
} else {
_ = ndk.__android_log_print(android_log_level, package_name, " at address: 0x%X", first_trace_addr orelse @returnAddress());
logFatal(" (stack trace printing not supported in Zig 0.16.X+ for Android SDK)");
}
}

@trap();
}

/// Write a previously captured stack trace to `writer`, annotated with source locations.
pub fn writeStackTrace(st: *const std.builtin.StackTrace) !void {
if (!std.options.allow_stack_tracing) {
logFatal("Cannot print stack trace: stack tracing is disabled");
return;
}

// Fetch `st.index` straight away. Aside from avoiding redundant loads, this prevents issues if
// `st` is `@errorReturnTrace()` and errors are encountered while writing the stack trace.
const n_frames = st.index;
if (n_frames == 0) return logFatal("(empty stack trace)");

const captured_frames = @min(n_frames, st.instruction_addresses.len);
logFatal("(stack trace support unimplemented for Zig 0.16.X+)");

// const di_gpa = std.debug.getDebugInfoAllocator();
// const di = std.debug.getSelfDebugInfo() catch |err| switch (err) {
// error.UnsupportedTarget => {
// logFatal("Cannot print stack trace: debug info unavailable for target\n\n");
// return;
// },
// };
// const io = std.Options.debug_io;
//
// for (st.instruction_addresses[0..captured_frames]) |ret_addr| {
// // `ret_addr` is the return address, which is *after* the function call.
// // Subtract 1 to get an address *in* the function call for a better source location.
// try printSourceAtAddress(di_gpa, io, di, t, ret_addr -| StackIterator.ra_call_offset);
// }
if (n_frames > captured_frames) {
_ = ndk.__android_log_print(
@intFromEnum(ndk.Level.fatal),
package_name,
"(%d additional stack frames skipped...)",
n_frames - captured_frames,
);
}
}

inline fn logFatal(text: []const u8) void {
_ = ndk.__android_log_print(
@intFromEnum(ndk.Level.fatal),
package_name,
"%.*s",
text.len,
text.ptr,
);
}