11//! Seperate module for Zig 0.16.X-dev functionality as @Type() comptime directive was removed
22
33const 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
510const 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 ("\n stack 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