Last active
August 29, 2015 14:14
-
-
Save ganadist/46afd6b4b39c826ee530 to your computer and use it in GitHub Desktop.
show BinderProxy reference information when run "dumpsys meminfo -a"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python2 | |
| import sys, os | |
| import collections | |
| def parse_meminfo(filename): | |
| def parse(filename): | |
| lines = [] | |
| for line in open(filename): | |
| line = line[:-1] | |
| if line.startswith('** MEMINFO in pid '): | |
| if len(lines) > 3: | |
| yield get_binder_info(lines) | |
| lines = [] | |
| lines.append(line) | |
| yield get_binder_info(lines) | |
| d = {} | |
| for pid, name, binder_info in parse(filename): | |
| d[name] = binder_info | |
| return d | |
| def get_binder_info(item): | |
| l = item[0].split() | |
| pid = l[4] | |
| pname = l[5][1:-1] | |
| proxies = [] | |
| lines = [] | |
| for line in item[2:]: | |
| if not line.strip(): | |
| proxies.append('\n'.join(lines)) | |
| lines = [] | |
| continue | |
| if line.startswith(' Shared'): | |
| break | |
| lines.append(line) | |
| return pid, pname, collections.Counter(proxies) | |
| if __name__ == '__main__': | |
| def parse_args(argv): | |
| tags = [] | |
| filenames = [] | |
| for filename in argv: | |
| if os.access(filename, os.R_OK): | |
| filenames.append(filename) | |
| else: | |
| tags.append(filename) | |
| return tags, filenames | |
| tags, filenames = parse_args(sys.argv[1:]) | |
| if not filenames: | |
| print 'Usage: %s dumpsys_meminfo_a_output1 dumpsys_meminfo_a_output2 ...'%sys.argv[0] | |
| sys.exit(-1) | |
| parsed = map(parse_meminfo, filenames) | |
| now = parsed[-1] | |
| if not tags: | |
| tags = now.keys() # ['system', ] | |
| for tag in tags: | |
| printed = False | |
| for k, v in now[tag].most_common(10): | |
| if v < 4: continue | |
| if not printed: | |
| print 'process: ', tag | |
| printed = True | |
| print 'count history:', map(lambda x: x.get(tag, {}).get(k, 0), parsed) | |
| print 'item: ', k | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| From d42e2221b30fb9a386cf531d37dc58ee91ba602e Mon Sep 17 00:00:00 2001 | |
| From: Young-Ho Cha <[email protected]> | |
| Date: Wed, 07 May 2014 17:44:17 +0900 | |
| Subject: [PATCH] DO NOT MERGE: show BinderProxy reference information when run | |
| "dumpsys meminfo -a" | |
| Change-Id: I59b8816f9c5062d7bd233b3a635ff8e5c56d3927 | |
| Signed-off-by: Young-Ho Cha <[email protected]> | |
| --- | |
| core/java/android/app/ActivityThread.java | 2 ++ | |
| core/java/android/os/Binder.java | 55 +++++++++++++++++++++++++++++++ | |
| 2 files changed, 57 insertions(+) | |
| diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java | |
| index 9d821e1..3ecb69d 100644 | |
| --- a/core/java/android/app/ActivityThread.java | |
| +++ b/core/java/android/app/ActivityThread.java | |
| @@ -935,6 +935,8 @@ public final class ActivityThread { | |
| boolean dumpFullInfo, boolean dumpDalvik, String[] args) { | |
| FileOutputStream fout = new FileOutputStream(fd); | |
| PrintWriter pw = new FastPrintWriter(fout); | |
| + | |
| + Binder.dumpBinderProxyList(pw); | |
| try { | |
| dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik); | |
| } finally { | |
| diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java | |
| index b4a4624..7830637 100644 | |
| --- a/core/java/android/os/Binder.java | |
| +++ b/core/java/android/os/Binder.java | |
| @@ -481,9 +481,15 @@ public class Binder implements IBinder { | |
| return res; | |
| } | |
| + | |
| + /** @hide */ | |
| + public static void dumpBinderProxyList(PrintWriter pw) { | |
| + BinderProxy.dumpBinderProxyList(pw); | |
| + } | |
| } | |
| final class BinderProxy implements IBinder { | |
| + private static final boolean FIND_POTENTIAL_LEAKS = true; | |
| public native boolean pingBinder(); | |
| public native boolean isBinderAlive(); | |
| @@ -530,13 +536,62 @@ final class BinderProxy implements IBinder { | |
| } | |
| } | |
| + private static android.util.SparseArray<BinderProxyInfo> sBinderList = | |
| + new android.util.SparseArray(); | |
| + | |
| + static class BinderProxyInfo { | |
| + final int mPid; | |
| + final int mUid; | |
| + final StackTraceElement[] mSte; | |
| + BinderProxyInfo() { | |
| + mPid = Binder.getCallingPid(); | |
| + mUid = Binder.getCallingUid(); | |
| + StackTraceElement[] ste = Thread.currentThread().getStackTrace(); | |
| + if (ste.length > 5) { | |
| + mSte = new StackTraceElement[ste.length - 5]; | |
| + System.arraycopy(ste, 4, mSte, 0, ste.length - 5); | |
| + } else { | |
| + mSte = null; | |
| + } | |
| + } | |
| + } | |
| + | |
| + public static void dumpBinderProxyList(PrintWriter pw) { | |
| + if (FIND_POTENTIAL_LEAKS) { | |
| + synchronized(sBinderList) { | |
| + pw.println("BinderProxy count = " + sBinderList.size()); | |
| + for (int i = 0; i < sBinderList.size(); i++) { | |
| + BinderProxyInfo b = sBinderList.valueAt(i); | |
| + pw.println("BinderProxy instance is created by:"); | |
| + pw.println("pid: " + b.mPid + " uid: " + b.mUid); | |
| + if (b.mSte != null) { | |
| + for (StackTraceElement ste: b.mSte) { | |
| + pw.println(ste.toString()); | |
| + } | |
| + } | |
| + pw.println(); | |
| + } | |
| + } | |
| + } | |
| + } | |
| + | |
| BinderProxy() { | |
| + if (FIND_POTENTIAL_LEAKS) { | |
| + synchronized(sBinderList) { | |
| + sBinderList.put(hashCode(), new BinderProxyInfo()); | |
| + } | |
| + } | |
| mSelf = new WeakReference(this); | |
| } | |
| @Override | |
| protected void finalize() throws Throwable { | |
| try { | |
| + if (FIND_POTENTIAL_LEAKS) { | |
| + synchronized(sBinderList) { | |
| + sBinderList.delete(hashCode()); | |
| + } | |
| + } | |
| destroy(); | |
| } finally { | |
| super.finalize(); | |
| -- | |
| 2.2.2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment