Skip to content

Commit dbff910

Browse files
Jeff BrownAndroid Code Review
authored andcommitted
Merge "Support wrapping app processes to inject debug instrumentation. Bug: 4437846"
2 parents e15a73e + d5d7e16 commit dbff910

File tree

13 files changed

+638
-227
lines changed

13 files changed

+638
-227
lines changed

cmds/app_process/app_main.cpp

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,7 @@ int main(int argc, const char* const argv[])
128128
mArgLen--;
129129

130130
AppRuntime runtime;
131-
const char *arg;
132-
const char *argv0;
133-
134-
argv0 = argv[0];
131+
const char* argv0 = argv[0];
135132

136133
// Process command line arguments
137134
// ignore argv[0]
@@ -142,39 +139,53 @@ int main(int argc, const char* const argv[])
142139

143140
int i = runtime.addVmArguments(argc, argv);
144141

145-
// Next arg is parent directory
146-
if (i < argc) {
147-
runtime.mParentDir = argv[i++];
148-
}
149-
150-
// Next arg is startup classname or "--zygote"
151-
if (i < argc) {
152-
arg = argv[i++];
153-
if (0 == strcmp("--zygote", arg)) {
154-
bool startSystemServer = (i < argc) ?
155-
strcmp(argv[i], "--start-system-server") == 0 : false;
156-
setArgv0(argv0, "zygote");
157-
set_process_name("zygote");
158-
runtime.start("com.android.internal.os.ZygoteInit",
159-
startSystemServer);
142+
// Parse runtime arguments. Stop at first unrecognized option.
143+
bool zygote = false;
144+
bool startSystemServer = false;
145+
bool application = false;
146+
const char* parentDir = NULL;
147+
const char* niceName = NULL;
148+
const char* className = NULL;
149+
while (i < argc) {
150+
const char* arg = argv[i++];
151+
if (!parentDir) {
152+
parentDir = arg;
153+
} else if (strcmp(arg, "--zygote") == 0) {
154+
zygote = true;
155+
niceName = "zygote";
156+
} else if (strcmp(arg, "--start-system-server") == 0) {
157+
startSystemServer = true;
158+
} else if (strcmp(arg, "--application") == 0) {
159+
application = true;
160+
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
161+
niceName = arg + 12;
160162
} else {
161-
set_process_name(argv0);
162-
163-
runtime.mClassName = arg;
163+
className = arg;
164+
break;
165+
}
166+
}
164167

165-
// Remainder of args get passed to startup class main()
166-
runtime.mArgC = argc-i;
167-
runtime.mArgV = argv+i;
168+
if (niceName && *niceName) {
169+
setArgv0(argv0, niceName);
170+
set_process_name(niceName);
171+
}
168172

169-
LOGV("App process is starting with pid=%d, class=%s.\n",
170-
getpid(), runtime.getClassName());
171-
runtime.start();
172-
}
173+
runtime.mParentDir = parentDir;
174+
175+
if (zygote) {
176+
runtime.start("com.android.internal.os.ZygoteInit",
177+
startSystemServer ? "start-system-server" : "");
178+
} else if (className) {
179+
// Remainder of args get passed to startup class main()
180+
runtime.mClassName = className;
181+
runtime.mArgC = argc - i;
182+
runtime.mArgV = argv + i;
183+
runtime.start("com.android.internal.os.RuntimeInit",
184+
application ? "application" : "tool");
173185
} else {
174186
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
175187
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
176188
app_usage();
177189
return 10;
178190
}
179-
180191
}

cmds/runtime/main_runtime.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -497,8 +497,8 @@ int main(int argc, char* const argv[])
497497
} else {
498498
#ifndef HAVE_ANDROID_OS
499499
QuickRuntime* runt = new QuickRuntime();
500-
runt->start("com/android/server/SystemServer",
501-
false /* spontaneously fork system server from zygote */);
500+
runt->start("com/android/server/SystemServer",
501+
"" /* spontaneously fork system server from zygote */);
502502
#endif
503503
}
504504

core/java/android/os/Process.java

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -257,13 +257,12 @@ public class Process {
257257
* @param enableDebugger True if debugging should be enabled for this process.
258258
* @param zygoteArgs Additional arguments to supply to the zygote process.
259259
*
260-
* @return int If > 0 the pid of the new process; if 0 the process is
261-
* being emulated by a thread
260+
* @return An object that describes the result of the attempt to start the process.
262261
* @throws RuntimeException on fatal start failure
263262
*
264263
* {@hide}
265264
*/
266-
public static final int start(final String processClass,
265+
public static final ProcessStartResult start(final String processClass,
267266
final String niceName,
268267
int uid, int gid, int[] gids,
269268
int debugFlags,
@@ -294,16 +293,15 @@ public void run() {
294293
} else {
295294
new Thread(runnable).start();
296295
}
297-
298-
return 0;
296+
return new ProcessStartResult();
299297
}
300298
}
301299

302300
/**
303301
* Start a new process. Don't supply a custom nice name.
304302
* {@hide}
305303
*/
306-
public static final int start(String processClass, int uid, int gid,
304+
public static final ProcessStartResult start(String processClass, int uid, int gid,
307305
int[] gids, int debugFlags, String[] zygoteArgs) {
308306
return start(processClass, "", uid, gid, gids,
309307
debugFlags, zygoteArgs);
@@ -418,14 +416,11 @@ private static void openZygoteSocketIfNeeded()
418416
* and returns the child's pid. Please note: the present implementation
419417
* replaces newlines in the argument list with spaces.
420418
* @param args argument list
421-
* @return PID of new child process
419+
* @return An object that describes the result of the attempt to start the process.
422420
* @throws ZygoteStartFailedEx if process start failed for any reason
423421
*/
424-
private static int zygoteSendArgsAndGetPid(ArrayList<String> args)
422+
private static ProcessStartResult zygoteSendArgsAndGetResult(ArrayList<String> args)
425423
throws ZygoteStartFailedEx {
426-
427-
int pid;
428-
429424
openZygoteSocketIfNeeded();
430425

431426
try {
@@ -436,7 +431,8 @@ private static int zygoteSendArgsAndGetPid(ArrayList<String> args)
436431
* b) a number of newline-separated argument strings equal to count
437432
*
438433
* After the zygote process reads these it will write the pid of
439-
* the child or -1 on failure.
434+
* the child or -1 on failure, followed by boolean to
435+
* indicate whether a wrapper process was used.
440436
*/
441437

442438
sZygoteWriter.write(Integer.toString(args.size()));
@@ -456,11 +452,13 @@ private static int zygoteSendArgsAndGetPid(ArrayList<String> args)
456452
sZygoteWriter.flush();
457453

458454
// Should there be a timeout on this?
459-
pid = sZygoteInputStream.readInt();
460-
461-
if (pid < 0) {
455+
ProcessStartResult result = new ProcessStartResult();
456+
result.pid = sZygoteInputStream.readInt();
457+
if (result.pid < 0) {
462458
throw new ZygoteStartFailedEx("fork() failed");
463459
}
460+
result.usingWrapper = sZygoteInputStream.readBoolean();
461+
return result;
464462
} catch (IOException ex) {
465463
try {
466464
if (sZygoteSocket != null) {
@@ -475,8 +473,6 @@ private static int zygoteSendArgsAndGetPid(ArrayList<String> args)
475473

476474
throw new ZygoteStartFailedEx(ex);
477475
}
478-
479-
return pid;
480476
}
481477

482478
/**
@@ -490,18 +486,16 @@ private static int zygoteSendArgsAndGetPid(ArrayList<String> args)
490486
* new process should setgroup() to.
491487
* @param enableDebugger True if debugging should be enabled for this process.
492488
* @param extraArgs Additional arguments to supply to the zygote process.
493-
* @return PID
489+
* @return An object that describes the result of the attempt to start the process.
494490
* @throws ZygoteStartFailedEx if process start failed for any reason
495491
*/
496-
private static int startViaZygote(final String processClass,
492+
private static ProcessStartResult startViaZygote(final String processClass,
497493
final String niceName,
498494
final int uid, final int gid,
499495
final int[] gids,
500496
int debugFlags,
501497
String[] extraArgs)
502498
throws ZygoteStartFailedEx {
503-
int pid;
504-
505499
synchronized(Process.class) {
506500
ArrayList<String> argsForZygote = new ArrayList<String>();
507501

@@ -553,15 +547,9 @@ private static int startViaZygote(final String processClass,
553547
argsForZygote.add(arg);
554548
}
555549
}
556-
557-
pid = zygoteSendArgsAndGetPid(argsForZygote);
558-
}
559550

560-
if (pid <= 0) {
561-
throw new ZygoteStartFailedEx("zygote start failed:" + pid);
551+
return zygoteSendArgsAndGetResult(argsForZygote);
562552
}
563-
564-
return pid;
565553
}
566554

567555
/**
@@ -615,6 +603,20 @@ public static final int getUidForPid(int pid) {
615603
return (int) procStatusValues[0];
616604
}
617605

606+
/**
607+
* Returns the parent process id for a currently running process.
608+
* @param pid the process id
609+
* @return the parent process id of the process, or -1 if the process is not running.
610+
* @hide
611+
*/
612+
public static final int getParentPid(int pid) {
613+
String[] procStatusLabels = { "PPid:" };
614+
long[] procStatusValues = new long[1];
615+
procStatusValues[0] = -1;
616+
Process.readProcLines("/proc/" + pid + "/status", procStatusLabels, procStatusValues);
617+
return (int) procStatusValues[0];
618+
}
619+
618620
/**
619621
* Set the priority of a thread, based on Linux priorities.
620622
*
@@ -826,4 +828,21 @@ public static final native boolean parseProcLine(byte[] buffer, int startIndex,
826828
* @hide
827829
*/
828830
public static final native long getPss(int pid);
831+
832+
/**
833+
* Specifies the outcome of having started a process.
834+
* @hide
835+
*/
836+
public static final class ProcessStartResult {
837+
/**
838+
* The PID of the newly started process.
839+
* Always >= 0. (If the start failed, an exception will have been thrown instead.)
840+
*/
841+
public int pid;
842+
843+
/**
844+
* True if the process was started with a wrapper attached.
845+
*/
846+
public boolean usingWrapper;
847+
}
829848
}

0 commit comments

Comments
 (0)