How to catch JNI Crashes as exceptions using signal processing engine in Java

I developed a Java tool and it has many JNI functions, I often get JNI crashes. Is it possible to avoid these failures or catch these failures as exceptions. I surfed the Internet and found that this is possible thanks to signal processing, chanining signal, sigaction (), etc. But I could not get a reliable source to guide me. Please help me with this.

0
source share
1 answer

JNI exceptions are considered signals. You can set up signal handlers on sigaction , and then you can try to disable the crash stack, like libcorkscrew , to save this to disk. After that, you can call the Java method through the JNI interfaces to process the information you save.

Example:

 int watched_signals[] = { SIGABRT, SIGILL, SIGSEGV, SIGINT, SIGKILL }; void sighandler_func(int sig, siginfo_t* sig_info, void* ptr) { // Dump the callstack by libcorkscrew ... // Call a JNI interface to process the stack info ... } struct sigaction sighandler; sighandler.sa_sigaction = &sighandler_func; sighandler.sa_mask = 0; sighandler.sa_flags = SA_SIGINFO | SA_ONSTACK; for(int signal : watched_signals) { sigaction(signal, &sighandler, nullptr); } 

Suppose you used libcorkscrew in an ndk project, then you can get a failure stack:

 #include <dlfcn.h> #include <ucontext.h> #include <corkscrew/backtrace.h> #include <backtrace-arch.h> void dump_stack(int sig, siginfo_t* sig_info, void* ptr) { const size_t BACKTRACE_FRAMES_MAX = 0xFF; static backtrace_frame_t frames[BACKTRACE_FRAMES_MAX]; static backtrace_symbol_t symbols[BACKTRACE_FRAMES_MAX]; map_info_t* const info = acquire_my_map_info_list(); const ssize_t size = unwind_backtrace_signal_arch(sig_info, ptr, info, frames, 0, BACKTRACE_FRAMES_MAX); get_backtrace_symbols(frames, size, symbols); for (int i = 0; i < size; i++) { backtrace_symbol_t& symbol = symbols[i]; // You could change the printf to fwrite if you want to save the info on disk printf("#%02d pc %08X %s (%s+%d)", i, symbol.relative_pc, symbol.map_name ? symbol.map_name : "<unknown>", symbol.demangled_name ? symbol.demangled_name : symbol.symbol_name, symbol.relative_pc - symbol.relative_symbol_addr); } free_backtrace_symbols(symbols, size); release_my_map_info_list(info); } 

Even if you can continue the program after processing the signal, but I highly recommend that you save the information on disk and process it in the next application launch. Because most of the time when you run the program, you will not work.

0
source

Source: https://habr.com/ru/post/1274167/


All Articles