How to catch JNI Crashes as exceptions using Signal handling based mechanism in Java [duplicate]

为君一笑 提交于 2019-12-11 17:01:37

问题


I developed a Java tool and it has many JNI functions, I am getting JNI crashes often. Is there any possibility to avoid those crashes or to catch these crashes as exceptions. I surfed internet and found it is possible through signal processing, signal chanining, sigaction(), etc. But I could not get a reliable source to direct me. Please do guide me on this.


回答1:


JNI exceptions are considered as signals. You could set up your signal handlers by sigaction and then you could try to unwind the crash stack, for example by libcorkscrew, to save it on the disk. After that you could invoke a Java method via JNI interfaces to process the info you saved.

Sample:

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 have involved libcorkscrew into you ndk project then you could get the crash 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 through you could continue the program after you handled the signal but I strongly suggest you to save the info on disk and process it in the next app launch. Because most of the time you program would fail when a signal raised.



来源:https://stackoverflow.com/questions/30105719/how-to-catch-jni-crashes-as-exceptions-using-signal-handling-based-mechanism-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!