[Android] jni: catch the crash signals and trigger an event in Java LibVLC before calling their standard actions

Adrien Maglo git at videolan.org
Wed May 7 23:18:09 CEST 2014


vlc-ports/android | branch: master | Adrien Maglo <magsoft at videolan.org> | Wed May  7 23:18:02 2014 +0200| [dec94be09544bf2adee688b2366127ec0551d0ef] | committer: Adrien Maglo

jni: catch the crash signals and trigger an event in Java LibVLC before calling their standard actions

> http://git.videolan.org/gitweb.cgi/vlc-ports/android.git/?a=commit;h=dec94be09544bf2adee688b2366127ec0551d0ef
---

 vlc-android/jni/Android.mk                      |    2 +-
 vlc-android/jni/libvlcjni.c                     |    5 ++
 vlc-android/jni/native_crash_handler.c          |   88 +++++++++++++++++++++++
 vlc-android/jni/native_crash_handler.h          |   29 ++++++++
 vlc-android/src/org/videolan/libvlc/LibVLC.java |    3 +
 5 files changed, 126 insertions(+), 1 deletion(-)

diff --git a/vlc-android/jni/Android.mk b/vlc-android/jni/Android.mk
index 48b0976..ba909b2 100644
--- a/vlc-android/jni/Android.mk
+++ b/vlc-android/jni/Android.mk
@@ -3,7 +3,7 @@ include $(CLEAR_VARS)
 
 LOCAL_MODULE    := libvlcjni
 
-LOCAL_SRC_FILES := libvlcjni.c libvlcjni-util.c libvlcjni-track.c libvlcjni-medialist.c aout.c vout.c libvlcjni-equalizer.c
+LOCAL_SRC_FILES := libvlcjni.c libvlcjni-util.c libvlcjni-track.c libvlcjni-medialist.c aout.c vout.c libvlcjni-equalizer.c native_crash_handler.c
 LOCAL_SRC_FILES += thumbnailer.c pthread-condattr.c pthread-rwlocks.c pthread-once.c eventfd.c sem.c
 LOCAL_SRC_FILES += pipe2.c
 LOCAL_SRC_FILES += wchar/wcpcpy.c
diff --git a/vlc-android/jni/libvlcjni.c b/vlc-android/jni/libvlcjni.c
index 37a2b85..5a8464a 100644
--- a/vlc-android/jni/libvlcjni.c
+++ b/vlc-android/jni/libvlcjni.c
@@ -38,6 +38,7 @@
 #include "aout.h"
 #include "vout.h"
 #include "utils.h"
+#include "native_crash_handler.h"
 
 #define VOUT_ANDROID_SURFACE 0
 #define VOUT_OPENGLES2       1
@@ -301,10 +302,14 @@ void Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv *env, jobject thiz)
     LOGI("LibVLC initialized: %p", instance);
 
     libvlc_log_set(instance, debug_log, &verbosity);
+
+    init_native_crash_handler(env, thiz);
 }
 
 void Java_org_videolan_libvlc_LibVLC_nativeDestroy(JNIEnv *env, jobject thiz)
 {
+    destroy_native_crash_handler(env);
+
     releaseMediaPlayer(env, thiz);
     jlong libVlcInstance = getLong(env, thiz, "mLibVlcInstance");
     if (!libVlcInstance)
diff --git a/vlc-android/jni/native_crash_handler.c b/vlc-android/jni/native_crash_handler.c
new file mode 100644
index 0000000..cde180d
--- /dev/null
+++ b/vlc-android/jni/native_crash_handler.c
@@ -0,0 +1,88 @@
+/*****************************************************************************
+ * native_crash_handler.c
+ *****************************************************************************
+ * Copyright © 2010-2014 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include <signal.h>
+
+#include "native_crash_handler.h"
+
+static struct sigaction old_actions[NSIG];
+static jobject j_libVLC;
+
+
+/** Unique Java VM instance, as defined in libvlcjni.c */
+extern JavaVM *myVm;
+
+
+/**
+ * Callback called when a monitored signal is triggered.
+ */
+void sigaction_callback(int signal, siginfo_t *info, void *reserved)
+{
+    // Call the Java LibVLC method that handle the crash.
+    JNIEnv *env;
+    (*myVm)->AttachCurrentThread(myVm, &env, NULL);
+
+    jclass cls = (*env)->GetObjectClass(env, j_libVLC);
+    jmethodID methodId = (*env)->GetMethodID(env, cls, "onNativeCrash", "()V");
+    (*env)->CallVoidMethod(env, j_libVLC, methodId);
+
+    (*env)->DeleteLocalRef(env, cls);
+    (*myVm)->DetachCurrentThread(myVm);
+
+    // Call the old signal handler.
+    old_actions[signal].sa_handler(signal);
+}
+
+
+void init_native_crash_handler(JNIEnv *env, jobject j_libVLC_local)
+{
+    j_libVLC = (*env)->NewGlobalRef(env, j_libVLC_local);
+    struct sigaction handler;
+    memset(&handler, 0, sizeof(struct sigaction));
+
+    handler.sa_sigaction = sigaction_callback;
+    handler.sa_flags = SA_RESETHAND;
+
+    // Install the signal handlers and save their old actions.
+    #define CATCHSIG(X) sigaction(X, &handler, &old_actions[X])
+    CATCHSIG(SIGILL);
+    CATCHSIG(SIGABRT);
+    CATCHSIG(SIGBUS);
+    CATCHSIG(SIGFPE);
+    CATCHSIG(SIGSEGV);
+    CATCHSIG(SIGSTKFLT);
+    CATCHSIG(SIGPIPE);
+}
+
+
+void destroy_native_crash_handler(JNIEnv *env)
+{
+    // Uninstall the signal handlers and restore their old actions.
+    #define REMOVESIG(X) sigaction(X, &old_actions[X], NULL)
+    REMOVESIG(SIGILL);
+    REMOVESIG(SIGABRT);
+    REMOVESIG(SIGBUS);
+    REMOVESIG(SIGFPE);
+    REMOVESIG(SIGSEGV);
+    REMOVESIG(SIGSTKFLT);
+    REMOVESIG(SIGPIPE);
+
+    (*env)->DeleteGlobalRef(env, j_libVLC);
+}
diff --git a/vlc-android/jni/native_crash_handler.h b/vlc-android/jni/native_crash_handler.h
new file mode 100644
index 0000000..a57e61e
--- /dev/null
+++ b/vlc-android/jni/native_crash_handler.h
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * native_crash_handler.h
+ *****************************************************************************
+ * Copyright © 2010-2013 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef LIBVLCJNI_NATIVE_CRASH_HANDLER_H
+#define LIBVLCJNI_NATIVE_CRASH_HANDLER_H
+
+#include <jni.h>
+
+void init_native_crash_handler(JNIEnv *env, jobject j_libVLC_local);
+void destroy_native_crash_handler(JNIEnv *env);
+
+#endif // LIBVLCJNI_NATIVE_CRASH_HANDLER_H
diff --git a/vlc-android/src/org/videolan/libvlc/LibVLC.java b/vlc-android/src/org/videolan/libvlc/LibVLC.java
index 49ab661..a86541e 100644
--- a/vlc-android/src/org/videolan/libvlc/LibVLC.java
+++ b/vlc-android/src/org/videolan/libvlc/LibVLC.java
@@ -683,4 +683,7 @@ public class LibVLC {
     public native String[] getPresets();
 
     public native float[] getPreset(int index);
+
+    private void onNativeCrash() {
+    }
 }



More information about the Android mailing list