blob: 7adb27cd9e36d04ef79ea1e191e27ff8935fc17c [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.os;
18
Sudheer Shankadc589ac2016-11-10 15:30:17 -080019import android.app.ActivityManager;
Eric Rowe35980b22013-09-03 10:51:15 -070020import android.app.ActivityThread;
Dan Egnorb7f03672009-12-09 16:22:32 -080021import android.app.ApplicationErrorReport;
Evgenii Stepanovcba0c362020-01-22 15:01:31 -080022import android.compat.annotation.ChangeId;
23import android.compat.annotation.EnabledAfter;
Artur Satayevae5bcf22019-12-10 17:47:54 +000024import android.compat.annotation.UnsupportedAppUsage;
Tobias Thiereraf0cef92019-09-27 17:08:49 +010025import android.content.type.DefaultMimeMapFactory;
Dan Egnorb7f03672009-12-09 16:22:32 -080026import android.os.Build;
Jeff Sharkeyf8880562016-02-26 13:03:01 -070027import android.os.DeadObjectException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.os.Debug;
29import android.os.IBinder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.os.SystemProperties;
Narayan Kamathfbb32f62015-06-12 15:34:35 +010032import android.os.Trace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.util.Log;
Dianne Hackbornc9421ba2010-03-11 22:23:46 -080034import android.util.Slog;
David Sehra4944492019-12-06 13:03:29 -080035
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import com.android.internal.logging.AndroidConfig;
Jesse Wilson8568db52011-06-28 19:06:31 -070037import com.android.server.NetworkManagementSocketTagger;
David Sehra4944492019-12-06 13:03:29 -080038
Evgenii Stepanovcba0c362020-01-22 15:01:31 -080039import dalvik.annotation.compat.VersionCodes;
Neil Fullera84056a2018-07-11 13:59:45 +010040import dalvik.system.RuntimeHooks;
Rick Yiu2c7729e2020-01-08 16:00:59 +080041import dalvik.system.ThreadPrioritySetter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import dalvik.system.VMRuntime;
Tobias Thierer878c77b2019-08-18 15:19:45 +010043
Tobias Thierer8edd8372019-10-03 13:43:21 +010044import libcore.content.type.MimeMap;
Tobias Thierer878c77b2019-08-18 15:19:45 +010045
Narayan Kamathac0b4be2017-07-05 14:45:38 +010046import java.lang.reflect.InvocationTargetException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import java.lang.reflect.Method;
48import java.lang.reflect.Modifier;
Andreas Gampe50fa1222018-04-02 14:00:47 -070049import java.util.Objects;
Jesse Wilson8568db52011-06-28 19:06:31 -070050import java.util.logging.LogManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051
52/**
53 * Main entry point for runtime initialization. Not for
54 * public consumption.
55 * @hide
56 */
57public class RuntimeInit {
Andreas Gampe76d4fc82017-02-07 19:44:37 -080058 final static String TAG = "AndroidRuntime";
59 final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060
61 /** true if commonInit() has been called */
Andrei Oneaeecddd52019-03-27 10:32:55 +000062 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 private static boolean initialized;
64
Andrei Oneaeecddd52019-03-27 10:32:55 +000065 @UnsupportedAppUsage
Dan Egnor60d87622009-12-16 16:32:58 -080066 private static IBinder mApplicationObject;
67
68 private static volatile boolean mCrashing = false;
69
Evgenii Stepanovcba0c362020-01-22 15:01:31 -080070 /*
71 * Native heap allocations will now have a non-zero tag in the most significant byte.
72 * See {@linktourl https://source.android.com/devices/tech/debug/tagged-pointers}.
73 */
74 @ChangeId
75 @EnabledAfter(targetSdkVersion = VersionCodes.Q)
76 private static final long NATIVE_HEAP_POINTER_TAGGING = 135754954; // This is a bug id.
77
Jeff Brown16f5f5c2012-03-15 16:53:55 -070078 private static final native void nativeFinishInit();
Jeff Brown4280c4a2012-03-15 17:48:02 -070079 private static final native void nativeSetExitWithoutCleanup(boolean exitWithoutCleanup);
Evgenii Stepanovcba0c362020-01-22 15:01:31 -080080 private static native void nativeDisableHeapPointerTagging();
Jeff Brown16f5f5c2012-03-15 16:53:55 -070081
Mark Salyzyn69eb6f52014-04-09 07:39:15 -070082 private static int Clog_e(String tag, String msg, Throwable tr) {
Andreas Gamped888beb2016-02-18 14:01:41 -080083 return Log.printlns(Log.LOG_ID_CRASH, Log.ERROR, tag, msg, tr);
Mark Salyzyn69eb6f52014-04-09 07:39:15 -070084 }
85
Andreas Gampe8695b402019-06-18 12:36:46 -070086 public static void logUncaught(String threadName, String processName, int pid, Throwable e) {
87 StringBuilder message = new StringBuilder();
88 // The "FATAL EXCEPTION" string is still used on Android even though
89 // apps can set a custom UncaughtExceptionHandler that renders uncaught
90 // exceptions non-fatal.
91 message.append("FATAL EXCEPTION: ").append(threadName).append("\n");
92 if (processName != null) {
93 message.append("Process: ").append(processName).append(", ");
94 }
95 message.append("PID: ").append(pid);
96 Clog_e(TAG, message.toString(), e);
97 }
98
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 /**
Tobias Thiereraddbf902016-07-21 15:05:19 +0100100 * Logs a message when a thread encounters an uncaught exception. By
101 * default, {@link KillApplicationHandler} will terminate this process later,
102 * but apps can override that behavior.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 */
Tobias Thiereraddbf902016-07-21 15:05:19 +0100104 private static class LoggingHandler implements Thread.UncaughtExceptionHandler {
Andreas Gampe50fa1222018-04-02 14:00:47 -0700105 public volatile boolean mTriggered = false;
106
Tobias Thiereraddbf902016-07-21 15:05:19 +0100107 @Override
108 public void uncaughtException(Thread t, Throwable e) {
Andreas Gampe50fa1222018-04-02 14:00:47 -0700109 mTriggered = true;
110
Tobias Thiereraddbf902016-07-21 15:05:19 +0100111 // Don't re-enter if KillApplicationHandler has already run
112 if (mCrashing) return;
yuanhuihuie669ac22017-03-18 19:34:31 +0800113
114 // mApplicationObject is null for non-zygote java programs (e.g. "am")
115 // There are also apps running with the system UID. We don't want the
116 // first clause in either of these two cases, only for system_server.
117 if (mApplicationObject == null && (Process.SYSTEM_UID == Process.myUid())) {
Tobias Thiereraddbf902016-07-21 15:05:19 +0100118 Clog_e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e);
119 } else {
Andreas Gampe8695b402019-06-18 12:36:46 -0700120 logUncaught(t.getName(), ActivityThread.currentProcessName(), Process.myPid(), e);
Tobias Thiereraddbf902016-07-21 15:05:19 +0100121 }
122 }
123 }
124
125 /**
126 * Handle application death from an uncaught exception. The framework
127 * catches these for the main threads, so this should only matter for
Andreas Gampe50fa1222018-04-02 14:00:47 -0700128 * threads created by applications. Before this method runs, the given
129 * instance of {@link LoggingHandler} should already have logged details
130 * (and if not it is run first).
Tobias Thiereraddbf902016-07-21 15:05:19 +0100131 */
132 private static class KillApplicationHandler implements Thread.UncaughtExceptionHandler {
Andreas Gampe50fa1222018-04-02 14:00:47 -0700133 private final LoggingHandler mLoggingHandler;
134
135 /**
136 * Create a new KillApplicationHandler that follows the given LoggingHandler.
137 * If {@link #uncaughtException(Thread, Throwable) uncaughtException} is called
138 * on the created instance without {@code loggingHandler} having been triggered,
139 * {@link LoggingHandler#uncaughtException(Thread, Throwable)
140 * loggingHandler.uncaughtException} will be called first.
141 *
142 * @param loggingHandler the {@link LoggingHandler} expected to have run before
143 * this instance's {@link #uncaughtException(Thread, Throwable) uncaughtException}
144 * is being called.
145 */
146 public KillApplicationHandler(LoggingHandler loggingHandler) {
147 this.mLoggingHandler = Objects.requireNonNull(loggingHandler);
148 }
149
150 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 public void uncaughtException(Thread t, Throwable e) {
152 try {
Andreas Gampe50fa1222018-04-02 14:00:47 -0700153 ensureLogging(t, e);
154
Dan Egnor60d87622009-12-16 16:32:58 -0800155 // Don't re-enter -- avoid infinite loops if crash-reporting crashes.
156 if (mCrashing) return;
157 mCrashing = true;
158
Andreas Gampe4c79fea2016-01-28 20:11:41 -0800159 // Try to end profiling. If a profiler is running at this point, and we kill the
160 // process (below), the in-memory buffer will be lost. So try to stop, which will
161 // flush the buffer. (This makes method trace profiling useful to debug crashes.)
162 if (ActivityThread.currentActivityThread() != null) {
163 ActivityThread.currentActivityThread().stopProfiling();
164 }
165
Dan Egnor60d87622009-12-16 16:32:58 -0800166 // Bring up crash dialog, wait for it to be dismissed
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800167 ActivityManager.getService().handleApplicationCrash(
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700168 mApplicationObject, new ApplicationErrorReport.ParcelableCrashInfo(e));
Dan Egnor60d87622009-12-16 16:32:58 -0800169 } catch (Throwable t2) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700170 if (t2 instanceof DeadObjectException) {
171 // System process is dead; ignore
172 } else {
173 try {
174 Clog_e(TAG, "Error reporting crash", t2);
175 } catch (Throwable t3) {
176 // Even Clog_e() fails! Oh well.
177 }
Dan Egnor60d87622009-12-16 16:32:58 -0800178 }
179 } finally {
180 // Try everything to make sure this process goes away.
181 Process.killProcess(Process.myPid());
182 System.exit(10);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 }
Andreas Gampe50fa1222018-04-02 14:00:47 -0700185
186 /**
187 * Ensures that the logging handler has been triggered.
188 *
189 * See b/73380984. This reinstates the pre-O behavior of
190 *
191 * {@code thread.getUncaughtExceptionHandler().uncaughtException(thread, e);}
192 *
193 * logging the exception (in addition to killing the app). This behavior
194 * was never documented / guaranteed but helps in diagnostics of apps
195 * using the pattern.
196 *
197 * If this KillApplicationHandler is invoked the "regular" way (by
198 * {@link Thread#dispatchUncaughtException(Throwable)
199 * Thread.dispatchUncaughtException} in case of an uncaught exception)
200 * then the pre-handler (expected to be {@link #mLoggingHandler}) will already
201 * have run. Otherwise, we manually invoke it here.
202 */
203 private void ensureLogging(Thread t, Throwable e) {
204 if (!mLoggingHandler.mTriggered) {
205 try {
206 mLoggingHandler.uncaughtException(t, e);
207 } catch (Throwable loggingThrowable) {
208 // Ignored.
209 }
210 }
211 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 }
213
Tobias Thierera45917e2019-09-26 16:03:28 +0100214 /**
215 * Common initialization that (unlike {@link #commonInit()} should happen prior to
216 * the Zygote fork.
217 */
218 public static void preForkInit() {
219 if (DEBUG) Slog.d(TAG, "Entered preForkInit.");
Rick Yiu2c7729e2020-01-08 16:00:59 +0800220 RuntimeHooks.setThreadPrioritySetter(new RuntimeThreadPrioritySetter());
Tobias Thierera45917e2019-09-26 16:03:28 +0100221 RuntimeInit.enableDdms();
Tobias Thierer44356062019-10-04 00:31:59 +0100222 // TODO(b/142019040#comment13): Decide whether to load the default instance eagerly, i.e.
223 // MimeMap.setDefault(DefaultMimeMapFactory.create());
Tobias Thierer878c77b2019-08-18 15:19:45 +0100224 /*
225 * Replace libcore's minimal default mapping between MIME types and file
226 * extensions with a mapping that's suitable for Android. Android's mapping
227 * contains many more entries that are derived from IANA registrations but
228 * with several customizations (extensions, overrides).
229 */
Tobias Thierer44356062019-10-04 00:31:59 +0100230 MimeMap.setDefaultSupplier(DefaultMimeMapFactory::create);
Tobias Thierera45917e2019-09-26 16:03:28 +0100231 }
232
Rick Yiu2c7729e2020-01-08 16:00:59 +0800233 private static class RuntimeThreadPrioritySetter implements ThreadPrioritySetter {
234 // Should remain consistent with kNiceValues[] in system/libartpalette/palette_android.cc
235 private static final int[] NICE_VALUES = {
236 Process.THREAD_PRIORITY_LOWEST, // 1 (MIN_PRIORITY)
237 Process.THREAD_PRIORITY_BACKGROUND + 6,
238 Process.THREAD_PRIORITY_BACKGROUND + 3,
239 Process.THREAD_PRIORITY_BACKGROUND,
240 Process.THREAD_PRIORITY_DEFAULT, // 5 (NORM_PRIORITY)
241 Process.THREAD_PRIORITY_DEFAULT - 2,
242 Process.THREAD_PRIORITY_DEFAULT - 4,
243 Process.THREAD_PRIORITY_URGENT_DISPLAY + 3,
244 Process.THREAD_PRIORITY_URGENT_DISPLAY + 2,
245 Process.THREAD_PRIORITY_URGENT_DISPLAY // 10 (MAX_PRIORITY)
246 };
247
248 @Override
249 public void setPriority(int nativeTid, int priority) {
250 // Check NICE_VALUES[] length first.
251 if (NICE_VALUES.length != (1 + Thread.MAX_PRIORITY - Thread.MIN_PRIORITY)) {
252 throw new AssertionError("Unexpected NICE_VALUES.length=" + NICE_VALUES.length);
253 }
254 // Priority should be in the range of MIN_PRIORITY (1) to MAX_PRIORITY (10).
255 if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
256 throw new IllegalArgumentException("Priority out of range: " + priority);
257 }
258 Process.setThreadPriority(nativeTid, NICE_VALUES[priority - Thread.MIN_PRIORITY]);
259 }
260 }
261
Andrei Oneaeecddd52019-03-27 10:32:55 +0000262 @UnsupportedAppUsage
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800263 protected static final void commonInit() {
Jeff Brownebed7d62011-05-16 17:08:42 -0700264 if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265
Tobias Thiereraddbf902016-07-21 15:05:19 +0100266 /*
267 * set handlers; these apply to all threads in the VM. Apps can replace
268 * the default handler, but not the pre handler.
269 */
Andreas Gampe50fa1222018-04-02 14:00:47 -0700270 LoggingHandler loggingHandler = new LoggingHandler();
Neil Fullera84056a2018-07-11 13:59:45 +0100271 RuntimeHooks.setUncaughtExceptionPreHandler(loggingHandler);
Andreas Gampe50fa1222018-04-02 14:00:47 -0700272 Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 /*
Neil Fullera84056a2018-07-11 13:59:45 +0100275 * Install a time zone supplier that uses the Android persistent time zone system property.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 */
Neil Fullera84056a2018-07-11 13:59:45 +0100277 RuntimeHooks.setTimeZoneIdSupplier(() -> SystemProperties.get("persist.sys.timezone"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278
279 /*
280 * Sets handler for java.util.logging to use Android log facilities.
281 * The odd "new instance-and-then-throw-away" is a mirror of how
282 * the "java.util.logging.config.class" system property works. We
283 * can't use the system property here since the logger has almost
284 * certainly already been initialized.
285 */
286 LogManager.getLogManager().reset();
287 new AndroidConfig();
288
289 /*
Jesse Wilsond0f80d42009-09-18 18:06:43 -0700290 * Sets the default HTTP User-Agent used by HttpURLConnection.
291 */
292 String userAgent = getDefaultUserAgent();
293 System.setProperty("http.agent", userAgent);
294
295 /*
Jesse Wilson8568db52011-06-28 19:06:31 -0700296 * Wire socket tagging to traffic stats.
297 */
298 NetworkManagementSocketTagger.install();
299
300 /*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 * If we're running in an emulator launched with "-trace", put the
302 * VM into emulator trace profiling mode so that the user can hit
303 * F9/F10 at any time to capture traces. This has performance
304 * consequences, so it's not something you want to do always.
305 */
306 String trace = SystemProperties.get("ro.kernel.android.tracing");
307 if (trace.equals("1")) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -0800308 Slog.i(TAG, "NOTE: emulator trace profiling enabled");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 Debug.enableEmulatorTraceOutput();
310 }
311
312 initialized = true;
313 }
314
315 /**
Jesse Wilsond0f80d42009-09-18 18:06:43 -0700316 * Returns an HTTP user agent of the form
317 * "Dalvik/1.1.0 (Linux; U; Android Eclair Build/MASTER)".
318 */
319 private static String getDefaultUserAgent() {
320 StringBuilder result = new StringBuilder(64);
321 result.append("Dalvik/");
322 result.append(System.getProperty("java.vm.version")); // such as 1.1.0
323 result.append(" (Linux; U; Android ");
324
325 String version = Build.VERSION.RELEASE; // "1.0" or "3.4b5"
326 result.append(version.length() > 0 ? version : "1.0");
327
328 // add the model for the release build
329 if ("REL".equals(Build.VERSION.CODENAME)) {
330 String model = Build.MODEL;
331 if (model.length() > 0) {
332 result.append("; ");
333 result.append(model);
334 }
335 }
336 String id = Build.ID; // "MASTER" or "M4-rc20"
337 if (id.length() > 0) {
338 result.append(" Build/");
339 result.append(id);
340 }
341 result.append(")");
342 return result.toString();
343 }
344
345 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 * Invokes a static "main(argv[]) method on class "className".
347 * Converts various failing exceptions into RuntimeExceptions, with
348 * the assumption that they will then cause the VM instance to exit.
349 *
350 * @param className Fully-qualified class name
351 * @param argv Argument vector for main()
Narayan Kamath29564cd2014-08-07 10:57:40 +0100352 * @param classLoader the classLoader to load {@className} with
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800353 */
Robert Sesekd0a190df2018-02-12 18:46:01 -0500354 protected static Runnable findStaticMain(String className, String[] argv,
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100355 ClassLoader classLoader) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356 Class<?> cl;
357
358 try {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100359 cl = Class.forName(className, true, classLoader);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 } catch (ClassNotFoundException ex) {
361 throw new RuntimeException(
362 "Missing class when invoking static main " + className,
363 ex);
364 }
365
366 Method m;
367 try {
368 m = cl.getMethod("main", new Class[] { String[].class });
369 } catch (NoSuchMethodException ex) {
370 throw new RuntimeException(
371 "Missing static main on " + className, ex);
372 } catch (SecurityException ex) {
373 throw new RuntimeException(
374 "Problem getting static main on " + className, ex);
375 }
376
377 int modifiers = m.getModifiers();
378 if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
379 throw new RuntimeException(
380 "Main method is not public and static on " + className);
381 }
382
383 /*
384 * This throw gets caught in ZygoteInit.main(), which responds
385 * by invoking the exception's run() method. This arrangement
386 * clears up all the stack frames that were required in setting
387 * up the process.
388 */
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100389 return new MethodAndArgsCaller(m, argv);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 }
391
Andrei Oneaeecddd52019-03-27 10:32:55 +0000392 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 public static final void main(String[] argv) {
Tobias Thierera45917e2019-09-26 16:03:28 +0100394 preForkInit();
Jeff Brownebed7d62011-05-16 17:08:42 -0700395 if (argv.length == 2 && argv[1].equals("application")) {
396 if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application");
397 redirectLogStreams();
398 } else {
399 if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting tool");
400 }
401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 commonInit();
Bob Leee5408332009-09-04 18:31:17 -0700403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 /*
405 * Now that we're running in interpreted code, call back into native code
406 * to run the system.
407 */
Jeff Brown16f5f5c2012-03-15 16:53:55 -0700408 nativeFinishInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409
Jeff Brownebed7d62011-05-16 17:08:42 -0700410 if (DEBUG) Slog.d(TAG, "Leaving RuntimeInit!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 }
Bob Leee5408332009-09-04 18:31:17 -0700412
Evgenii Stepanovcba0c362020-01-22 15:01:31 -0800413 private static void maybeDisableHeapPointerTagging(long[] disabledCompatChanges) {
414 // Heap tagging needs to be disabled before any additional threads are created, but the
415 // AppCompat framework is not initialized enough at this point.
416 // Check if the change is enabled manually.
417 if (disabledCompatChanges != null) {
418 for (int i = 0; i < disabledCompatChanges.length; i++) {
419 if (disabledCompatChanges[i] == NATIVE_HEAP_POINTER_TAGGING) {
420 nativeDisableHeapPointerTagging();
421 break;
422 }
423 }
424 }
425 }
426
atroste44e1342019-12-11 18:44:20 +0000427 protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
428 String[] argv, ClassLoader classLoader) {
Jeff Brown4280c4a2012-03-15 17:48:02 -0700429 // If the application calls System.exit(), terminate the process
430 // immediately without running any shutdown hooks. It is not possible to
431 // shutdown an Android application gracefully. Among other things, the
432 // Android runtime shutdown hooks close the Binder driver, which can cause
433 // leftover running threads to crash before the process actually exits.
434 nativeSetExitWithoutCleanup(true);
435
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700436 VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
atroste44e1342019-12-11 18:44:20 +0000437 VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);
Jeff Brownebed7d62011-05-16 17:08:42 -0700438
Evgenii Stepanovcba0c362020-01-22 15:01:31 -0800439 maybeDisableHeapPointerTagging(disabledCompatChanges);
440
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100441 final Arguments args = new Arguments(argv);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100443 // The end of of the RuntimeInit event (see #zygoteInit).
444 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446 // Remaining arguments are passed to the start class's static main
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100447 return findStaticMain(args.startClass, args.startArgs, classLoader);
Jeff Brownebed7d62011-05-16 17:08:42 -0700448 }
Bob Leee5408332009-09-04 18:31:17 -0700449
Jeff Brownebed7d62011-05-16 17:08:42 -0700450 /**
451 * Redirect System.out and System.err to the Android log.
452 */
453 public static void redirectLogStreams() {
454 System.out.close();
455 System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
456 System.err.close();
457 System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 }
459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800460 /**
Dan Egnor60d87622009-12-16 16:32:58 -0800461 * Report a serious error in the current process. May or may not cause
462 * the process to terminate (depends on system settings).
Bob Leee5408332009-09-04 18:31:17 -0700463 *
Dan Egnor60d87622009-12-16 16:32:58 -0800464 * @param tag to record with the error
465 * @param t exception describing the error site and conditions
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466 */
Dianne Hackborn52322712014-08-26 22:47:26 -0700467 public static void wtf(String tag, Throwable t, boolean system) {
Dan Egnor60d87622009-12-16 16:32:58 -0800468 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800469 if (ActivityManager.getService().handleApplicationWtf(
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700470 mApplicationObject, tag, system,
471 new ApplicationErrorReport.ParcelableCrashInfo(t))) {
Dan Egnor60d87622009-12-16 16:32:58 -0800472 // The Activity Manager has already written us off -- now exit.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 Process.killProcess(Process.myPid());
474 System.exit(10);
475 }
Dan Egnor60d87622009-12-16 16:32:58 -0800476 } catch (Throwable t2) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700477 if (t2 instanceof DeadObjectException) {
478 // System process is dead; ignore
479 } else {
480 Slog.e(TAG, "Error reporting WTF", t2);
481 Slog.e(TAG, "Original WTF:", t);
482 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483 }
484 }
485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487 * Set the object identifying this application/process, for reporting VM
488 * errors.
489 */
490 public static final void setApplicationObject(IBinder app) {
491 mApplicationObject = app;
492 }
493
Andrei Oneaeecddd52019-03-27 10:32:55 +0000494 @UnsupportedAppUsage
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700495 public static final IBinder getApplicationObject() {
496 return mApplicationObject;
497 }
498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 /**
Piotr Jastrzebskida74a622015-02-12 13:55:23 +0000500 * Enable DDMS.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 */
Tobias Thierera45917e2019-09-26 16:03:28 +0100502 private static void enableDdms() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 // Register handlers for DDM messages.
504 android.ddm.DdmRegister.registerHandlers();
505 }
Jeff Brownebed7d62011-05-16 17:08:42 -0700506
507 /**
508 * Handles argument parsing for args related to the runtime.
509 *
510 * Current recognized args:
511 * <ul>
512 * <li> <code> [--] &lt;start class name&gt; &lt;args&gt;
513 * </ul>
514 */
515 static class Arguments {
516 /** first non-option argument */
517 String startClass;
518
519 /** all following arguments */
520 String[] startArgs;
521
522 /**
523 * Constructs instance and parses args
524 * @param args runtime command-line args
525 * @throws IllegalArgumentException
526 */
527 Arguments(String args[]) throws IllegalArgumentException {
528 parseArgs(args);
529 }
530
531 /**
532 * Parses the commandline arguments intended for the Runtime.
533 */
534 private void parseArgs(String args[])
535 throws IllegalArgumentException {
536 int curArg = 0;
537 for (; curArg < args.length; curArg++) {
538 String arg = args[curArg];
539
540 if (arg.equals("--")) {
541 curArg++;
542 break;
543 } else if (!arg.startsWith("--")) {
544 break;
545 }
546 }
547
548 if (curArg == args.length) {
549 throw new IllegalArgumentException("Missing classname argument to RuntimeInit!");
550 }
551
552 startClass = args[curArg++];
553 startArgs = new String[args.length - curArg];
554 System.arraycopy(args, curArg, startArgs, 0, startArgs.length);
555 }
556 }
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100557
558 /**
559 * Helper class which holds a method and arguments and can call them. This is used as part of
560 * a trampoline to get rid of the initial process setup stack frames.
561 */
562 static class MethodAndArgsCaller implements Runnable {
563 /** method to call */
564 private final Method mMethod;
565
566 /** argument array */
567 private final String[] mArgs;
568
569 public MethodAndArgsCaller(Method method, String[] args) {
570 mMethod = method;
571 mArgs = args;
572 }
573
574 public void run() {
575 try {
576 mMethod.invoke(null, new Object[] { mArgs });
577 } catch (IllegalAccessException ex) {
578 throw new RuntimeException(ex);
579 } catch (InvocationTargetException ex) {
580 Throwable cause = ex.getCause();
581 if (cause instanceof RuntimeException) {
582 throw (RuntimeException) cause;
583 } else if (cause instanceof Error) {
584 throw (Error) cause;
585 }
586 throw new RuntimeException(ex);
587 }
588 }
589 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590}