blob: 2de12047dc48dd91503400bb08d79f29619af9cb [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.os;
18
Dianne Hackborn8c841092013-06-24 13:46:13 -070019import com.android.internal.util.FastPrintWriter;
Dave Bort1ce5bd32009-04-22 17:36:56 -070020import com.android.internal.util.TypedProperties;
21
Dave Bort1ce5bd32009-04-22 17:36:56 -070022import android.util.Log;
23
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070024import java.io.FileDescriptor;
Dave Bort1ce5bd32009-04-22 17:36:56 -070025import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import java.io.FileOutputStream;
Dave Bort1ce5bd32009-04-22 17:36:56 -070027import java.io.FileReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import java.io.IOException;
29import java.io.OutputStreamWriter;
30import java.io.PrintWriter;
Dave Bort1ce5bd32009-04-22 17:36:56 -070031import java.io.Reader;
32import java.lang.reflect.Field;
33import java.lang.reflect.Modifier;
Romain Guyc4b11a72009-05-13 15:46:37 -070034import java.lang.annotation.Target;
35import java.lang.annotation.ElementType;
36import java.lang.annotation.Retention;
37import java.lang.annotation.RetentionPolicy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038
39import org.apache.harmony.dalvik.ddmc.Chunk;
40import org.apache.harmony.dalvik.ddmc.ChunkHandler;
41import org.apache.harmony.dalvik.ddmc.DdmServer;
42
Dan Bornstein9f315542010-11-19 18:12:55 -080043import dalvik.bytecode.OpcodeInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import dalvik.bytecode.Opcodes;
45import dalvik.system.VMDebug;
46
47
48/**
Ian Rogersfe067a42013-02-22 19:59:23 -080049 * Provides various debugging methods for Android applications, including
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 * tracing and allocation counts.
51 * <p><strong>Logging Trace Files</strong></p>
52 * <p>Debug can create log files that give details about an application, such as
53 * a call stack and start/stop times for any running methods. See <a
54href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
55 * information about reading trace files. To start logging trace files, call one
56 * of the startMethodTracing() methods. To stop tracing, call
57 * {@link #stopMethodTracing()}.
58 */
59public final class Debug
60{
Dan Egnor3eda9792010-03-05 13:28:36 -080061 private static final String TAG = "Debug";
62
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 /**
64 * Flags for startMethodTracing(). These can be ORed together.
65 *
66 * TRACE_COUNT_ALLOCS adds the results from startAllocCounting to the
67 * trace key file.
68 */
69 public static final int TRACE_COUNT_ALLOCS = VMDebug.TRACE_COUNT_ALLOCS;
70
71 /**
72 * Flags for printLoadedClasses(). Default behavior is to only show
73 * the class name.
74 */
75 public static final int SHOW_FULL_DETAIL = 1;
76 public static final int SHOW_CLASSLOADER = (1 << 1);
77 public static final int SHOW_INITIALIZED = (1 << 2);
78
79 // set/cleared by waitForDebugger()
80 private static volatile boolean mWaiting = false;
81
82 private Debug() {}
83
84 /*
85 * How long to wait for the debugger to finish sending requests. I've
86 * seen this hit 800msec on the device while waiting for a response
87 * to travel over USB and get processed, so we take that and add
88 * half a second.
89 */
90 private static final int MIN_DEBUGGER_IDLE = 1300; // msec
91
92 /* how long to sleep when polling for activity */
93 private static final int SPIN_DELAY = 200; // msec
94
95 /**
96 * Default trace file path and file
97 */
Christian Mehlmauer798e2d32010-06-17 18:24:07 +020098 private static final String DEFAULT_TRACE_PATH_PREFIX =
Jeff Sharkeyb049e212012-09-07 23:16:01 -070099 Environment.getLegacyExternalStorageDirectory().getPath() + "/";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 private static final String DEFAULT_TRACE_BODY = "dmtrace";
101 private static final String DEFAULT_TRACE_EXTENSION = ".trace";
102 private static final String DEFAULT_TRACE_FILE_PATH =
103 DEFAULT_TRACE_PATH_PREFIX + DEFAULT_TRACE_BODY
104 + DEFAULT_TRACE_EXTENSION;
105
106
107 /**
108 * This class is used to retrieved various statistics about the memory mappings for this
109 * process. The returns info broken down by dalvik, native, and other. All results are in kB.
110 */
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700111 public static class MemoryInfo implements Parcelable {
Dianne Hackborn64770d12013-05-23 17:51:19 -0700112 /** The proportional set size for dalvik heap. (Doesn't include other Dalvik overhead.) */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 public int dalvikPss;
Dianne Hackborn64770d12013-05-23 17:51:19 -0700114 /** The proportional set size that is swappable for dalvik heap. */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700115 /** @hide We may want to expose this, eventually. */
116 public int dalvikSwappablePss;
Dianne Hackborn64770d12013-05-23 17:51:19 -0700117 /** The private dirty pages used by dalvik heap. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118 public int dalvikPrivateDirty;
Dianne Hackborn64770d12013-05-23 17:51:19 -0700119 /** The shared dirty pages used by dalvik heap. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 public int dalvikSharedDirty;
Dianne Hackborn64770d12013-05-23 17:51:19 -0700121 /** The private clean pages used by dalvik heap. */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700122 /** @hide We may want to expose this, eventually. */
123 public int dalvikPrivateClean;
Dianne Hackborn64770d12013-05-23 17:51:19 -0700124 /** The shared clean pages used by dalvik heap. */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700125 /** @hide We may want to expose this, eventually. */
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700126 public int dalvikSharedClean;
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700127 /** The dirty dalvik pages that have been swapped out. */
128 /** @hide We may want to expose this, eventually. */
129 public int dalvikSwappedOut;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130
131 /** The proportional set size for the native heap. */
132 public int nativePss;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700133 /** The proportional set size that is swappable for the native heap. */
134 /** @hide We may want to expose this, eventually. */
135 public int nativeSwappablePss;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 /** The private dirty pages used by the native heap. */
137 public int nativePrivateDirty;
138 /** The shared dirty pages used by the native heap. */
139 public int nativeSharedDirty;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700140 /** The private clean pages used by the native heap. */
141 /** @hide We may want to expose this, eventually. */
142 public int nativePrivateClean;
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700143 /** The shared clean pages used by the native heap. */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700144 /** @hide We may want to expose this, eventually. */
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700145 public int nativeSharedClean;
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700146 /** The dirty native pages that have been swapped out. */
147 /** @hide We may want to expose this, eventually. */
148 public int nativeSwappedOut;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149
150 /** The proportional set size for everything else. */
151 public int otherPss;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700152 /** The proportional set size that is swappable for everything else. */
153 /** @hide We may want to expose this, eventually. */
154 public int otherSwappablePss;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 /** The private dirty pages used by everything else. */
156 public int otherPrivateDirty;
157 /** The shared dirty pages used by everything else. */
158 public int otherSharedDirty;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700159 /** The private clean pages used by everything else. */
160 /** @hide We may want to expose this, eventually. */
161 public int otherPrivateClean;
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700162 /** The shared clean pages used by everything else. */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700163 /** @hide We may want to expose this, eventually. */
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700164 public int otherSharedClean;
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700165 /** The dirty pages used by anyting else that have been swapped out. */
166 /** @hide We may want to expose this, eventually. */
167 public int otherSwappedOut;
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200168
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700169 /** @hide */
Adam Lesinski5b4ef812013-09-23 10:06:09 -0700170 public static final int NUM_OTHER_STATS = 16;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700171
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700172 /** @hide */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700173 public static final int NUM_DVK_STATS = 5;
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700174
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700175 /** @hide */
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700176 public static final int NUM_CATEGORIES = 7;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700177
178 /** @hide */
179 public static final int offsetPss = 0;
180 /** @hide */
181 public static final int offsetSwappablePss = 1;
182 /** @hide */
183 public static final int offsetPrivateDirty = 2;
184 /** @hide */
185 public static final int offsetSharedDirty = 3;
186 /** @hide */
187 public static final int offsetPrivateClean = 4;
188 /** @hide */
189 public static final int offsetSharedClean = 5;
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700190 /** @hide */
191 public static final int offsetSwappedOut = 6;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700192
193 private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES];
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700194
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700195 public MemoryInfo() {
196 }
197
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -0700198 /**
199 * Return total PSS memory usage in kB.
200 */
201 public int getTotalPss() {
202 return dalvikPss + nativePss + otherPss;
203 }
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200204
Dianne Hackbornc8230512013-07-13 21:32:12 -0700205 /**
206 * @hide Return total PSS memory usage in kB.
207 */
208 public int getTotalUss() {
209 return dalvikPrivateClean + dalvikPrivateDirty
210 + nativePrivateClean + nativePrivateDirty
211 + otherPrivateClean + otherPrivateDirty;
212 }
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700213
214 /**
215 * Return total PSS memory usage in kB.
216 */
217 public int getTotalSwappablePss() {
218 return dalvikSwappablePss + nativeSwappablePss + otherSwappablePss;
219 }
220
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -0700221 /**
222 * Return total private dirty memory usage in kB.
223 */
224 public int getTotalPrivateDirty() {
225 return dalvikPrivateDirty + nativePrivateDirty + otherPrivateDirty;
226 }
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200227
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -0700228 /**
229 * Return total shared dirty memory usage in kB.
230 */
231 public int getTotalSharedDirty() {
232 return dalvikSharedDirty + nativeSharedDirty + otherSharedDirty;
233 }
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200234
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700235 /**
236 * Return total shared clean memory usage in kB.
237 */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700238 public int getTotalPrivateClean() {
239 return dalvikPrivateClean + nativePrivateClean + otherPrivateClean;
240 }
241
242 /**
243 * Return total shared clean memory usage in kB.
244 */
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700245 public int getTotalSharedClean() {
246 return dalvikSharedClean + nativeSharedClean + otherSharedClean;
247 }
248
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700249 /**
250 * Return total swapped out memory in kB.
251 * @hide
252 */
253 public int getTotalSwappedOut() {
254 return dalvikSwappedOut + nativeSwappedOut + otherSwappedOut;
255 }
256
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700257 /** @hide */
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700258 public int getOtherPss(int which) {
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700259 return otherStats[which*NUM_CATEGORIES + offsetPss];
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700260 }
261
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700262
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700263 /** @hide */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700264 public int getOtherSwappablePss(int which) {
265 return otherStats[which*NUM_CATEGORIES + offsetSwappablePss];
266 }
267
268
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700269 /** @hide */
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700270 public int getOtherPrivateDirty(int which) {
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700271 return otherStats[which*NUM_CATEGORIES + offsetPrivateDirty];
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700272 }
273
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700274 /** @hide */
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700275 public int getOtherSharedDirty(int which) {
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700276 return otherStats[which*NUM_CATEGORIES + offsetSharedDirty];
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700277 }
278
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700279 /** @hide */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700280 public int getOtherPrivateClean(int which) {
281 return otherStats[which*NUM_CATEGORIES + offsetPrivateClean];
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700282 }
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700283
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700284 /** @hide */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700285 public int getOtherSharedClean(int which) {
286 return otherStats[which*NUM_CATEGORIES + offsetSharedClean];
287 }
288
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700289 /** @hide */
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700290 public int getOtherSwappedOut(int which) {
291 return otherStats[which*NUM_CATEGORIES + offsetSwappedOut];
292 }
293
294 /** @hide */
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700295 public static String getOtherLabel(int which) {
296 switch (which) {
Dianne Hackborn64770d12013-05-23 17:51:19 -0700297 case 0: return "Dalvik Other";
298 case 1: return "Stack";
299 case 2: return "Cursor";
300 case 3: return "Ashmem";
301 case 4: return "Other dev";
302 case 5: return ".so mmap";
303 case 6: return ".jar mmap";
304 case 7: return ".apk mmap";
305 case 8: return ".ttf mmap";
306 case 9: return ".dex mmap";
307 case 10: return "code mmap";
308 case 11: return "image mmap";
309 case 12: return "Other mmap";
Adam Lesinski5b4ef812013-09-23 10:06:09 -0700310 case 13: return "Graphics";
311 case 14: return "GL";
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700312 case 15: return "Memtrack";
Adam Lesinski5b4ef812013-09-23 10:06:09 -0700313 case 16: return ".Heap";
314 case 17: return ".LOS";
315 case 18: return ".LinearAlloc";
316 case 19: return ".GC";
317 case 20: return ".JITCache";
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700318 default: return "????";
319 }
320 }
321
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700322 public int describeContents() {
323 return 0;
324 }
325
326 public void writeToParcel(Parcel dest, int flags) {
327 dest.writeInt(dalvikPss);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700328 dest.writeInt(dalvikSwappablePss);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700329 dest.writeInt(dalvikPrivateDirty);
330 dest.writeInt(dalvikSharedDirty);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700331 dest.writeInt(dalvikPrivateClean);
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700332 dest.writeInt(dalvikSharedClean);
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700333 dest.writeInt(dalvikSwappedOut);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700334 dest.writeInt(nativePss);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700335 dest.writeInt(nativeSwappablePss);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700336 dest.writeInt(nativePrivateDirty);
337 dest.writeInt(nativeSharedDirty);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700338 dest.writeInt(nativePrivateClean);
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700339 dest.writeInt(nativeSharedClean);
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700340 dest.writeInt(nativeSwappedOut);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700341 dest.writeInt(otherPss);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700342 dest.writeInt(otherSwappablePss);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700343 dest.writeInt(otherPrivateDirty);
344 dest.writeInt(otherSharedDirty);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700345 dest.writeInt(otherPrivateClean);
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700346 dest.writeInt(otherSharedClean);
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700347 dest.writeInt(otherSwappedOut);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700348 dest.writeIntArray(otherStats);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700349 }
350
351 public void readFromParcel(Parcel source) {
352 dalvikPss = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700353 dalvikSwappablePss = source.readInt();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700354 dalvikPrivateDirty = source.readInt();
355 dalvikSharedDirty = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700356 dalvikPrivateClean = source.readInt();
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700357 dalvikSharedClean = source.readInt();
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700358 dalvikSwappedOut = source.readInt();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700359 nativePss = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700360 nativeSwappablePss = source.readInt();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700361 nativePrivateDirty = source.readInt();
362 nativeSharedDirty = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700363 nativePrivateClean = source.readInt();
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700364 nativeSharedClean = source.readInt();
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700365 nativeSwappedOut = source.readInt();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700366 otherPss = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700367 otherSwappablePss = source.readInt();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700368 otherPrivateDirty = source.readInt();
369 otherSharedDirty = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700370 otherPrivateClean = source.readInt();
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700371 otherSharedClean = source.readInt();
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700372 otherSwappedOut = source.readInt();
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700373 otherStats = source.createIntArray();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700374 }
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200375
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700376 public static final Creator<MemoryInfo> CREATOR = new Creator<MemoryInfo>() {
377 public MemoryInfo createFromParcel(Parcel source) {
378 return new MemoryInfo(source);
379 }
380 public MemoryInfo[] newArray(int size) {
381 return new MemoryInfo[size];
382 }
383 };
384
385 private MemoryInfo(Parcel source) {
386 readFromParcel(source);
387 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388 }
389
390
391 /**
392 * Wait until a debugger attaches. As soon as the debugger attaches,
393 * this returns, so you will need to place a breakpoint after the
394 * waitForDebugger() call if you want to start tracing immediately.
395 */
396 public static void waitForDebugger() {
397 if (!VMDebug.isDebuggingEnabled()) {
398 //System.out.println("debugging not enabled, not waiting");
399 return;
400 }
401 if (isDebuggerConnected())
402 return;
403
404 // if DDMS is listening, inform them of our plight
405 System.out.println("Sending WAIT chunk");
406 byte[] data = new byte[] { 0 }; // 0 == "waiting for debugger"
407 Chunk waitChunk = new Chunk(ChunkHandler.type("WAIT"), data, 0, 1);
408 DdmServer.sendChunk(waitChunk);
409
410 mWaiting = true;
411 while (!isDebuggerConnected()) {
412 try { Thread.sleep(SPIN_DELAY); }
413 catch (InterruptedException ie) {}
414 }
415 mWaiting = false;
416
417 System.out.println("Debugger has connected");
418
419 /*
420 * There is no "ready to go" signal from the debugger, and we're
421 * not allowed to suspend ourselves -- the debugger expects us to
422 * be running happily, and gets confused if we aren't. We need to
423 * allow the debugger a chance to set breakpoints before we start
424 * running again.
425 *
426 * Sit and spin until the debugger has been idle for a short while.
427 */
428 while (true) {
429 long delta = VMDebug.lastDebuggerActivity();
430 if (delta < 0) {
431 System.out.println("debugger detached?");
432 break;
433 }
434
435 if (delta < MIN_DEBUGGER_IDLE) {
436 System.out.println("waiting for debugger to settle...");
437 try { Thread.sleep(SPIN_DELAY); }
438 catch (InterruptedException ie) {}
439 } else {
440 System.out.println("debugger has settled (" + delta + ")");
441 break;
442 }
443 }
444 }
445
446 /**
447 * Returns "true" if one or more threads is waiting for a debugger
448 * to attach.
449 */
450 public static boolean waitingForDebugger() {
451 return mWaiting;
452 }
453
454 /**
455 * Determine if a debugger is currently attached.
456 */
457 public static boolean isDebuggerConnected() {
458 return VMDebug.isDebuggerConnected();
459 }
460
461 /**
Andy McFaddene5772322010-01-22 07:23:31 -0800462 * Returns an array of strings that identify VM features. This is
463 * used by DDMS to determine what sorts of operations the VM can
464 * perform.
465 *
466 * @hide
467 */
468 public static String[] getVmFeatureList() {
469 return VMDebug.getVmFeatureList();
470 }
471
472 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 * Change the JDWP port.
474 *
475 * @deprecated no longer needed or useful
476 */
477 @Deprecated
478 public static void changeDebugPort(int port) {}
479
480 /**
481 * This is the pathname to the sysfs file that enables and disables
482 * tracing on the qemu emulator.
483 */
484 private static final String SYSFS_QEMU_TRACE_STATE = "/sys/qemu_trace/state";
485
486 /**
487 * Enable qemu tracing. For this to work requires running everything inside
488 * the qemu emulator; otherwise, this method will have no effect. The trace
489 * file is specified on the command line when the emulator is started. For
490 * example, the following command line <br />
491 * <code>emulator -trace foo</code><br />
492 * will start running the emulator and create a trace file named "foo". This
493 * method simply enables writing the trace records to the trace file.
494 *
495 * <p>
496 * The main differences between this and {@link #startMethodTracing()} are
497 * that tracing in the qemu emulator traces every cpu instruction of every
498 * process, including kernel code, so we have more complete information,
499 * including all context switches. We can also get more detailed information
500 * such as cache misses. The sequence of calls is determined by
501 * post-processing the instruction trace. The qemu tracing is also done
502 * without modifying the application or perturbing the timing of calls
503 * because no instrumentation is added to the application being traced.
504 * </p>
505 *
506 * <p>
507 * One limitation of using this method compared to using
508 * {@link #startMethodTracing()} on the real device is that the emulator
509 * does not model all of the real hardware effects such as memory and
510 * bus contention. The emulator also has a simple cache model and cannot
511 * capture all the complexities of a real cache.
512 * </p>
513 */
514 public static void startNativeTracing() {
515 // Open the sysfs file for writing and write "1" to it.
516 PrintWriter outStream = null;
517 try {
518 FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700519 outStream = new FastPrintWriter(fos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 outStream.println("1");
521 } catch (Exception e) {
522 } finally {
523 if (outStream != null)
524 outStream.close();
525 }
526
527 VMDebug.startEmulatorTracing();
528 }
529
530 /**
531 * Stop qemu tracing. See {@link #startNativeTracing()} to start tracing.
532 *
533 * <p>Tracing can be started and stopped as many times as desired. When
534 * the qemu emulator itself is stopped then the buffered trace records
535 * are flushed and written to the trace file. In fact, it is not necessary
536 * to call this method at all; simply killing qemu is sufficient. But
537 * starting and stopping a trace is useful for examining a specific
538 * region of code.</p>
539 */
540 public static void stopNativeTracing() {
541 VMDebug.stopEmulatorTracing();
542
543 // Open the sysfs file for writing and write "0" to it.
544 PrintWriter outStream = null;
545 try {
546 FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700547 outStream = new FastPrintWriter(fos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 outStream.println("0");
549 } catch (Exception e) {
550 // We could print an error message here but we probably want
551 // to quietly ignore errors if we are not running in the emulator.
552 } finally {
553 if (outStream != null)
554 outStream.close();
555 }
556 }
557
558 /**
559 * Enable "emulator traces", in which information about the current
560 * method is made available to the "emulator -trace" feature. There
561 * is no corresponding "disable" call -- this is intended for use by
562 * the framework when tracing should be turned on and left that way, so
563 * that traces captured with F9/F10 will include the necessary data.
564 *
565 * This puts the VM into "profile" mode, which has performance
566 * consequences.
567 *
568 * To temporarily enable tracing, use {@link #startNativeTracing()}.
569 */
570 public static void enableEmulatorTraceOutput() {
571 VMDebug.startEmulatorTracing();
572 }
573
574 /**
575 * Start method tracing with default log name and buffer size. See <a
576href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
577 * information about reading these files. Call stopMethodTracing() to stop
578 * tracing.
579 */
580 public static void startMethodTracing() {
Jeff Haod02e60f2014-01-06 15:52:52 -0800581 VMDebug.startMethodTracing(DEFAULT_TRACE_FILE_PATH, 0, 0, false, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 }
583
584 /**
585 * Start method tracing, specifying the trace log file name. The trace
586 * file will be put under "/sdcard" unless an absolute path is given.
587 * See <a
588 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
589 * information about reading trace files.
590 *
591 * @param traceName Name for the trace log file to create.
Jeff Haod02e60f2014-01-06 15:52:52 -0800592 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace".
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 * If the files already exist, they will be truncated.
594 * If the trace file given does not end in ".trace", it will be appended for you.
595 */
596 public static void startMethodTracing(String traceName) {
597 startMethodTracing(traceName, 0, 0);
598 }
599
600 /**
601 * Start method tracing, specifying the trace log file name and the
602 * buffer size. The trace files will be put under "/sdcard" unless an
603 * absolute path is given. See <a
604 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
605 * information about reading trace files.
606 * @param traceName Name for the trace log file to create.
Jeff Haod02e60f2014-01-06 15:52:52 -0800607 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace".
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 * If the files already exist, they will be truncated.
609 * If the trace file given does not end in ".trace", it will be appended for you.
610 *
611 * @param bufferSize The maximum amount of trace data we gather. If not given, it defaults to 8MB.
612 */
613 public static void startMethodTracing(String traceName, int bufferSize) {
614 startMethodTracing(traceName, bufferSize, 0);
615 }
616
617 /**
618 * Start method tracing, specifying the trace log file name and the
619 * buffer size. The trace files will be put under "/sdcard" unless an
620 * absolute path is given. See <a
621 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
622 * information about reading trace files.
623 *
624 * <p>
625 * When method tracing is enabled, the VM will run more slowly than
626 * usual, so the timings from the trace files should only be considered
627 * in relative terms (e.g. was run #1 faster than run #2). The times
628 * for native methods will not change, so don't try to use this to
629 * compare the performance of interpreted and native implementations of the
Jeff Haod02e60f2014-01-06 15:52:52 -0800630 * same method. As an alternative, consider using sampling-based method
631 * tracing via {@link #startMethodTracingSampling(String, int, int)} or
632 * "native" tracing in the emulator via {@link #startNativeTracing()}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800633 * </p>
634 *
635 * @param traceName Name for the trace log file to create.
Jeff Haod02e60f2014-01-06 15:52:52 -0800636 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace".
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800637 * If the files already exist, they will be truncated.
638 * If the trace file given does not end in ".trace", it will be appended for you.
639 * @param bufferSize The maximum amount of trace data we gather. If not given, it defaults to 8MB.
Jeff Haod02e60f2014-01-06 15:52:52 -0800640 * @param flags Flags to control method tracing. The only one that is currently defined is {@link #TRACE_COUNT_ALLOCS}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 */
642 public static void startMethodTracing(String traceName, int bufferSize,
643 int flags) {
Jeff Haod02e60f2014-01-06 15:52:52 -0800644 VMDebug.startMethodTracing(fixTraceName(traceName), bufferSize, flags, false, 0);
645 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800646
Jeff Haod02e60f2014-01-06 15:52:52 -0800647 /**
648 * Start sampling-based method tracing, specifying the trace log file name,
649 * the buffer size, and the sampling interval. The trace files will be put
650 * under "/sdcard" unless an absolute path is given. See <a
651 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a>
652 * for information about reading trace files.
653 *
654 * @param traceName Name for the trace log file to create.
655 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace".
656 * If the files already exist, they will be truncated.
657 * If the trace file given does not end in ".trace", it will be appended for you.
658 * @param bufferSize The maximum amount of trace data we gather. If not given, it defaults to 8MB.
659 * @param intervalUs The amount of time between each sample in microseconds.
660 */
661 public static void startMethodTracingSampling(String traceName,
662 int bufferSize, int intervalUs) {
663 VMDebug.startMethodTracing(fixTraceName(traceName), bufferSize, 0, true, intervalUs);
664 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665
Jeff Haod02e60f2014-01-06 15:52:52 -0800666 /**
667 * Formats name of trace log file for method tracing.
668 */
669 private static String fixTraceName(String traceName) {
670 if (traceName == null)
671 traceName = DEFAULT_TRACE_FILE_PATH;
672 if (traceName.charAt(0) != '/')
673 traceName = DEFAULT_TRACE_PATH_PREFIX + traceName;
674 if (!traceName.endsWith(DEFAULT_TRACE_EXTENSION))
675 traceName = traceName + DEFAULT_TRACE_EXTENSION;
676
677 return traceName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678 }
679
680 /**
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700681 * Like startMethodTracing(String, int, int), but taking an already-opened
682 * FileDescriptor in which the trace is written. The file name is also
683 * supplied simply for logging. Makes a dup of the file descriptor.
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200684 *
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700685 * Not exposed in the SDK unless we are really comfortable with supporting
686 * this and find it would be useful.
687 * @hide
688 */
689 public static void startMethodTracing(String traceName, FileDescriptor fd,
690 int bufferSize, int flags) {
Jeff Haod02e60f2014-01-06 15:52:52 -0800691 VMDebug.startMethodTracing(traceName, fd, bufferSize, flags, false, 0);
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700692 }
693
694 /**
Andy McFadden72a20db0c2010-01-22 12:20:41 -0800695 * Starts method tracing without a backing file. When stopMethodTracing
696 * is called, the result is sent directly to DDMS. (If DDMS is not
697 * attached when tracing ends, the profiling data will be discarded.)
698 *
699 * @hide
700 */
Jeff Hao7be3a132013-08-22 15:53:12 -0700701 public static void startMethodTracingDdms(int bufferSize, int flags,
702 boolean samplingEnabled, int intervalUs) {
703 VMDebug.startMethodTracingDdms(bufferSize, flags, samplingEnabled, intervalUs);
Andy McFadden72a20db0c2010-01-22 12:20:41 -0800704 }
705
706 /**
Jeff Haoac277052013-08-29 11:19:39 -0700707 * Determine whether method tracing is currently active and what type is
708 * active.
709 *
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -0700710 * @hide
711 */
Jeff Haoac277052013-08-29 11:19:39 -0700712 public static int getMethodTracingMode() {
713 return VMDebug.getMethodTracingMode();
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -0700714 }
715
716 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800717 * Stop method tracing.
718 */
719 public static void stopMethodTracing() {
720 VMDebug.stopMethodTracing();
721 }
722
723 /**
724 * Get an indication of thread CPU usage. The value returned
725 * indicates the amount of time that the current thread has spent
726 * executing code or waiting for certain types of I/O.
727 *
728 * The time is expressed in nanoseconds, and is only meaningful
729 * when compared to the result from an earlier call. Note that
730 * nanosecond resolution does not imply nanosecond accuracy.
731 *
732 * On system which don't support this operation, the call returns -1.
733 */
734 public static long threadCpuTimeNanos() {
735 return VMDebug.threadCpuTimeNanos();
736 }
737
738 /**
Chet Haase2970c492010-11-09 13:58:04 -0800739 * Start counting the number and aggregate size of memory allocations.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800740 *
Ian Rogersfe067a42013-02-22 19:59:23 -0800741 * <p>The {@link #startAllocCounting() start} method resets the counts and enables counting.
742 * The {@link #stopAllocCounting() stop} method disables the counting so that the analysis
743 * code doesn't cause additional allocations. The various <code>get</code> methods return
744 * the specified value. And the various <code>reset</code> methods reset the specified
Chet Haase2970c492010-11-09 13:58:04 -0800745 * count.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800746 *
Ian Rogersfe067a42013-02-22 19:59:23 -0800747 * <p>Counts are kept for the system as a whole (global) and for each thread.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 * The per-thread counts for threads other than the current thread
Chet Haase2970c492010-11-09 13:58:04 -0800749 * are not cleared by the "reset" or "start" calls.</p>
Ian Rogersfe067a42013-02-22 19:59:23 -0800750 *
751 * @deprecated Accurate counting is a burden on the runtime and may be removed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800752 */
Ian Rogersfe067a42013-02-22 19:59:23 -0800753 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 public static void startAllocCounting() {
755 VMDebug.startAllocCounting();
756 }
Chet Haase2970c492010-11-09 13:58:04 -0800757
758 /**
759 * Stop counting the number and aggregate size of memory allocations.
760 *
761 * @see #startAllocCounting()
762 */
Ian Rogersc2a3adb2013-04-19 11:31:48 -0700763 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800764 public static void stopAllocCounting() {
765 VMDebug.stopAllocCounting();
766 }
767
Ian Rogersfe067a42013-02-22 19:59:23 -0800768 /**
769 * Returns the global count of objects allocated by the runtime between a
770 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
771 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800772 public static int getGlobalAllocCount() {
773 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS);
774 }
Ian Rogersfe067a42013-02-22 19:59:23 -0800775
776 /**
777 * Clears the global count of objects allocated.
778 * @see #getGlobalAllocCount()
779 */
780 public static void resetGlobalAllocCount() {
781 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS);
782 }
783
784 /**
785 * Returns the global size, in bytes, of objects allocated by the runtime between a
786 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
787 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800788 public static int getGlobalAllocSize() {
789 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES);
790 }
Ian Rogersfe067a42013-02-22 19:59:23 -0800791
792 /**
793 * Clears the global size of objects allocated.
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700794 * @see #getGlobalAllocSize()
Ian Rogersfe067a42013-02-22 19:59:23 -0800795 */
796 public static void resetGlobalAllocSize() {
797 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES);
798 }
799
800 /**
801 * Returns the global count of objects freed by the runtime between a
802 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
803 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 public static int getGlobalFreedCount() {
805 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS);
806 }
Ian Rogersfe067a42013-02-22 19:59:23 -0800807
808 /**
809 * Clears the global count of objects freed.
810 * @see #getGlobalFreedCount()
811 */
812 public static void resetGlobalFreedCount() {
813 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS);
814 }
815
816 /**
817 * Returns the global size, in bytes, of objects freed by the runtime between a
818 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
819 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800820 public static int getGlobalFreedSize() {
821 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES);
822 }
Ian Rogersfe067a42013-02-22 19:59:23 -0800823
824 /**
825 * Clears the global size of objects freed.
826 * @see #getGlobalFreedSize()
827 */
828 public static void resetGlobalFreedSize() {
829 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES);
830 }
831
832 /**
833 * Returns the number of non-concurrent GC invocations between a
834 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
835 */
836 public static int getGlobalGcInvocationCount() {
837 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS);
838 }
839
840 /**
841 * Clears the count of non-concurrent GC invocations.
842 * @see #getGlobalGcInvocationCount()
843 */
844 public static void resetGlobalGcInvocationCount() {
845 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS);
846 }
847
848 /**
849 * Returns the number of classes successfully initialized (ie those that executed without
850 * throwing an exception) between a {@link #startAllocCounting() start} and
851 * {@link #stopAllocCounting() stop}.
852 */
Andy McFaddenc4e1bf72010-02-22 17:07:36 -0800853 public static int getGlobalClassInitCount() {
Andy McFaddenc4e1bf72010-02-22 17:07:36 -0800854 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT);
855 }
Ian Rogersfe067a42013-02-22 19:59:23 -0800856
857 /**
858 * Clears the count of classes initialized.
859 * @see #getGlobalClassInitCount()
860 */
861 public static void resetGlobalClassInitCount() {
862 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT);
863 }
864
865 /**
866 * Returns the time spent successfully initializing classes between a
867 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
868 */
Andy McFaddenc4e1bf72010-02-22 17:07:36 -0800869 public static int getGlobalClassInitTime() {
870 /* cumulative elapsed time for class initialization, in usec */
871 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME);
872 }
Carl Shapirob5961982010-12-22 15:54:53 -0800873
874 /**
Ian Rogersfe067a42013-02-22 19:59:23 -0800875 * Clears the count of time spent initializing classes.
876 * @see #getGlobalClassInitTime()
877 */
878 public static void resetGlobalClassInitTime() {
879 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME);
880 }
881
882 /**
Carl Shapiro7e942842011-01-12 17:17:45 -0800883 * This method exists for compatibility and always returns 0.
Carl Shapirob5961982010-12-22 15:54:53 -0800884 * @deprecated This method is now obsolete.
885 */
886 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 public static int getGlobalExternalAllocCount() {
Carl Shapirob5961982010-12-22 15:54:53 -0800888 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800889 }
Carl Shapirob5961982010-12-22 15:54:53 -0800890
891 /**
Ian Rogersfe067a42013-02-22 19:59:23 -0800892 * This method exists for compatibility and has no effect.
893 * @deprecated This method is now obsolete.
894 */
895 @Deprecated
896 public static void resetGlobalExternalAllocSize() {}
897
898 /**
899 * This method exists for compatibility and has no effect.
900 * @deprecated This method is now obsolete.
901 */
902 @Deprecated
903 public static void resetGlobalExternalAllocCount() {}
904
905 /**
Carl Shapiro7e942842011-01-12 17:17:45 -0800906 * This method exists for compatibility and always returns 0.
Carl Shapirob5961982010-12-22 15:54:53 -0800907 * @deprecated This method is now obsolete.
908 */
909 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910 public static int getGlobalExternalAllocSize() {
Carl Shapirob5961982010-12-22 15:54:53 -0800911 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800912 }
Carl Shapirob5961982010-12-22 15:54:53 -0800913
914 /**
Ian Rogersfe067a42013-02-22 19:59:23 -0800915 * This method exists for compatibility and always returns 0.
Carl Shapirob5961982010-12-22 15:54:53 -0800916 * @deprecated This method is now obsolete.
917 */
918 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 public static int getGlobalExternalFreedCount() {
Carl Shapirob5961982010-12-22 15:54:53 -0800920 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921 }
Carl Shapirob5961982010-12-22 15:54:53 -0800922
923 /**
Ian Rogersfe067a42013-02-22 19:59:23 -0800924 * This method exists for compatibility and has no effect.
925 * @deprecated This method is now obsolete.
926 */
927 @Deprecated
928 public static void resetGlobalExternalFreedCount() {}
929
930 /**
931 * This method exists for compatibility and has no effect.
Carl Shapirob5961982010-12-22 15:54:53 -0800932 * @deprecated This method is now obsolete.
933 */
934 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 public static int getGlobalExternalFreedSize() {
Carl Shapirob5961982010-12-22 15:54:53 -0800936 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937 }
Carl Shapirob5961982010-12-22 15:54:53 -0800938
Ian Rogersfe067a42013-02-22 19:59:23 -0800939 /**
940 * This method exists for compatibility and has no effect.
941 * @deprecated This method is now obsolete.
942 */
943 @Deprecated
944 public static void resetGlobalExternalFreedSize() {}
945
946 /**
947 * Returns the thread-local count of objects allocated by the runtime between a
948 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
949 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800950 public static int getThreadAllocCount() {
951 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS);
952 }
Ian Rogersfe067a42013-02-22 19:59:23 -0800953
954 /**
955 * Clears the thread-local count of objects allocated.
956 * @see #getThreadAllocCount()
957 */
958 public static void resetThreadAllocCount() {
959 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS);
960 }
961
962 /**
963 * Returns the thread-local size of objects allocated by the runtime between a
964 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
965 * @return The allocated size in bytes.
966 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 public static int getThreadAllocSize() {
968 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES);
969 }
Carl Shapirob5961982010-12-22 15:54:53 -0800970
971 /**
Ian Rogersfe067a42013-02-22 19:59:23 -0800972 * Clears the thread-local count of objects allocated.
973 * @see #getThreadAllocSize()
974 */
975 public static void resetThreadAllocSize() {
976 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES);
977 }
978
979 /**
980 * This method exists for compatibility and has no effect.
Carl Shapirob5961982010-12-22 15:54:53 -0800981 * @deprecated This method is now obsolete.
982 */
983 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 public static int getThreadExternalAllocCount() {
Carl Shapirob5961982010-12-22 15:54:53 -0800985 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800986 }
Carl Shapirob5961982010-12-22 15:54:53 -0800987
988 /**
Ian Rogersfe067a42013-02-22 19:59:23 -0800989 * This method exists for compatibility and has no effect.
990 * @deprecated This method is now obsolete.
991 */
992 @Deprecated
993 public static void resetThreadExternalAllocCount() {}
994
995 /**
996 * This method exists for compatibility and has no effect.
Carl Shapirob5961982010-12-22 15:54:53 -0800997 * @deprecated This method is now obsolete.
998 */
999 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 public static int getThreadExternalAllocSize() {
Carl Shapirob5961982010-12-22 15:54:53 -08001001 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001002 }
Carl Shapirob5961982010-12-22 15:54:53 -08001003
Carl Shapirob5961982010-12-22 15:54:53 -08001004 /**
Carl Shapiro7e942842011-01-12 17:17:45 -08001005 * This method exists for compatibility and has no effect.
Carl Shapirob5961982010-12-22 15:54:53 -08001006 * @deprecated This method is now obsolete.
1007 */
1008 @Deprecated
1009 public static void resetThreadExternalAllocSize() {}
1010
Ian Rogersfe067a42013-02-22 19:59:23 -08001011 /**
1012 * Returns the number of thread-local non-concurrent GC invocations between a
1013 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
1014 */
1015 public static int getThreadGcInvocationCount() {
1016 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS);
1017 }
1018
1019 /**
1020 * Clears the thread-local count of non-concurrent GC invocations.
1021 * @see #getThreadGcInvocationCount()
1022 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 public static void resetThreadGcInvocationCount() {
1024 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS);
1025 }
Ian Rogersfe067a42013-02-22 19:59:23 -08001026
1027 /**
1028 * Clears all the global and thread-local memory allocation counters.
1029 * @see #startAllocCounting()
1030 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001031 public static void resetAllCounts() {
1032 VMDebug.resetAllocCount(VMDebug.KIND_ALL_COUNTS);
1033 }
1034
1035 /**
1036 * Returns the size of the native heap.
1037 * @return The size of the native heap in bytes.
1038 */
1039 public static native long getNativeHeapSize();
1040
1041 /**
1042 * Returns the amount of allocated memory in the native heap.
1043 * @return The allocated size in bytes.
1044 */
1045 public static native long getNativeHeapAllocatedSize();
1046
1047 /**
1048 * Returns the amount of free memory in the native heap.
1049 * @return The freed size in bytes.
1050 */
1051 public static native long getNativeHeapFreeSize();
1052
1053 /**
1054 * Retrieves information about this processes memory usages. This information is broken down by
1055 * how much is in use by dalivk, the native heap, and everything else.
1056 */
1057 public static native void getMemoryInfo(MemoryInfo memoryInfo);
1058
1059 /**
Dianne Hackborn3025ef32009-08-31 21:31:47 -07001060 * Note: currently only works when the requested pid has the same UID
1061 * as the caller.
1062 * @hide
1063 */
1064 public static native void getMemoryInfo(int pid, MemoryInfo memoryInfo);
1065
1066 /**
Dianne Hackbornb437e092011-08-05 17:50:29 -07001067 * Retrieves the PSS memory used by the process as given by the
1068 * smaps.
1069 */
1070 public static native long getPss();
1071
1072 /**
1073 * Retrieves the PSS memory used by the process as given by the
Dianne Hackbornc8230512013-07-13 21:32:12 -07001074 * smaps. Optionally supply a long array of 1 entry to also
1075 * receive the uss of the process. @hide
Dianne Hackbornb437e092011-08-05 17:50:29 -07001076 */
Dianne Hackbornc8230512013-07-13 21:32:12 -07001077 public static native long getPss(int pid, long[] outUss);
Dianne Hackbornb437e092011-08-05 17:50:29 -07001078
Dianne Hackborn8e692572013-09-10 19:06:15 -07001079 /** @hide */
1080 public static final int MEMINFO_TOTAL = 0;
1081 /** @hide */
1082 public static final int MEMINFO_FREE = 1;
1083 /** @hide */
1084 public static final int MEMINFO_BUFFERS = 2;
1085 /** @hide */
1086 public static final int MEMINFO_CACHED = 3;
1087 /** @hide */
1088 public static final int MEMINFO_SHMEM = 4;
1089 /** @hide */
1090 public static final int MEMINFO_SLAB = 5;
1091 /** @hide */
Dianne Hackborncbd9a522013-09-24 23:10:14 -07001092 public static final int MEMINFO_SWAP_TOTAL = 6;
1093 /** @hide */
1094 public static final int MEMINFO_SWAP_FREE = 7;
1095 /** @hide */
1096 public static final int MEMINFO_ZRAM_TOTAL = 8;
1097 /** @hide */
1098 public static final int MEMINFO_COUNT = 9;
Dianne Hackborn8e692572013-09-10 19:06:15 -07001099
1100 /**
1101 * Retrieves /proc/meminfo. outSizes is filled with fields
1102 * as defined by MEMINFO_* offsets.
1103 * @hide
1104 */
1105 public static native void getMemInfo(long[] outSizes);
1106
Dianne Hackbornb437e092011-08-05 17:50:29 -07001107 /**
Carl Shapiro11073832011-01-12 16:28:57 -08001108 * Establish an object allocation limit in the current thread.
Carl Shapiro7e942842011-01-12 17:17:45 -08001109 * This feature was never enabled in release builds. The
1110 * allocation limits feature was removed in Honeycomb. This
1111 * method exists for compatibility and always returns -1 and has
1112 * no effect.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 *
Carl Shapiro11073832011-01-12 16:28:57 -08001114 * @deprecated This method is now obsolete.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001115 */
Carl Shapiro11073832011-01-12 16:28:57 -08001116 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 public static int setAllocationLimit(int limit) {
Carl Shapiro11073832011-01-12 16:28:57 -08001118 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001119 }
1120
1121 /**
Carl Shapiro11073832011-01-12 16:28:57 -08001122 * Establish a global object allocation limit. This feature was
Carl Shapiro7e942842011-01-12 17:17:45 -08001123 * never enabled in release builds. The allocation limits feature
1124 * was removed in Honeycomb. This method exists for compatibility
1125 * and always returns -1 and has no effect.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001126 *
Carl Shapiro11073832011-01-12 16:28:57 -08001127 * @deprecated This method is now obsolete.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001128 */
Carl Shapiro11073832011-01-12 16:28:57 -08001129 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001130 public static int setGlobalAllocationLimit(int limit) {
Carl Shapiro11073832011-01-12 16:28:57 -08001131 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001132 }
1133
1134 /**
1135 * Dump a list of all currently loaded class to the log file.
1136 *
1137 * @param flags See constants above.
1138 */
1139 public static void printLoadedClasses(int flags) {
1140 VMDebug.printLoadedClasses(flags);
1141 }
1142
1143 /**
1144 * Get the number of loaded classes.
1145 * @return the number of loaded classes.
1146 */
1147 public static int getLoadedClassCount() {
1148 return VMDebug.getLoadedClassCount();
1149 }
1150
1151 /**
Andy McFadden824c5102010-07-09 16:26:57 -07001152 * Dump "hprof" data to the specified file. This may cause a GC.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001153 *
1154 * @param fileName Full pathname of output file (e.g. "/sdcard/dump.hprof").
1155 * @throws UnsupportedOperationException if the VM was built without
1156 * HPROF support.
1157 * @throws IOException if an error occurs while opening or writing files.
1158 */
1159 public static void dumpHprofData(String fileName) throws IOException {
1160 VMDebug.dumpHprofData(fileName);
1161 }
1162
1163 /**
Andy McFadden824c5102010-07-09 16:26:57 -07001164 * Like dumpHprofData(String), but takes an already-opened
1165 * FileDescriptor to which the trace is written. The file name is also
1166 * supplied simply for logging. Makes a dup of the file descriptor.
1167 *
1168 * Primarily for use by the "am" shell command.
1169 *
1170 * @hide
1171 */
1172 public static void dumpHprofData(String fileName, FileDescriptor fd)
1173 throws IOException {
1174 VMDebug.dumpHprofData(fileName, fd);
1175 }
1176
1177 /**
1178 * Collect "hprof" and send it to DDMS. This may cause a GC.
Andy McFadden07a96612010-01-28 16:54:37 -08001179 *
1180 * @throws UnsupportedOperationException if the VM was built without
1181 * HPROF support.
Andy McFadden07a96612010-01-28 16:54:37 -08001182 * @hide
1183 */
1184 public static void dumpHprofDataDdms() {
1185 VMDebug.dumpHprofDataDdms();
1186 }
1187
1188 /**
Andy McFadden06a6b552010-07-13 16:28:09 -07001189 * Writes native heap data to the specified file descriptor.
1190 *
1191 * @hide
1192 */
1193 public static native void dumpNativeHeap(FileDescriptor fd);
1194
1195 /**
Brian Carlstromc21550a2010-10-05 21:34:06 -07001196 * Returns a count of the extant instances of a class.
1197 *
1198 * @hide
1199 */
1200 public static long countInstancesOfClass(Class cls) {
Brian Carlstrom7495cfa2010-11-30 18:06:00 -08001201 return VMDebug.countInstancesOfClass(cls, true);
Brian Carlstromc21550a2010-10-05 21:34:06 -07001202 }
1203
1204 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001205 * Returns the number of sent transactions from this process.
1206 * @return The number of sent transactions or -1 if it could not read t.
1207 */
1208 public static native int getBinderSentTransactions();
1209
1210 /**
1211 * Returns the number of received transactions from the binder driver.
1212 * @return The number of received transactions or -1 if it could not read the stats.
1213 */
1214 public static native int getBinderReceivedTransactions();
1215
1216 /**
1217 * Returns the number of active local Binder objects that exist in the
1218 * current process.
1219 */
1220 public static final native int getBinderLocalObjectCount();
1221
1222 /**
1223 * Returns the number of references to remote proxy Binder objects that
1224 * exist in the current process.
1225 */
1226 public static final native int getBinderProxyObjectCount();
1227
1228 /**
1229 * Returns the number of death notification links to Binder objects that
1230 * exist in the current process.
1231 */
1232 public static final native int getBinderDeathObjectCount();
1233
1234 /**
Andy McFadden599c9182009-04-08 00:35:56 -07001235 * Primes the register map cache.
1236 *
1237 * Only works for classes in the bootstrap class loader. Does not
1238 * cause classes to be loaded if they're not already present.
1239 *
1240 * The classAndMethodDesc argument is a concatentation of the VM-internal
1241 * class descriptor, method name, and method descriptor. Examples:
1242 * Landroid/os/Looper;.loop:()V
1243 * Landroid/app/ActivityThread;.main:([Ljava/lang/String;)V
1244 *
1245 * @param classAndMethodDesc the method to prepare
1246 *
1247 * @hide
1248 */
1249 public static final boolean cacheRegisterMap(String classAndMethodDesc) {
1250 return VMDebug.cacheRegisterMap(classAndMethodDesc);
1251 }
1252
1253 /**
Andy McFaddenbfd6d482009-10-22 17:25:57 -07001254 * Dumps the contents of VM reference tables (e.g. JNI locals and
1255 * globals) to the log file.
1256 *
1257 * @hide
1258 */
1259 public static final void dumpReferenceTables() {
1260 VMDebug.dumpReferenceTables();
1261 }
1262
1263 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001264 * API for gathering and querying instruction counts.
1265 *
1266 * Example usage:
Chet Haase2970c492010-11-09 13:58:04 -08001267 * <pre>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 * Debug.InstructionCount icount = new Debug.InstructionCount();
1269 * icount.resetAndStart();
1270 * [... do lots of stuff ...]
1271 * if (icount.collect()) {
1272 * System.out.println("Total instructions executed: "
1273 * + icount.globalTotal());
1274 * System.out.println("Method invocations: "
1275 * + icount.globalMethodInvocations());
1276 * }
Chet Haase2970c492010-11-09 13:58:04 -08001277 * </pre>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001278 */
1279 public static class InstructionCount {
Dan Bornsteinb96f5892010-12-02 17:19:53 -08001280 private static final int NUM_INSTR =
1281 OpcodeInfo.MAXIMUM_PACKED_VALUE + 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001282
1283 private int[] mCounts;
1284
1285 public InstructionCount() {
1286 mCounts = new int[NUM_INSTR];
1287 }
1288
1289 /**
1290 * Reset counters and ensure counts are running. Counts may
1291 * have already been running.
1292 *
1293 * @return true if counting was started
1294 */
1295 public boolean resetAndStart() {
1296 try {
1297 VMDebug.startInstructionCounting();
1298 VMDebug.resetInstructionCount();
1299 } catch (UnsupportedOperationException uoe) {
1300 return false;
1301 }
1302 return true;
1303 }
1304
1305 /**
1306 * Collect instruction counts. May or may not stop the
1307 * counting process.
1308 */
1309 public boolean collect() {
1310 try {
1311 VMDebug.stopInstructionCounting();
1312 VMDebug.getInstructionCount(mCounts);
1313 } catch (UnsupportedOperationException uoe) {
1314 return false;
1315 }
1316 return true;
1317 }
1318
1319 /**
1320 * Return the total number of instructions executed globally (i.e. in
1321 * all threads).
1322 */
1323 public int globalTotal() {
1324 int count = 0;
Dan Bornstein1d99b062010-11-30 12:26:52 -08001325
1326 for (int i = 0; i < NUM_INSTR; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001327 count += mCounts[i];
Dan Bornstein1d99b062010-11-30 12:26:52 -08001328 }
1329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001330 return count;
1331 }
1332
1333 /**
1334 * Return the total number of method-invocation instructions
1335 * executed globally.
1336 */
1337 public int globalMethodInvocations() {
1338 int count = 0;
1339
Dan Bornstein1d99b062010-11-30 12:26:52 -08001340 for (int i = 0; i < NUM_INSTR; i++) {
1341 if (OpcodeInfo.isInvoke(i)) {
1342 count += mCounts[i];
1343 }
1344 }
1345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001346 return count;
1347 }
Dave Bort1ce5bd32009-04-22 17:36:56 -07001348 }
1349
Dave Bort1ce5bd32009-04-22 17:36:56 -07001350 /**
1351 * A Map of typed debug properties.
1352 */
1353 private static final TypedProperties debugProperties;
1354
1355 /*
1356 * Load the debug properties from the standard files into debugProperties.
1357 */
1358 static {
Joe Onorato43a17652011-04-06 19:22:23 -07001359 if (false) {
Dave Bort1ce5bd32009-04-22 17:36:56 -07001360 final String TAG = "DebugProperties";
1361 final String[] files = { "/system/debug.prop", "/debug.prop", "/data/debug.prop" };
1362 final TypedProperties tp = new TypedProperties();
1363
1364 // Read the properties from each of the files, if present.
Dave Borte9bfd9b2009-05-04 14:35:23 -07001365 for (String file : files) {
Dave Bort1ce5bd32009-04-22 17:36:56 -07001366 Reader r;
1367 try {
1368 r = new FileReader(file);
1369 } catch (FileNotFoundException ex) {
1370 // It's ok if a file is missing.
1371 continue;
1372 }
1373
Dave Bort1ce5bd32009-04-22 17:36:56 -07001374 try {
1375 tp.load(r);
Dave Borte9bfd9b2009-05-04 14:35:23 -07001376 } catch (Exception ex) {
1377 throw new RuntimeException("Problem loading " + file, ex);
1378 } finally {
1379 try {
1380 r.close();
1381 } catch (IOException ex) {
1382 // Ignore this error.
1383 }
Dave Bort1ce5bd32009-04-22 17:36:56 -07001384 }
1385 }
1386
1387 debugProperties = tp.isEmpty() ? null : tp;
1388 } else {
1389 debugProperties = null;
1390 }
1391 }
1392
1393
1394 /**
1395 * Returns true if the type of the field matches the specified class.
1396 * Handles the case where the class is, e.g., java.lang.Boolean, but
1397 * the field is of the primitive "boolean" type. Also handles all of
1398 * the java.lang.Number subclasses.
1399 */
1400 private static boolean fieldTypeMatches(Field field, Class<?> cl) {
1401 Class<?> fieldClass = field.getType();
1402 if (fieldClass == cl) {
1403 return true;
1404 }
1405 Field primitiveTypeField;
1406 try {
1407 /* All of the classes we care about (Boolean, Integer, etc.)
1408 * have a Class field called "TYPE" that points to the corresponding
1409 * primitive class.
1410 */
1411 primitiveTypeField = cl.getField("TYPE");
1412 } catch (NoSuchFieldException ex) {
1413 return false;
1414 }
1415 try {
Dave Borte9bfd9b2009-05-04 14:35:23 -07001416 return fieldClass == (Class<?>) primitiveTypeField.get(null);
Dave Bort1ce5bd32009-04-22 17:36:56 -07001417 } catch (IllegalAccessException ex) {
1418 return false;
1419 }
1420 }
1421
1422
1423 /**
1424 * Looks up the property that corresponds to the field, and sets the field's value
1425 * if the types match.
1426 */
Dave Borte9bfd9b2009-05-04 14:35:23 -07001427 private static void modifyFieldIfSet(final Field field, final TypedProperties properties,
1428 final String propertyName) {
Dave Bort1ce5bd32009-04-22 17:36:56 -07001429 if (field.getType() == java.lang.String.class) {
Dave Borte9bfd9b2009-05-04 14:35:23 -07001430 int stringInfo = properties.getStringInfo(propertyName);
Dave Bort1ce5bd32009-04-22 17:36:56 -07001431 switch (stringInfo) {
Dave Borte9bfd9b2009-05-04 14:35:23 -07001432 case TypedProperties.STRING_SET:
1433 // Handle as usual below.
1434 break;
1435 case TypedProperties.STRING_NULL:
1436 try {
1437 field.set(null, null); // null object for static fields; null string
1438 } catch (IllegalAccessException ex) {
1439 throw new IllegalArgumentException(
1440 "Cannot set field for " + propertyName, ex);
1441 }
1442 return;
1443 case TypedProperties.STRING_NOT_SET:
1444 return;
1445 case TypedProperties.STRING_TYPE_MISMATCH:
Dave Bort1ce5bd32009-04-22 17:36:56 -07001446 throw new IllegalArgumentException(
Dave Borte9bfd9b2009-05-04 14:35:23 -07001447 "Type of " + propertyName + " " +
1448 " does not match field type (" + field.getType() + ")");
1449 default:
1450 throw new IllegalStateException(
1451 "Unexpected getStringInfo(" + propertyName + ") return value " +
1452 stringInfo);
Dave Bort1ce5bd32009-04-22 17:36:56 -07001453 }
1454 }
Dave Borte9bfd9b2009-05-04 14:35:23 -07001455 Object value = properties.get(propertyName);
Dave Bort1ce5bd32009-04-22 17:36:56 -07001456 if (value != null) {
1457 if (!fieldTypeMatches(field, value.getClass())) {
1458 throw new IllegalArgumentException(
1459 "Type of " + propertyName + " (" + value.getClass() + ") " +
1460 " does not match field type (" + field.getType() + ")");
1461 }
1462 try {
1463 field.set(null, value); // null object for static fields
1464 } catch (IllegalAccessException ex) {
1465 throw new IllegalArgumentException(
1466 "Cannot set field for " + propertyName, ex);
1467 }
1468 }
1469 }
1470
1471
1472 /**
Romain Guyc4b11a72009-05-13 15:46:37 -07001473 * Equivalent to <code>setFieldsOn(cl, false)</code>.
1474 *
1475 * @see #setFieldsOn(Class, boolean)
Romain Guyd4103d02009-05-14 12:24:21 -07001476 *
1477 * @hide
Romain Guyc4b11a72009-05-13 15:46:37 -07001478 */
1479 public static void setFieldsOn(Class<?> cl) {
1480 setFieldsOn(cl, false);
1481 }
1482
1483 /**
Dave Bort1ce5bd32009-04-22 17:36:56 -07001484 * Reflectively sets static fields of a class based on internal debugging
Joe Onorato43a17652011-04-06 19:22:23 -07001485 * properties. This method is a no-op if false is
Dave Bort1ce5bd32009-04-22 17:36:56 -07001486 * false.
1487 * <p>
Joe Onorato43a17652011-04-06 19:22:23 -07001488 * <strong>NOTE TO APPLICATION DEVELOPERS</strong>: false will
Dave Bort1ce5bd32009-04-22 17:36:56 -07001489 * always be false in release builds. This API is typically only useful
1490 * for platform developers.
1491 * </p>
1492 * Class setup: define a class whose only fields are non-final, static
1493 * primitive types (except for "char") or Strings. In a static block
1494 * after the field definitions/initializations, pass the class to
Romain Guyc4b11a72009-05-13 15:46:37 -07001495 * this method, Debug.setFieldsOn(). Example:
Dave Bort1ce5bd32009-04-22 17:36:56 -07001496 * <pre>
1497 * package com.example;
1498 *
1499 * import android.os.Debug;
1500 *
1501 * public class MyDebugVars {
1502 * public static String s = "a string";
1503 * public static String s2 = "second string";
1504 * public static String ns = null;
1505 * public static boolean b = false;
1506 * public static int i = 5;
Romain Guyc4b11a72009-05-13 15:46:37 -07001507 * @Debug.DebugProperty
Dave Bort1ce5bd32009-04-22 17:36:56 -07001508 * public static float f = 0.1f;
Romain Guyc4b11a72009-05-13 15:46:37 -07001509 * @@Debug.DebugProperty
Dave Bort1ce5bd32009-04-22 17:36:56 -07001510 * public static double d = 0.5d;
1511 *
1512 * // This MUST appear AFTER all fields are defined and initialized!
1513 * static {
Romain Guyc4b11a72009-05-13 15:46:37 -07001514 * // Sets all the fields
Dave Borte9bfd9b2009-05-04 14:35:23 -07001515 * Debug.setFieldsOn(MyDebugVars.class);
Christian Mehlmauer798e2d32010-06-17 18:24:07 +02001516 *
Romain Guyc4b11a72009-05-13 15:46:37 -07001517 * // Sets only the fields annotated with @Debug.DebugProperty
1518 * // Debug.setFieldsOn(MyDebugVars.class, true);
Dave Bort1ce5bd32009-04-22 17:36:56 -07001519 * }
1520 * }
1521 * </pre>
Dave Borte9bfd9b2009-05-04 14:35:23 -07001522 * setFieldsOn() may override the value of any field in the class based
Dave Bort1ce5bd32009-04-22 17:36:56 -07001523 * on internal properties that are fixed at boot time.
1524 * <p>
1525 * These properties are only set during platform debugging, and are not
1526 * meant to be used as a general-purpose properties store.
1527 *
1528 * {@hide}
1529 *
1530 * @param cl The class to (possibly) modify
Romain Guyc4b11a72009-05-13 15:46:37 -07001531 * @param partial If false, sets all static fields, otherwise, only set
1532 * fields with the {@link android.os.Debug.DebugProperty}
1533 * annotation
Dave Bort1ce5bd32009-04-22 17:36:56 -07001534 * @throws IllegalArgumentException if any fields are final or non-static,
1535 * or if the type of the field does not match the type of
1536 * the internal debugging property value.
1537 */
Romain Guyc4b11a72009-05-13 15:46:37 -07001538 public static void setFieldsOn(Class<?> cl, boolean partial) {
Joe Onorato43a17652011-04-06 19:22:23 -07001539 if (false) {
Dave Bort1ce5bd32009-04-22 17:36:56 -07001540 if (debugProperties != null) {
1541 /* Only look for fields declared directly by the class,
1542 * so we don't mysteriously change static fields in superclasses.
1543 */
1544 for (Field field : cl.getDeclaredFields()) {
Romain Guyc4b11a72009-05-13 15:46:37 -07001545 if (!partial || field.getAnnotation(DebugProperty.class) != null) {
1546 final String propertyName = cl.getName() + "." + field.getName();
1547 boolean isStatic = Modifier.isStatic(field.getModifiers());
1548 boolean isFinal = Modifier.isFinal(field.getModifiers());
1549
1550 if (!isStatic || isFinal) {
1551 throw new IllegalArgumentException(propertyName +
1552 " must be static and non-final");
1553 }
1554 modifyFieldIfSet(field, debugProperties, propertyName);
Dave Bort1ce5bd32009-04-22 17:36:56 -07001555 }
Dave Bort1ce5bd32009-04-22 17:36:56 -07001556 }
1557 }
1558 } else {
Dan Egnor3eda9792010-03-05 13:28:36 -08001559 Log.wtf(TAG,
Dave Borte9bfd9b2009-05-04 14:35:23 -07001560 "setFieldsOn(" + (cl == null ? "null" : cl.getName()) +
Dave Bort1ce5bd32009-04-22 17:36:56 -07001561 ") called in non-DEBUG build");
1562 }
1563 }
Romain Guyc4b11a72009-05-13 15:46:37 -07001564
1565 /**
1566 * Annotation to put on fields you want to set with
1567 * {@link Debug#setFieldsOn(Class, boolean)}.
1568 *
1569 * @hide
1570 */
1571 @Target({ ElementType.FIELD })
1572 @Retention(RetentionPolicy.RUNTIME)
1573 public @interface DebugProperty {
1574 }
Dan Egnor3eda9792010-03-05 13:28:36 -08001575
1576 /**
1577 * Get a debugging dump of a system service by name.
1578 *
1579 * <p>Most services require the caller to hold android.permission.DUMP.
1580 *
1581 * @param name of the service to dump
1582 * @param fd to write dump output to (usually an output log file)
1583 * @param args to pass to the service's dump method, may be null
1584 * @return true if the service was dumped successfully, false if
1585 * the service could not be found or had an error while dumping
1586 */
1587 public static boolean dumpService(String name, FileDescriptor fd, String[] args) {
1588 IBinder service = ServiceManager.getService(name);
1589 if (service == null) {
1590 Log.e(TAG, "Can't find service to dump: " + name);
1591 return false;
1592 }
1593
1594 try {
1595 service.dump(fd, args);
1596 return true;
1597 } catch (RemoteException e) {
1598 Log.e(TAG, "Can't dump service: " + name, e);
1599 return false;
1600 }
1601 }
Craig Mautnera51a9562012-04-17 17:05:26 -07001602
1603 /**
Dianne Hackbornf72467a2012-06-08 17:23:59 -07001604 * Have the stack traces of the given native process dumped to the
1605 * specified file. Will be appended to the file.
1606 * @hide
1607 */
1608 public static native void dumpNativeBacktraceToFile(int pid, String file);
1609
1610 /**
Craig Mautnera51a9562012-04-17 17:05:26 -07001611 * Return a String describing the calling method and location at a particular stack depth.
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -07001612 * @param callStack the Thread stack
Craig Mautnera51a9562012-04-17 17:05:26 -07001613 * @param depth the depth of stack to return information for.
1614 * @return the String describing the caller at that depth.
1615 */
1616 private static String getCaller(StackTraceElement callStack[], int depth) {
1617 // callStack[4] is the caller of the method that called getCallers()
1618 if (4 + depth >= callStack.length) {
1619 return "<bottom of call stack>";
1620 }
1621 StackTraceElement caller = callStack[4 + depth];
1622 return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber();
1623 }
1624
1625 /**
1626 * Return a string consisting of methods and locations at multiple call stack levels.
1627 * @param depth the number of levels to return, starting with the immediate caller.
1628 * @return a string describing the call stack.
1629 * {@hide}
1630 */
1631 public static String getCallers(final int depth) {
1632 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
1633 StringBuffer sb = new StringBuffer();
1634 for (int i = 0; i < depth; i++) {
1635 sb.append(getCaller(callStack, i)).append(" ");
1636 }
1637 return sb.toString();
1638 }
1639
1640 /**
Dianne Hackbornfd6c7b12013-10-03 10:42:26 -07001641 * Return a string consisting of methods and locations at multiple call stack levels.
1642 * @param depth the number of levels to return, starting with the immediate caller.
1643 * @return a string describing the call stack.
1644 * {@hide}
1645 */
1646 public static String getCallers(final int start, int depth) {
1647 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
1648 StringBuffer sb = new StringBuffer();
1649 depth += start;
1650 for (int i = start; i < depth; i++) {
1651 sb.append(getCaller(callStack, i)).append(" ");
1652 }
1653 return sb.toString();
1654 }
1655
1656 /**
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001657 * Like {@link #getCallers(int)}, but each location is append to the string
1658 * as a new line with <var>linePrefix</var> in front of it.
1659 * @param depth the number of levels to return, starting with the immediate caller.
1660 * @param linePrefix prefix to put in front of each location.
1661 * @return a string describing the call stack.
1662 * {@hide}
1663 */
1664 public static String getCallers(final int depth, String linePrefix) {
1665 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
1666 StringBuffer sb = new StringBuffer();
1667 for (int i = 0; i < depth; i++) {
1668 sb.append(linePrefix).append(getCaller(callStack, i)).append("\n");
1669 }
1670 return sb.toString();
1671 }
1672
1673 /**
Ian Rogersfe067a42013-02-22 19:59:23 -08001674 * @return a String describing the immediate caller of the calling method.
Craig Mautnera51a9562012-04-17 17:05:26 -07001675 * {@hide}
1676 */
1677 public static String getCaller() {
1678 return getCaller(Thread.currentThread().getStackTrace(), 0);
1679 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001680}