Mobile Development 12 min read

Implementing Controllable Native Crash Handling in Android Using SIGSEGV, sigsetjmp, and siglongjmp

This article explains how Android native developers can capture and recover from controllable SIGSEGV crashes by registering signal handlers and using sigsetjmp/siglongjmp to emulate a try‑catch mechanism, complete with sample JNI code and practical considerations.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Implementing Controllable Native Crash Handling in Android Using SIGSEGV, sigsetjmp, and siglongjmp

Introduction

In everyday development, crashes are a critical metric that cannot be ignored. Whether on Android or iOS, native‑layer crashes caused by .so libraries are especially troublesome. When the offending library is third‑party, developers often resort to PLT hooking, but internal logic errors require a different approach. This article explores how native library authors can implement a controllable crash‑handling mechanism.

SIGSEGV

SIGSEGV is sent to a process when it performs an invalid memory reference, such as dereferencing a wild pointer. The article provides a simple flowchart (image omitted) and a quote from xhook author caikelun emphasizing that a SIGSEGV is merely the kernel notifying the process of an illegal memory access, and if the fault location is controllable, it can be handled.

sigsetjmp and siglongjmp

In native C, sigsetjmp saves the current stack environment, and siglongjmp can restore it, allowing a form of back‑tracking. The article shows the function signatures and explains the two parameters of sigsetjmp (environment buffer and whether to save the signal mask) and the parameters of siglongjmp (environment buffer and return value).

sigaction

The sigaction API registers a handler for a specific signal. An example registration for SIGSEGV is shown:

sigaction(SIGSEGV, &sigc, nullptr);

Practical Implementation

First, a function that deliberately raises SIGSEGV is defined:

void create_crash(){
    raise(SIGSEGV);
}

A Java click listener triggers a JNI call that invokes the native crash:

text.setOnClickListener {
    throwNativeCrash()
}

extern "C"
JNIEXPORT void JNICALL Java_com_example_signal_MainActivity_throwNativeCrash(JNIEnv *env, jobject thiz) {
    create_crash();
}

The recovery logic uses a global sigjmp_buf and a flag to ensure the handler runs only after sigsetjmp has been set:

static sigjmp_buf sigsegv_env;
static sig_atomic_t flag = 0;

static void sigsegv_handler(int sig) {
    if (flag) {
        siglongjmp(sigsegv_env, 1);
    }
}

During throwNativeCrash the code saves the stack state, triggers the crash, and logs the result:

if (sigsetjmp(sigsegv_env, 1)) {
    __android_log_print(ANDROID_LOG_INFO, "hello", "%s", "crash 了,但被我抓住了");
} else {
    create_crash();
    __android_log_print(ANDROID_LOG_INFO, "hello", "%s", "SIGSEGV");
}

The signal handler is registered in JNI_OnLoad :

extern "C" jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    struct sigaction sigc;
    sigc.sa_handler = sigsegv_handler;
    sigemptyset(&sigc.sa_mask);
    sigc.sa_flags = SA_SIGINFO;
    sigaction(SIGSEGV, &sigc, nullptr);
    return JNI_VERSION_1_4;
}

Running the example prints:

SIGSEGV
crash 了,但被我抓住了

Further Experiment

The article discusses moving the sigsetjmp call to JNI_OnLoad , which can cause an infinite loop of crashes because the saved environment is repeatedly restored without resetting the flag.

Conclusion

By combining signal registration, sigsetjmp , and siglongjmp , developers can build a native‑level try‑catch mechanism to catch controllable crashes like SIGSEGV. Care must be taken to avoid dead‑loops and to understand the limitations of this technique.

AndroidJNISignal HandlingNative Crashsiglongjmpsigsetjmp
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.