Merge "ActivityThread: Attempt to attach agent with app's classloader" am: f779d7e3be

am: 9f1f950c31

Change-Id: I0df113aff5a54c5a1dbc5f968679bb9d4f8ea158
This commit is contained in:
Andreas Gampe
2018-01-16 19:59:02 +00:00
committed by android-build-merger
4 changed files with 73 additions and 15 deletions

View File

@@ -1832,9 +1832,11 @@ public final class ActivityThread {
handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1, handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1,
(IVoiceInteractor) ((SomeArgs) msg.obj).arg2); (IVoiceInteractor) ((SomeArgs) msg.obj).arg2);
break; break;
case ATTACH_AGENT: case ATTACH_AGENT: {
handleAttachAgent((String) msg.obj); Application app = getApplication();
handleAttachAgent((String) msg.obj, app != null ? app.mLoadedApk : null);
break; break;
}
case APPLICATION_INFO_CHANGED: case APPLICATION_INFO_CHANGED:
mUpdatingSystemConfig = true; mUpdatingSystemConfig = true;
try { try {
@@ -3119,11 +3121,23 @@ public final class ActivityThread {
} }
} }
static final void handleAttachAgent(String agent) { private static boolean attemptAttachAgent(String agent, ClassLoader classLoader) {
try { try {
VMDebug.attachAgent(agent); VMDebug.attachAgent(agent, classLoader);
return true;
} catch (IOException e) { } catch (IOException e) {
Slog.e(TAG, "Attaching agent failed: " + agent); Slog.e(TAG, "Attaching agent with " + classLoader + " failed: " + agent);
return false;
}
}
static void handleAttachAgent(String agent, LoadedApk loadedApk) {
ClassLoader classLoader = loadedApk != null ? loadedApk.getClassLoader() : null;
if (attemptAttachAgent(agent, classLoader)) {
return;
}
if (classLoader != null) {
attemptAttachAgent(agent, null);
} }
} }
@@ -5441,12 +5455,16 @@ public final class ActivityThread {
mCompatConfiguration = new Configuration(data.config); mCompatConfiguration = new Configuration(data.config);
mProfiler = new Profiler(); mProfiler = new Profiler();
String agent = null;
if (data.initProfilerInfo != null) { if (data.initProfilerInfo != null) {
mProfiler.profileFile = data.initProfilerInfo.profileFile; mProfiler.profileFile = data.initProfilerInfo.profileFile;
mProfiler.profileFd = data.initProfilerInfo.profileFd; mProfiler.profileFd = data.initProfilerInfo.profileFd;
mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval; mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler; mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
mProfiler.streamingOutput = data.initProfilerInfo.streamingOutput; mProfiler.streamingOutput = data.initProfilerInfo.streamingOutput;
if (data.initProfilerInfo.attachAgentDuringBind) {
agent = data.initProfilerInfo.agent;
}
} }
// send up app name; do this *before* waiting for debugger // send up app name; do this *before* waiting for debugger
@@ -5496,6 +5514,10 @@ public final class ActivityThread {
data.loadedApk = getLoadedApkNoCheck(data.appInfo, data.compatInfo); data.loadedApk = getLoadedApkNoCheck(data.appInfo, data.compatInfo);
if (agent != null) {
handleAttachAgent(agent, data.loadedApk);
}
/** /**
* Switch this process to density compatibility mode if needed. * Switch this process to density compatibility mode if needed.
*/ */

View File

@@ -54,14 +54,24 @@ public class ProfilerInfo implements Parcelable {
*/ */
public final String agent; public final String agent;
/**
* Whether the {@link agent} should be attached early (before bind-application) or during
* bind-application. Agents attached prior to binding cannot be loaded from the app's APK
* directly and must be given as an absolute path (or available in the default LD_LIBRARY_PATH).
* Agents attached during bind-application will miss early setup (e.g., resource initialization
* and classloader generation), but are searched in the app's library search path.
*/
public final boolean attachAgentDuringBind;
public ProfilerInfo(String filename, ParcelFileDescriptor fd, int interval, boolean autoStop, public ProfilerInfo(String filename, ParcelFileDescriptor fd, int interval, boolean autoStop,
boolean streaming, String agent) { boolean streaming, String agent, boolean attachAgentDuringBind) {
profileFile = filename; profileFile = filename;
profileFd = fd; profileFd = fd;
samplingInterval = interval; samplingInterval = interval;
autoStopProfiler = autoStop; autoStopProfiler = autoStop;
streamingOutput = streaming; streamingOutput = streaming;
this.agent = agent; this.agent = agent;
this.attachAgentDuringBind = attachAgentDuringBind;
} }
public ProfilerInfo(ProfilerInfo in) { public ProfilerInfo(ProfilerInfo in) {
@@ -71,6 +81,7 @@ public class ProfilerInfo implements Parcelable {
autoStopProfiler = in.autoStopProfiler; autoStopProfiler = in.autoStopProfiler;
streamingOutput = in.streamingOutput; streamingOutput = in.streamingOutput;
agent = in.agent; agent = in.agent;
attachAgentDuringBind = in.attachAgentDuringBind;
} }
/** /**
@@ -109,6 +120,7 @@ public class ProfilerInfo implements Parcelable {
out.writeInt(autoStopProfiler ? 1 : 0); out.writeInt(autoStopProfiler ? 1 : 0);
out.writeInt(streamingOutput ? 1 : 0); out.writeInt(streamingOutput ? 1 : 0);
out.writeString(agent); out.writeString(agent);
out.writeBoolean(attachAgentDuringBind);
} }
public static final Parcelable.Creator<ProfilerInfo> CREATOR = public static final Parcelable.Creator<ProfilerInfo> CREATOR =
@@ -131,5 +143,6 @@ public class ProfilerInfo implements Parcelable {
autoStopProfiler = in.readInt() != 0; autoStopProfiler = in.readInt() != 0;
streamingOutput = in.readInt() != 0; streamingOutput = in.readInt() != 0;
agent = in.readString(); agent = in.readString();
attachAgentDuringBind = in.readBoolean();
} }
} }

View File

@@ -7027,15 +7027,22 @@ public class ActivityManagerService extends IActivityManager.Stub
} }
ProfilerInfo profilerInfo = null; ProfilerInfo profilerInfo = null;
String agent = null; String preBindAgent = null;
if (mProfileApp != null && mProfileApp.equals(processName)) { if (mProfileApp != null && mProfileApp.equals(processName)) {
mProfileProc = app; mProfileProc = app;
profilerInfo = (mProfilerInfo != null && mProfilerInfo.profileFile != null) ? if (mProfilerInfo != null) {
new ProfilerInfo(mProfilerInfo) : null; // Send a profiler info object to the app if either a file is given, or
agent = mProfilerInfo != null ? mProfilerInfo.agent : null; // an agent should be loaded at bind-time.
boolean needsInfo = mProfilerInfo.profileFile != null
|| mProfilerInfo.attachAgentDuringBind;
profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
if (!mProfilerInfo.attachAgentDuringBind) {
preBindAgent = mProfilerInfo.agent;
}
}
} else if (app.instr != null && app.instr.mProfileFile != null) { } else if (app.instr != null && app.instr.mProfileFile != null) {
profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false, profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
null); null, false);
} }
boolean enableTrackAllocation = false; boolean enableTrackAllocation = false;
@@ -7102,8 +7109,8 @@ public class ActivityManagerService extends IActivityManager.Stub
// If we were asked to attach an agent on startup, do so now, before we're binding // If we were asked to attach an agent on startup, do so now, before we're binding
// application code. // application code.
if (agent != null) { if (preBindAgent != null) {
thread.attachAgent(agent); thread.attachAgent(preBindAgent);
} }
checkTime(startTime, "attachApplicationLocked: immediately before bindApplication"); checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");

View File

@@ -114,6 +114,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
private boolean mAutoStop; private boolean mAutoStop;
private boolean mStreaming; // Streaming the profiling output to a file. private boolean mStreaming; // Streaming the profiling output to a file.
private String mAgent; // Agent to attach on startup. private String mAgent; // Agent to attach on startup.
private boolean mAttachAgentDuringBind; // Whether agent should be attached late.
private int mDisplayId; private int mDisplayId;
private int mStackId; private int mStackId;
private int mTaskId; private int mTaskId;
@@ -295,7 +296,21 @@ final class ActivityManagerShellCommand extends ShellCommand {
} else if (opt.equals("--streaming")) { } else if (opt.equals("--streaming")) {
mStreaming = true; mStreaming = true;
} else if (opt.equals("--attach-agent")) { } else if (opt.equals("--attach-agent")) {
if (mAgent != null) {
cmd.getErrPrintWriter().println(
"Multiple --attach-agent(-bind) not supported");
return false;
}
mAgent = getNextArgRequired(); mAgent = getNextArgRequired();
mAttachAgentDuringBind = false;
} else if (opt.equals("--attach-agent-bind")) {
if (mAgent != null) {
cmd.getErrPrintWriter().println(
"Multiple --attach-agent(-bind) not supported");
return false;
}
mAgent = getNextArgRequired();
mAttachAgentDuringBind = true;
} else if (opt.equals("-R")) { } else if (opt.equals("-R")) {
mRepeat = Integer.parseInt(getNextArgRequired()); mRepeat = Integer.parseInt(getNextArgRequired());
} else if (opt.equals("-S")) { } else if (opt.equals("-S")) {
@@ -381,7 +396,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
} }
} }
profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop, profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop,
mStreaming, mAgent); mStreaming, mAgent, mAttachAgentDuringBind);
} }
pw.println("Starting: " + intent); pw.println("Starting: " + intent);
@@ -755,7 +770,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
return -1; return -1;
} }
profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming, profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming,
null); null, false);
} }
try { try {
@@ -2679,6 +2694,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
pw.println(" (use with --start-profiler)"); pw.println(" (use with --start-profiler)");
pw.println(" -P <FILE>: like above, but profiling stops when app goes idle"); pw.println(" -P <FILE>: like above, but profiling stops when app goes idle");
pw.println(" --attach-agent <agent>: attach the given agent before binding"); pw.println(" --attach-agent <agent>: attach the given agent before binding");
pw.println(" --attach-agent-bind <agent>: attach the given agent during binding");
pw.println(" -R: repeat the activity launch <COUNT> times. Prior to each repeat,"); pw.println(" -R: repeat the activity launch <COUNT> times. Prior to each repeat,");
pw.println(" the top activity will be finished."); pw.println(" the top activity will be finished.");
pw.println(" -S: force stop the target app before starting the activity"); pw.println(" -S: force stop the target app before starting the activity");