Merge "If an application calls System.exit() terminate it immediately."
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 333c12c..cdd2ad1 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -52,6 +52,7 @@
private static final native void nativeZygoteInit();
private static final native void nativeFinishInit();
+ private static final native void nativeSetExitWithoutCleanup(boolean exitWithoutCleanup);
/**
* Use this to log a message when a thread exits due to an uncaught
@@ -281,6 +282,13 @@
private static void applicationInit(int targetSdkVersion, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
+ // If the application calls System.exit(), terminate the process
+ // immediately without running any shutdown hooks. It is not possible to
+ // shutdown an Android application gracefully. Among other things, the
+ // Android runtime shutdown hooks close the Binder driver, which can cause
+ // leftover running threads to crash before the process actually exits.
+ nativeSetExitWithoutCleanup(true);
+
// We want to be fairly aggressive about heap utilization, to avoid
// holding on to a lot of memory that isn't needed.
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index d33dccb..e705c47 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -199,6 +199,12 @@
gCurRuntime->onZygoteInit();
}
+static void com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup(JNIEnv* env,
+ jobject clazz, jboolean exitWithoutCleanup)
+{
+ gCurRuntime->setExitWithoutCleanup(exitWithoutCleanup);
+}
+
/*
* JNI registration.
*/
@@ -207,6 +213,8 @@
(void*) com_android_internal_os_RuntimeInit_nativeFinishInit },
{ "nativeZygoteInit", "()V",
(void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },
+ { "nativeSetExitWithoutCleanup", "(Z)V",
+ (void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },
};
int register_com_android_internal_os_RuntimeInit(JNIEnv* env)
@@ -220,7 +228,8 @@
/*static*/ JavaVM* AndroidRuntime::mJavaVM = NULL;
-AndroidRuntime::AndroidRuntime()
+AndroidRuntime::AndroidRuntime() :
+ mExitWithoutCleanup(false)
{
SkGraphics::Init();
// this sets our preference for 16bit images during decode
@@ -298,8 +307,7 @@
*/
static void runtime_exit(int code)
{
- gCurRuntime->onExit(code);
- exit(code);
+ gCurRuntime->exit(code);
}
/*
@@ -870,10 +878,16 @@
ALOGW("Warning: VM did not shut down cleanly\n");
}
-void AndroidRuntime::onExit(int code)
+void AndroidRuntime::exit(int code)
{
- ALOGV("AndroidRuntime onExit calling exit(%d)", code);
- exit(code);
+ if (mExitWithoutCleanup) {
+ ALOGI("VM exiting with result code %d, cleanup skipped.", code);
+ ::_exit(code);
+ } else {
+ ALOGI("VM exiting with result code %d.", code);
+ onExit(code);
+ ::exit(code);
+ }
}
void AndroidRuntime::onVmCreated(JNIEnv* env)
diff --git a/include/android_runtime/AndroidRuntime.h b/include/android_runtime/AndroidRuntime.h
index fd33d59..0b3ce9a 100644
--- a/include/android_runtime/AndroidRuntime.h
+++ b/include/android_runtime/AndroidRuntime.h
@@ -66,6 +66,12 @@
void start(const char *classname, const char* options);
+ void exit(int code);
+
+ void setExitWithoutCleanup(bool exitWithoutCleanup) {
+ mExitWithoutCleanup = exitWithoutCleanup;
+ }
+
static AndroidRuntime* getRuntime();
/**
@@ -86,14 +92,13 @@
* fork. Override it to initialize threads, etc. Upon return, the
* correct static main will be invoked.
*/
- virtual void onZygoteInit() {};
-
+ virtual void onZygoteInit() { }
/**
- * Called when the Java application exits. The default
- * implementation calls exit(code).
+ * Called when the Java application exits to perform additional cleanup actions
+ * before the process is terminated.
*/
- virtual void onExit(int code);
+ virtual void onExit(int code) { }
/** create a new thread that is visible from Java */
static android_thread_id_t createJavaThread(const char* name, void (*start)(void *),
@@ -114,6 +119,7 @@
int startVm(JavaVM** pJavaVM, JNIEnv** pEnv);
Vector<JavaVMOption> mOptions;
+ bool mExitWithoutCleanup;
/* JNI JavaVM pointer */
static JavaVM* mJavaVM;