Merge "If an application calls System.exit() terminate it immediately."
This commit is contained in:
@@ -52,6 +52,7 @@ public class RuntimeInit {
|
||||
|
||||
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 @@ public class RuntimeInit {
|
||||
|
||||
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);
|
||||
|
||||
@@ -199,6 +199,12 @@ static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jo
|
||||
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 @@ static JNINativeMethod gMethods[] = {
|
||||
(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 @@ int register_com_android_internal_os_RuntimeInit(JNIEnv* env)
|
||||
/*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 @@ status_t AndroidRuntime::callMain(const char* className,
|
||||
*/
|
||||
static void runtime_exit(int code)
|
||||
{
|
||||
gCurRuntime->onExit(code);
|
||||
exit(code);
|
||||
gCurRuntime->exit(code);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -870,10 +878,16 @@ void AndroidRuntime::start(const char* className, const char* options)
|
||||
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)
|
||||
|
||||
@@ -66,6 +66,12 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
* 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 @@ private:
|
||||
int startVm(JavaVM** pJavaVM, JNIEnv** pEnv);
|
||||
|
||||
Vector<JavaVMOption> mOptions;
|
||||
bool mExitWithoutCleanup;
|
||||
|
||||
/* JNI JavaVM pointer */
|
||||
static JavaVM* mJavaVM;
|
||||
|
||||
Reference in New Issue
Block a user