Merge "ActivityThread: Attempt to attach agent with app's classloader" am: f779d7e3be
am: 9f1f950c31
Change-Id: I0df113aff5a54c5a1dbc5f968679bb9d4f8ea158
This commit is contained in:
@@ -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.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
Reference in New Issue
Block a user