summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2009-06-23 19:22:52 -0700
committerDianne Hackborn <hackbod@google.com>2009-06-24 16:23:14 -0700
commit9c8dd55a9d829c29a3feee9469d8c2f27a9f5516 (patch)
treedeb1f95fbdc6972bf1d50fffb79ef2c74731314b /services
parent0bc7b8490b1575bb8266a3b0c6652d4f460fcda1 (diff)
downloadframeworks_base-9c8dd55a9d829c29a3feee9469d8c2f27a9f5516.zip
frameworks_base-9c8dd55a9d829c29a3feee9469d8c2f27a9f5516.tar.gz
frameworks_base-9c8dd55a9d829c29a3feee9469d8c2f27a9f5516.tar.bz2
Fix bug 1829561 ("am profile" with bad filename kills process).
The am command is now the one that takes care of opening the target file, handling the opened file descriptor to the process that will be profiled. This allows you to send profile data to anywhere the shell can access, and avoids any problems coming up from the target process trying to open the file.
Diffstat (limited to 'services')
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java90
1 files changed, 51 insertions, 39 deletions
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 62b4d5e..0d9d2b0 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -12601,51 +12601,63 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
public boolean profileControl(String process, boolean start,
- String path) throws RemoteException {
+ String path, ParcelFileDescriptor fd) throws RemoteException {
- synchronized (this) {
- // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
- // its own permission.
- if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires permission "
- + android.Manifest.permission.SET_ACTIVITY_WATCHER);
- }
-
- ProcessRecord proc = null;
- try {
- int pid = Integer.parseInt(process);
- synchronized (mPidsSelfLocked) {
- proc = mPidsSelfLocked.get(pid);
+ try {
+ synchronized (this) {
+ // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
+ // its own permission.
+ if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires permission "
+ + android.Manifest.permission.SET_ACTIVITY_WATCHER);
}
- } catch (NumberFormatException e) {
- }
-
- if (proc == null) {
- HashMap<String, SparseArray<ProcessRecord>> all
- = mProcessNames.getMap();
- SparseArray<ProcessRecord> procs = all.get(process);
- if (procs != null && procs.size() > 0) {
- proc = procs.valueAt(0);
+
+ if (start && fd == null) {
+ throw new IllegalArgumentException("null fd");
}
- }
-
- if (proc == null || proc.thread == null) {
- throw new IllegalArgumentException("Unknown process: " + process);
- }
-
- boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
- if (isSecure) {
- if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
- throw new SecurityException("Process not debuggable: " + proc);
+
+ ProcessRecord proc = null;
+ try {
+ int pid = Integer.parseInt(process);
+ synchronized (mPidsSelfLocked) {
+ proc = mPidsSelfLocked.get(pid);
+ }
+ } catch (NumberFormatException e) {
+ }
+
+ if (proc == null) {
+ HashMap<String, SparseArray<ProcessRecord>> all
+ = mProcessNames.getMap();
+ SparseArray<ProcessRecord> procs = all.get(process);
+ if (procs != null && procs.size() > 0) {
+ proc = procs.valueAt(0);
+ }
+ }
+
+ if (proc == null || proc.thread == null) {
+ throw new IllegalArgumentException("Unknown process: " + process);
+ }
+
+ boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
+ if (isSecure) {
+ if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
+ throw new SecurityException("Process not debuggable: " + proc);
+ }
}
- }
- try {
- proc.thread.profilerControl(start, path);
+ proc.thread.profilerControl(start, path, fd);
+ fd = null;
return true;
- } catch (RemoteException e) {
- throw new IllegalStateException("Process disappeared");
+ }
+ } catch (RemoteException e) {
+ throw new IllegalStateException("Process disappeared");
+ } finally {
+ if (fd != null) {
+ try {
+ fd.close();
+ } catch (IOException e) {
+ }
}
}
}