为什么 SIGSEGV 的行为与 Android 中的其他异常代码不同?

问题描述 投票:0回答:1

我正在使用本机代码构建 Android 应用程序。我想处理SIGSEGV、SIGFPE、SIGILL等异常

我的目标是,在其中一种不太可能发生的情况下,我不会终止应用程序。

基本上,我遵循从here得到的方法:

  1. 在Application.onCreate中,我调用System.loadLibrary(它调用JNI_OnLoad)
  2. 在 JNI_OnLoad 中,我设置异常处理程序(并保留所需的全局类指针)
  3. 在 Activity.onCreate 中,我存储 Activity 上下文并调用将创建工作线程的本机方法。
  4. 在工作线程上,我编写了一些会导致 SIGSEGV 或 SIGFPE 的错误代码。
  5. 异常处理程序在同一工作线程上触发。
  6. 在异常处理程序中,我将调用一个 Activity,该 Activity 将显示出现问题。
  7. 发布我调用默认异常处理程序(按照建议)。我还终止了工作线程以确保不会重复引发异常。
  8. 进程因调用默认处理程序而终止。
  9. 启动的 Activity 被标记为在自己的进程中运行(通过清单文件),因此当第一个进程终止时不会终止。
// MainApplication.kt

package com.example.exceptionhandling

import android.app.Application
import android.content.Context
import android.util.Log

class MainApplication : Application ()  {

    override fun onCreate()
    {
        Log.d ("MyApp", "MainApplication.onCreate")

        super.onCreate ()
        System.loadLibrary ("exceptionhandling")
    }

    companion object {

        public var sActivityCtx : Context? = null
    }

}
// MainActivity.kt

package com.example.exceptionhandling

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.example.exceptionhandling.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override
    fun onCreate (pSavedInstanceState: Bundle?)
    {
        Log.d ("MyApp", "MainActivity.onCreate")
        super.onCreate (pSavedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        MainApplication.sActivityCtx = this

        NativeMethod ()
    }

    override
    fun onStop()
    {
        super.onStop()

        Log.d ("MyApp", "MainActivity.onStop")
    }
    
    external fun NativeMethod () : Unit
}

// ExceptionActivity.kt

package com.example.exceptionhandling

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.example.exceptionhandling.databinding.ActivityMainBinding

class ExceptionActivity : AppCompatActivity () {

    companion object {

        // Invoked from C++

        @JvmStatic
        public fun StartExceptionActivity ()
        {
            Log.e ("MyApp", "Inside ExceptionActivity.StartExceptionActivity")

            MainApplication.sActivityCtx!!.startActivity (Intent (MainApplication.sActivityCtx, ExceptionActivity::class.java))
        }
    }

    public override
    fun onCreate (pSavedInstanceState: Bundle?)
    {
        Log.d ("MyApp", "Inside ExceptionActivity.onCreate")

        super.onCreate (pSavedInstanceState)

            val linear_layout : LinearLayout
            val textview      : TextView?

        linear_layout = LinearLayout (this)

        textview = TextView (this)
        textview.text = "Something has gone wrong!!"

        linear_layout.addView (textview)
        setContentView (linear_layout)
    }
}

// native-lib.cpp

#include <jni.h>
#include <string>
#include <android/log.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>

#define TRACE_LOG(x, ...) __android_log_print (ANDROID_LOG_DEBUG, "MyApp", x, ##__VA_ARGS__)
#define TRACEFUNC TRACE_LOG ("Inside %s", __PRETTY_FUNCTION__)
#define TRACELINE TRACE_LOG ("At line: %d", __LINE__)

JavaVM* gJavaVM;
jclass  gExceptionActivityClass; // To store the class pointer of Exception Activity. Will be needed if its methods are to be invoked
thread_local JNIEnv * gThreadLocalEnv;
thread_local bool gIsWorkerThread {}; // Whether the thread is worker thread or main thread

using SignalHandlerFunc = void (*) (int, siginfo_t*, void *);

struct tSignals {

    int uSignal;
    SignalHandlerFunc uSignalHandlerFunc;
    SignalHandlerFunc uDefaultSignalHandlerFunc;
};

void
ExceptionHandler (int pNum, siginfo_t *pInfo, void *pCtx) noexcept;

tSignals gSignals [] =
        {
                {SIGILL,  ExceptionHandler, nullptr},
                {SIGSEGV, ExceptionHandler, nullptr},
                {SIGFPE,  ExceptionHandler, nullptr},
        };

void
ShouldNotGetCalled (int, siginfo_t*, void *) noexcept
{
        TRACEFUNC;

}

SignalHandlerFunc
GetDefaultSignalHandlerFunc (int pSignal) noexcept
{
        TRACEFUNC;

        SignalHandlerFunc func = nullptr;

    for (auto signal : gSignals) {

        if (pSignal == signal.uSignal) {

            func = signal.uDefaultSignalHandlerFunc;
            break;
        }
    }

    if (func)
        return func;

    return ShouldNotGetCalled;
}

void
StartExceptionActivity () noexcept
{
        TRACEFUNC;

        jmethodID  method_id;

    method_id = gThreadLocalEnv->GetStaticMethodID (gExceptionActivityClass, "StartExceptionActivity", "()V");

    if (method_id == NULL) {

        TRACELINE;
        return;
    }

    gThreadLocalEnv->CallStaticVoidMethod (gExceptionActivityClass, method_id);

    TRACELINE;
}

void
AttachThread () noexcept
{
    TRACEFUNC;

    gJavaVM->GetEnv ((void **) &gThreadLocalEnv, JNI_VERSION_1_6);

    gJavaVM->AttachCurrentThread (&gThreadLocalEnv, nullptr);
}

void
DetachThread () noexcept
{
        TRACEFUNC;

    gJavaVM->DetachCurrentThread ();
}

[[noreturn]]
void
KillThread () noexcept
{
        TRACEFUNC;

    DetachThread ();

    pthread_exit (nullptr);
}

void
ExceptionHandler (int pNum, siginfo_t* pInfo, void * pCtx) noexcept
{
        TRACEFUNC;

    TRACE_LOG ("Exception number = %d", pNum);

    StartExceptionActivity();

    GetDefaultSignalHandlerFunc (pNum) (pNum, pInfo, pCtx);

    if (gIsWorkerThread)
        KillThread ();
}

void
SetExceptionHandlers () noexcept
{
        TRACEFUNC;

        struct sigaction sa {};
        struct sigaction sa_out {};

    // SIGACTION Register
    sa.sa_flags = SA_SIGINFO | SA_RESETHAND;

    for (auto & signal : gSignals) {

        sa.sa_sigaction = signal.uSignalHandlerFunc;
        sigaction (signal.uSignal, &sa, &sa_out);

        signal.uDefaultSignalHandlerFunc = sa_out.sa_sigaction;
        TRACE_LOG ("Default handler = %p\n", signal.uDefaultSignalHandlerFunc);
    }

    TRACE_LOG ("ExceptionHandler Set");
}

extern "C" JNIEXPORT jint JNICALL
JNI_OnLoad (JavaVM * pJavaVM, [[maybe_unused]] void * pReserved)
{
        TRACEFUNC;

        jclass exception_activity_class;
        JNIEnv * env;

    gJavaVM = pJavaVM;
    gIsWorkerThread = false;

    if (pJavaVM->GetEnv ((void **) &env, JNI_VERSION_1_6) != JNI_OK)
        return JNI_ERR;

    exception_activity_class = env->FindClass ("com/example/exceptionhandling/ExceptionActivity");

    if (exception_activity_class == nullptr) {

        TRACELINE;
        return JNI_ERR;
    }

    gExceptionActivityClass = (jclass) env->NewGlobalRef (exception_activity_class);

    SetExceptionHandlers ();

    return JNI_VERSION_1_6;
}

void
RaiseException () noexcept
{
        TRACEFUNC;

        int a = 5;
        int b = 0;
        int c;

    c = a / b;

    TRACE_LOG ("Num = %d", c);
}

void *
ThreadFunc (void* ) noexcept
{
        TRACEFUNC;

    gIsWorkerThread = true;

    AttachThread ();

    RaiseException ();

    TRACELINE;

    return nullptr;
}

// Invoked from MainActivity.onCreate

extern "C" JNIEXPORT void JNICALL
Java_com_example_exceptionhandling_MainActivity_NativeMethod (JNIEnv* pEnv, jobject pObject)
{
        TRACEFUNC;

    pthread_t thread_handle;

    pthread_create (&thread_handle, nullptr, ThreadFunc, nullptr);
}

在 RaiseException 函数中,我引发了“除以零”异常,从而导致 SIGFPE。 ExceptionHandler 被调用,它调用 ExceptionActivity,然后调用默认处理程序,然后终止线程(因为它是工作线程)。

ExceptionActivity在自己的进程中运行,第一个进程就死掉了。我收到以下日志:

---------------------------- PROCESS STARTED (4523) for package com.example.exceptionhandling ----------------------------
2024-04-09 20:02:16.117  4523-4523  MyApp                   com.example.exceptionhandling        D  MainApplication.onCreate
2024-04-09 20:02:16.120  4523-4523  MyApp                   com.example.exceptionhandling        D  Inside jint JNI_OnLoad(JavaVM *, void *)
2024-04-09 20:02:16.144  4523-4523  MyApp                   com.example.exceptionhandling        D  Inside void SetExceptionHandlers()
2024-04-09 20:02:16.147  4523-4523  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 20:02:16.149  4523-4523  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 20:02:16.149  4523-4523  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 20:02:16.152  4523-4523  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 20:02:16.152  4523-4523  MyApp                   com.example.exceptionhandling        D  ExceptionHandler Set
2024-04-09 20:02:16.807  4523-4523  MyApp                   com.example.exceptionhandling        D  MainActivity.onCreate
2024-04-09 20:02:17.922  4523-4523  MyApp                   com.example.exceptionhandling        D  Inside void Java_com_example_exceptionhandling_MainActivity_NativeMethod(JNIEnv *, jobject)
2024-04-09 20:02:17.923  4523-4523  MyApp                   com.example.exceptionhandling        D  Inside void CreateThread()
2024-04-09 20:02:17.925  4523-4604  MyApp                   com.example.exceptionhandling        D  Inside void *ThreadFunc(void *)
2024-04-09 20:02:17.925  4523-4604  MyApp                   com.example.exceptionhandling        D  Inside void AttachThread()
2024-04-09 20:02:17.925  4523-4604  MyApp                   com.example.exceptionhandling        D  Inside void RaiseException()
2024-04-09 20:02:17.925  4523-4604  MyApp                   com.example.exceptionhandling        D  Inside void ExceptionHandler(int, siginfo_t *, void *)
2024-04-09 20:02:17.925  4523-4604  MyApp                   com.example.exceptionhandling        D  Exception number = 8
2024-04-09 20:02:17.925  4523-4604  MyApp                   com.example.exceptionhandling        D  Inside void StartExceptionActivity()
2024-04-09 20:02:17.967  4523-4604  MyApp                   com.example.exceptionhandling        D  At line: 46
2024-04-09 20:02:17.967  4523-4604  MyApp                   com.example.exceptionhandling        D  Inside SignalHandlerFunc GetDefaultSignalHandlerFunc(int)
---------------------------- PROCESS STARTED (4606) for package com.example.exceptionhandling ----------------------------
---------------------------- PROCESS STARTED (4616) for package com.example.exceptionhandling ----------------------------
2024-04-09 20:02:18.420  4523-4604  MyApp                   com.example.exceptionhandling        D  Inside void KillThread()
2024-04-09 20:02:18.420  4523-4604  MyApp                   com.example.exceptionhandling        D  Inside void DetachThread()
2024-04-09 20:02:18.580  4606-4606  MyApp                   com.example.exceptionhandling        D  MainApplication.onCreate
2024-04-09 20:02:18.597  4606-4606  MyApp                   com.example.exceptionhandling        D  Inside jint JNI_OnLoad(JavaVM *, void *)
2024-04-09 20:02:18.635  4606-4606  MyApp                   com.example.exceptionhandling        D  Inside void SetExceptionHandlers()
2024-04-09 20:02:18.636  4606-4606  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 20:02:18.637  4606-4606  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 20:02:18.637  4606-4606  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 20:02:18.638  4606-4606  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 20:02:18.638  4606-4606  MyApp                   com.example.exceptionhandling        D  ExceptionHandler Set
2024-04-09 20:02:18.825  4523-4523  MyApp                   com.example.exceptionhandling        D  MainActivity.onStop
2024-04-09 20:02:19.181  4606-4606  MyApp                   com.example.exceptionhandling        D  Inside ExceptionActivity.onCreate
---------------------------- PROCESS ENDED (4616) for package com.example.exceptionhandling ----------------------------

此行为符合预期。第一个进程调用第二个进程,然后第一个进程终止。由于保留了第二个流程,所以不会给用户带来不好的体验。

现在,如果我更改 RaiseException 函数(在工作线程上调用)的逻辑以引发 SIGSEGV,事情就会发生:(

// native-lib.cpp

void
RaiseException () noexcept
{
        TRACEFUNC;

        int * ptr = nullptr;

    *ptr = 45;
    TRACE_LOG ("Num = %d", *ptr);
}

我观察到 ExceptionHandler 是通过 SIGSEGV 异常代码调用的。在这里,我调用 StartExceptionActivity,这再次导致使用 SIGABRT 调用 ExceptionHandler。

导致该问题的行是 CallStaticVoidMethod,它调用了 Kotlin 中的 StartExceptionActivity。当它尝试startActivity启动ExceptionActivity时,它会抛出一堆异常。这种情况发生了很多次,然后一切都消失了。

---------------------------- PROCESS STARTED (1678) for package com.example.exceptionhandling ----------------------------
2024-04-09 19:49:49.729  1678-1678  MyApp                   com.example.exceptionhandling        D  MainApplication.onCreate
2024-04-09 19:49:49.731  1678-1678  MyApp                   com.example.exceptionhandling        D  Inside jint JNI_OnLoad(JavaVM *, void *)
2024-04-09 19:49:49.767  1678-1678  MyApp                   com.example.exceptionhandling        D  Inside void SetExceptionHandlers()
2024-04-09 19:49:49.767  1678-1678  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 19:49:49.767  1678-1678  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 19:49:49.767  1678-1678  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 19:49:49.768  1678-1678  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 19:49:49.775  1678-1678  MyApp                   com.example.exceptionhandling        D  ExceptionHandler Set
2024-04-09 19:49:50.709  1678-1678  MyApp                   com.example.exceptionhandling        D  MainActivity.onCreate
2024-04-09 19:49:51.497  1678-1678  MyApp                   com.example.exceptionhandling        D  Inside void Java_com_example_exceptionhandling_MainActivity_NativeMethod(JNIEnv *, jobject)
2024-04-09 19:49:51.497  1678-1678  MyApp                   com.example.exceptionhandling        D  Inside void CreateThread()
2024-04-09 19:49:51.499  1678-1758  MyApp                   com.example.exceptionhandling        D  Inside void *ThreadFunc(void *)
2024-04-09 19:49:51.499  1678-1758  MyApp                   com.example.exceptionhandling        D  Inside void AttachThread()
2024-04-09 19:49:51.499  1678-1758  MyApp                   com.example.exceptionhandling        D  Inside void RaiseException()
2024-04-09 19:49:51.499  1678-1758  MyApp                   com.example.exceptionhandling        D  Inside void ExceptionHandler(int, siginfo_t *, void *)
2024-04-09 19:49:51.499  1678-1758  MyApp                   com.example.exceptionhandling        D  Exception number = 11
2024-04-09 19:49:51.499  1678-1758  MyApp                   com.example.exceptionhandling        D  Inside void StartExceptionActivity()
2024-04-09 19:49:51.839  1678-1758  MyApp                   com.example.exceptionhandling        D  Inside void ExceptionHandler(int, siginfo_t *, void *)
2024-04-09 19:49:51.839  1678-1758  MyApp                   com.example.exceptionhandling        D  Exception number = 6
2024-04-09 19:49:51.839  1678-1758  MyApp                   com.example.exceptionhandling        D  Inside void StartExceptionActivity()
---------------------------- PROCESS ENDED (1678) for package com.example.exceptionhandling ----------------------------
---------------------------- PROCESS STARTED (1759) for package com.example.exceptionhandling ----------------------------
2024-04-09 19:49:52.588  1759-1759  MyApp                   com.example.exceptionhandling        D  MainApplication.onCreate
2024-04-09 19:49:52.591  1759-1759  MyApp                   com.example.exceptionhandling        D  Inside jint JNI_OnLoad(JavaVM *, void *)
2024-04-09 19:49:52.603  1759-1759  MyApp                   com.example.exceptionhandling        D  Inside void SetExceptionHandlers()
2024-04-09 19:49:52.604  1759-1759  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 19:49:52.604  1759-1759  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 19:49:52.604  1759-1759  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 19:49:52.604  1759-1759  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 19:49:52.604  1759-1759  MyApp                   com.example.exceptionhandling        D  ExceptionHandler Set
2024-04-09 19:49:52.967  1759-1759  MyApp                   com.example.exceptionhandling        D  MainActivity.onCreate
2024-04-09 19:49:53.767  1759-1759  MyApp                   com.example.exceptionhandling        D  Inside void Java_com_example_exceptionhandling_MainActivity_NativeMethod(JNIEnv *, jobject)
2024-04-09 19:49:53.767  1759-1759  MyApp                   com.example.exceptionhandling        D  Inside void CreateThread()
2024-04-09 19:49:53.771  1759-1788  MyApp                   com.example.exceptionhandling        D  Inside void *ThreadFunc(void *)
2024-04-09 19:49:53.771  1759-1788  MyApp                   com.example.exceptionhandling        D  Inside void AttachThread()
2024-04-09 19:49:53.771  1759-1788  MyApp                   com.example.exceptionhandling        D  Inside void RaiseException()
2024-04-09 19:49:53.771  1759-1788  MyApp                   com.example.exceptionhandling        D  Inside void ExceptionHandler(int, siginfo_t *, void *)
2024-04-09 19:49:53.771  1759-1788  MyApp                   com.example.exceptionhandling        D  Exception number = 11
2024-04-09 19:49:53.771  1759-1788  MyApp                   com.example.exceptionhandling        D  Inside void StartExceptionActivity()
2024-04-09 19:49:54.110  1759-1788  MyApp                   com.example.exceptionhandling        D  Inside void ExceptionHandler(int, siginfo_t *, void *)
2024-04-09 19:49:54.110  1759-1788  MyApp                   com.example.exceptionhandling        D  Exception number = 6
2024-04-09 19:49:54.110  1759-1788  MyApp                   com.example.exceptionhandling        D  Inside void StartExceptionActivity()
---------------------------- PROCESS ENDED (1759) for package com.example.exceptionhandling ----------------------------
---------------------------- PROCESS STARTED (1789) for package com.example.exceptionhandling ----------------------------
2024-04-09 19:49:54.911  1789-1789  MyApp                   com.example.exceptionhandling        D  MainApplication.onCreate
2024-04-09 19:49:54.912  1789-1789  MyApp                   com.example.exceptionhandling        D  Inside jint JNI_OnLoad(JavaVM *, void *)
2024-04-09 19:49:54.927  1789-1789  MyApp                   com.example.exceptionhandling        D  Inside void SetExceptionHandlers()
2024-04-09 19:49:54.928  1789-1789  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 19:49:54.928  1789-1789  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 19:49:54.928  1789-1789  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 19:49:54.929  1789-1789  MyApp                   com.example.exceptionhandling        D  Default handler = 0x7395f2d1ab91
2024-04-09 19:49:54.929  1789-1789  MyApp                   com.example.exceptionhandling        D  ExceptionHandler Set
2024-04-09 19:49:55.585  1789-1789  MyApp                   com.example.exceptionhandling        D  MainActivity.onCreate
2024-04-09 19:49:56.296  1789-1789  MyApp                   com.example.exceptionhandling        D  Inside void Java_com_example_exceptionhandling_MainActivity_NativeMethod(JNIEnv *, jobject)
2024-04-09 19:49:56.296  1789-1789  MyApp                   com.example.exceptionhandling        D  Inside void CreateThread()
2024-04-09 19:49:56.296  1789-1840  MyApp                   com.example.exceptionhandling        D  Inside void *ThreadFunc(void *)
2024-04-09 19:49:56.297  1789-1840  MyApp                   com.example.exceptionhandling        D  Inside void AttachThread()
2024-04-09 19:49:56.297  1789-1840  MyApp                   com.example.exceptionhandling        D  Inside void RaiseException()
2024-04-09 19:49:56.297  1789-1840  MyApp                   com.example.exceptionhandling        D  Inside void ExceptionHandler(int, siginfo_t *, void *)
2024-04-09 19:49:56.297  1789-1840  MyApp                   com.example.exceptionhandling        D  Exception number = 11
2024-04-09 19:49:56.297  1789-1840  MyApp                   com.example.exceptionhandling        D  Inside void StartExceptionActivity()
2024-04-09 19:49:56.783  1789-1840  MyApp                   com.example.exceptionhandling        D  Inside void ExceptionHandler(int, siginfo_t *, void *)
2024-04-09 19:49:56.783  1789-1840  MyApp                   com.example.exceptionhandling        D  Exception number = 6
2024-04-09 19:49:56.783  1789-1840  MyApp                   com.example.exceptionhandling        D  Inside void StartExceptionActivity()
---------------------------- PROCESS ENDED (1789) for package com.example.exceptionhandling ----------------------------

打开所有日志后,会显示

2024-04-09 19:57:50.419  1928-1956  MyApp                   com.example.exceptionhandling        D  Inside void StartExceptionActivity()
2024-04-09 19:57:50.424  1928-1956  ceptionhandling         com.example.exceptionhandling        A  java_vm_ext.cc:591] JNI DETECTED ERROR IN APPLICATION: JNI ERROR (app bug): jobject is an invalid JNI transition frame reference: 0x7395e30c9d20 (use of invalid jobject)
                                                                                                    java_vm_ext.cc:591]     in call to IsInstanceOf
                                                                                                    java_vm_ext.cc:591]     from void android.os.Parcel.nativeMarkForBinder(long, android.os.IBinder)

出于某种原因,我在 Kotlin 中编写的任何代码都会导致此类错误(甚至是 Log.d)。

我的问题是:

  1. 为什么只有 SIGSEGV 会发生这种情况,而其他的则不会?即使它们的默认处理程序是相同的(如日志中所示)。
  2. 有办法解决吗?
  3. 如果不能,我可以处理 SIGSEGV 吗?
android c++ exception android-ndk java-native-interface
1个回答
0
投票

我的目标是,在其中一种不太可能发生的情况下,我不会终止应用程序。

在 Java 进程内,您不能这样做。

首先,JVM 在内部使用

SIGSEGV
,因此您几乎无法安装自己的
SIGSEGV
处理程序。理论上,如果您能够区分源自 JVM 代码(您不想干扰信号处理)的信号和源自您确实想要干扰信号处理的代码的信号,您就可以安装您的处理程序。干扰信号处理。但在实践中,这几乎不可能可靠地完成,并且它不会解决在收到所谓的致命信号后尝试继续运行的所有其他问题。 您无法从其他信号的信号处理程序返回,因为只会再次引发相同的信号。
所以你只剩下某个版本的 

SIGSEGV

/

[sig]setjmp()

如果你使用它们,你就会面临它们发生在异步信号
不安全
函数调用内部,或者某些状态被互斥体或其他同步对象锁定的风险。

如果您[sig]longjmp()脱离了异步信号-

不安全

功能,Linux

[sig]longjmp()
手册页解释了整个进程必须运行的一些
限制:
setjmp() 跳出信号处理程序后,您必须将整个过程限制为仅进行异步信号安全调用。或者,您必须在每次异步信号不安全调用之前阻止信号。然而,您无法确保“整个 JVM”将遵循这些限制中的任何一个。事实上,您可以有效地确定 JVM 不会以这种方式工作。 这甚至还没有开始解决如果你跳出互斥锁被锁定的上下文或其他类似情况会发生什么。

© www.soinside.com 2019 - 2024. All rights reserved.