Skip to content

Commit 543ec1c

Browse files
Jeff BrownAndroid (Google) Code Review
authored andcommitted
Merge "If an application calls System.exit() terminate it immediately."
2 parents c1ac23d + 4280c4a commit 543ec1c

File tree

3 files changed

+39
-11
lines changed

3 files changed

+39
-11
lines changed

core/java/com/android/internal/os/RuntimeInit.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public class RuntimeInit {
5252

5353
private static final native void nativeZygoteInit();
5454
private static final native void nativeFinishInit();
55+
private static final native void nativeSetExitWithoutCleanup(boolean exitWithoutCleanup);
5556

5657
/**
5758
* Use this to log a message when a thread exits due to an uncaught
@@ -281,6 +282,13 @@ public static void wrapperInit(int targetSdkVersion, String[] argv)
281282

282283
private static void applicationInit(int targetSdkVersion, String[] argv)
283284
throws ZygoteInit.MethodAndArgsCaller {
285+
// If the application calls System.exit(), terminate the process
286+
// immediately without running any shutdown hooks. It is not possible to
287+
// shutdown an Android application gracefully. Among other things, the
288+
// Android runtime shutdown hooks close the Binder driver, which can cause
289+
// leftover running threads to crash before the process actually exits.
290+
nativeSetExitWithoutCleanup(true);
291+
284292
// We want to be fairly aggressive about heap utilization, to avoid
285293
// holding on to a lot of memory that isn't needed.
286294
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);

core/jni/AndroidRuntime.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,12 @@ static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jo
199199
gCurRuntime->onZygoteInit();
200200
}
201201

202+
static void com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup(JNIEnv* env,
203+
jobject clazz, jboolean exitWithoutCleanup)
204+
{
205+
gCurRuntime->setExitWithoutCleanup(exitWithoutCleanup);
206+
}
207+
202208
/*
203209
* JNI registration.
204210
*/
@@ -207,6 +213,8 @@ static JNINativeMethod gMethods[] = {
207213
(void*) com_android_internal_os_RuntimeInit_nativeFinishInit },
208214
{ "nativeZygoteInit", "()V",
209215
(void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },
216+
{ "nativeSetExitWithoutCleanup", "(Z)V",
217+
(void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },
210218
};
211219

212220
int register_com_android_internal_os_RuntimeInit(JNIEnv* env)
@@ -220,7 +228,8 @@ int register_com_android_internal_os_RuntimeInit(JNIEnv* env)
220228
/*static*/ JavaVM* AndroidRuntime::mJavaVM = NULL;
221229

222230

223-
AndroidRuntime::AndroidRuntime()
231+
AndroidRuntime::AndroidRuntime() :
232+
mExitWithoutCleanup(false)
224233
{
225234
SkGraphics::Init();
226235
// this sets our preference for 16bit images during decode
@@ -298,8 +307,7 @@ status_t AndroidRuntime::callMain(const char* className,
298307
*/
299308
static void runtime_exit(int code)
300309
{
301-
gCurRuntime->onExit(code);
302-
exit(code);
310+
gCurRuntime->exit(code);
303311
}
304312

305313
/*
@@ -870,10 +878,16 @@ void AndroidRuntime::start(const char* className, const char* options)
870878
ALOGW("Warning: VM did not shut down cleanly\n");
871879
}
872880

873-
void AndroidRuntime::onExit(int code)
881+
void AndroidRuntime::exit(int code)
874882
{
875-
ALOGV("AndroidRuntime onExit calling exit(%d)", code);
876-
exit(code);
883+
if (mExitWithoutCleanup) {
884+
ALOGI("VM exiting with result code %d, cleanup skipped.", code);
885+
::_exit(code);
886+
} else {
887+
ALOGI("VM exiting with result code %d.", code);
888+
onExit(code);
889+
::exit(code);
890+
}
877891
}
878892

879893
void AndroidRuntime::onVmCreated(JNIEnv* env)

include/android_runtime/AndroidRuntime.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ class AndroidRuntime
6666

6767
void start(const char *classname, const char* options);
6868

69+
void exit(int code);
70+
71+
void setExitWithoutCleanup(bool exitWithoutCleanup) {
72+
mExitWithoutCleanup = exitWithoutCleanup;
73+
}
74+
6975
static AndroidRuntime* getRuntime();
7076

7177
/**
@@ -86,14 +92,13 @@ class AndroidRuntime
8692
* fork. Override it to initialize threads, etc. Upon return, the
8793
* correct static main will be invoked.
8894
*/
89-
virtual void onZygoteInit() {};
90-
95+
virtual void onZygoteInit() { }
9196

9297
/**
93-
* Called when the Java application exits. The default
94-
* implementation calls exit(code).
98+
* Called when the Java application exits to perform additional cleanup actions
99+
* before the process is terminated.
95100
*/
96-
virtual void onExit(int code);
101+
virtual void onExit(int code) { }
97102

98103
/** create a new thread that is visible from Java */
99104
static android_thread_id_t createJavaThread(const char* name, void (*start)(void *),
@@ -114,6 +119,7 @@ class AndroidRuntime
114119
int startVm(JavaVM** pJavaVM, JNIEnv** pEnv);
115120

116121
Vector<JavaVMOption> mOptions;
122+
bool mExitWithoutCleanup;
117123

118124
/* JNI JavaVM pointer */
119125
static JavaVM* mJavaVM;

0 commit comments

Comments
 (0)