blob: 18730b65a7dd12eae9bcc1af0d00546f8b172f3f [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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import java.io.PrintWriter;
Dave Bort1ce5bd32009-04-22 17:36:56 -070030import java.io.Reader;
31import java.lang.reflect.Field;
32import java.lang.reflect.Modifier;
Romain Guyc4b11a72009-05-13 15:46:37 -070033import java.lang.annotation.Target;
34import java.lang.annotation.ElementType;
35import java.lang.annotation.Retention;
36import java.lang.annotation.RetentionPolicy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037
38import org.apache.harmony.dalvik.ddmc.Chunk;
39import org.apache.harmony.dalvik.ddmc.ChunkHandler;
40import org.apache.harmony.dalvik.ddmc.DdmServer;
41
Dan Bornstein9f315542010-11-19 18:12:55 -080042import dalvik.bytecode.OpcodeInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import dalvik.system.VMDebug;
44
45
46/**
Ian Rogersfe067a42013-02-22 19:59:23 -080047 * Provides various debugging methods for Android applications, including
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048 * tracing and allocation counts.
49 * <p><strong>Logging Trace Files</strong></p>
50 * <p>Debug can create log files that give details about an application, such as
51 * a call stack and start/stop times for any running methods. See <a
52href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
53 * information about reading trace files. To start logging trace files, call one
54 * of the startMethodTracing() methods. To stop tracing, call
55 * {@link #stopMethodTracing()}.
56 */
57public final class Debug
58{
Dan Egnor3eda9792010-03-05 13:28:36 -080059 private static final String TAG = "Debug";
60
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061 /**
62 * Flags for startMethodTracing(). These can be ORed together.
63 *
64 * TRACE_COUNT_ALLOCS adds the results from startAllocCounting to the
65 * trace key file.
66 */
67 public static final int TRACE_COUNT_ALLOCS = VMDebug.TRACE_COUNT_ALLOCS;
68
69 /**
70 * Flags for printLoadedClasses(). Default behavior is to only show
71 * the class name.
72 */
73 public static final int SHOW_FULL_DETAIL = 1;
74 public static final int SHOW_CLASSLOADER = (1 << 1);
75 public static final int SHOW_INITIALIZED = (1 << 2);
76
77 // set/cleared by waitForDebugger()
78 private static volatile boolean mWaiting = false;
79
80 private Debug() {}
81
82 /*
83 * How long to wait for the debugger to finish sending requests. I've
84 * seen this hit 800msec on the device while waiting for a response
85 * to travel over USB and get processed, so we take that and add
86 * half a second.
87 */
88 private static final int MIN_DEBUGGER_IDLE = 1300; // msec
89
90 /* how long to sleep when polling for activity */
91 private static final int SPIN_DELAY = 200; // msec
92
93 /**
94 * Default trace file path and file
95 */
Christian Mehlmauer798e2d32010-06-17 18:24:07 +020096 private static final String DEFAULT_TRACE_PATH_PREFIX =
Jeff Sharkeyb049e212012-09-07 23:16:01 -070097 Environment.getLegacyExternalStorageDirectory().getPath() + "/";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 private static final String DEFAULT_TRACE_BODY = "dmtrace";
99 private static final String DEFAULT_TRACE_EXTENSION = ".trace";
100 private static final String DEFAULT_TRACE_FILE_PATH =
101 DEFAULT_TRACE_PATH_PREFIX + DEFAULT_TRACE_BODY
102 + DEFAULT_TRACE_EXTENSION;
103
104
105 /**
106 * This class is used to retrieved various statistics about the memory mappings for this
107 * process. The returns info broken down by dalvik, native, and other. All results are in kB.
108 */
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700109 public static class MemoryInfo implements Parcelable {
Dianne Hackborn64770d12013-05-23 17:51:19 -0700110 /** The proportional set size for dalvik heap. (Doesn't include other Dalvik overhead.) */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 public int dalvikPss;
Dianne Hackborn64770d12013-05-23 17:51:19 -0700112 /** The proportional set size that is swappable for dalvik heap. */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700113 /** @hide We may want to expose this, eventually. */
114 public int dalvikSwappablePss;
Dianne Hackborn64770d12013-05-23 17:51:19 -0700115 /** The private dirty pages used by dalvik heap. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 public int dalvikPrivateDirty;
Dianne Hackborn64770d12013-05-23 17:51:19 -0700117 /** The shared dirty pages used by dalvik heap. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118 public int dalvikSharedDirty;
Dianne Hackborn64770d12013-05-23 17:51:19 -0700119 /** The private clean pages used by dalvik heap. */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700120 /** @hide We may want to expose this, eventually. */
121 public int dalvikPrivateClean;
Dianne Hackborn64770d12013-05-23 17:51:19 -0700122 /** The shared clean pages used by dalvik heap. */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700123 /** @hide We may want to expose this, eventually. */
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700124 public int dalvikSharedClean;
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700125 /** The dirty dalvik pages that have been swapped out. */
126 /** @hide We may want to expose this, eventually. */
127 public int dalvikSwappedOut;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128
129 /** The proportional set size for the native heap. */
130 public int nativePss;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700131 /** The proportional set size that is swappable for the native heap. */
132 /** @hide We may want to expose this, eventually. */
133 public int nativeSwappablePss;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 /** The private dirty pages used by the native heap. */
135 public int nativePrivateDirty;
136 /** The shared dirty pages used by the native heap. */
137 public int nativeSharedDirty;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700138 /** The private clean pages used by the native heap. */
139 /** @hide We may want to expose this, eventually. */
140 public int nativePrivateClean;
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700141 /** The shared clean pages used by the native heap. */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700142 /** @hide We may want to expose this, eventually. */
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700143 public int nativeSharedClean;
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700144 /** The dirty native pages that have been swapped out. */
145 /** @hide We may want to expose this, eventually. */
146 public int nativeSwappedOut;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147
148 /** The proportional set size for everything else. */
149 public int otherPss;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700150 /** The proportional set size that is swappable for everything else. */
151 /** @hide We may want to expose this, eventually. */
152 public int otherSwappablePss;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 /** The private dirty pages used by everything else. */
154 public int otherPrivateDirty;
155 /** The shared dirty pages used by everything else. */
156 public int otherSharedDirty;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700157 /** The private clean pages used by everything else. */
158 /** @hide We may want to expose this, eventually. */
159 public int otherPrivateClean;
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700160 /** The shared clean pages used by everything else. */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700161 /** @hide We may want to expose this, eventually. */
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700162 public int otherSharedClean;
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700163 /** The dirty pages used by anyting else that have been swapped out. */
164 /** @hide We may want to expose this, eventually. */
165 public int otherSwappedOut;
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200166
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700167 /** @hide */
Adam Lesinski5b4ef812013-09-23 10:06:09 -0700168 public static final int NUM_OTHER_STATS = 16;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700169
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700170 /** @hide */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700171 public static final int NUM_DVK_STATS = 5;
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700172
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700173 /** @hide */
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700174 public static final int NUM_CATEGORIES = 7;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700175
176 /** @hide */
177 public static final int offsetPss = 0;
178 /** @hide */
179 public static final int offsetSwappablePss = 1;
180 /** @hide */
181 public static final int offsetPrivateDirty = 2;
182 /** @hide */
183 public static final int offsetSharedDirty = 3;
184 /** @hide */
185 public static final int offsetPrivateClean = 4;
186 /** @hide */
187 public static final int offsetSharedClean = 5;
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700188 /** @hide */
189 public static final int offsetSwappedOut = 6;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700190
191 private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES];
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700192
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700193 public MemoryInfo() {
194 }
195
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -0700196 /**
197 * Return total PSS memory usage in kB.
198 */
199 public int getTotalPss() {
200 return dalvikPss + nativePss + otherPss;
201 }
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200202
Dianne Hackbornc8230512013-07-13 21:32:12 -0700203 /**
204 * @hide Return total PSS memory usage in kB.
205 */
206 public int getTotalUss() {
207 return dalvikPrivateClean + dalvikPrivateDirty
208 + nativePrivateClean + nativePrivateDirty
209 + otherPrivateClean + otherPrivateDirty;
210 }
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700211
212 /**
213 * Return total PSS memory usage in kB.
214 */
215 public int getTotalSwappablePss() {
216 return dalvikSwappablePss + nativeSwappablePss + otherSwappablePss;
217 }
218
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -0700219 /**
220 * Return total private dirty memory usage in kB.
221 */
222 public int getTotalPrivateDirty() {
223 return dalvikPrivateDirty + nativePrivateDirty + otherPrivateDirty;
224 }
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200225
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -0700226 /**
227 * Return total shared dirty memory usage in kB.
228 */
229 public int getTotalSharedDirty() {
230 return dalvikSharedDirty + nativeSharedDirty + otherSharedDirty;
231 }
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200232
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700233 /**
234 * Return total shared clean memory usage in kB.
235 */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700236 public int getTotalPrivateClean() {
237 return dalvikPrivateClean + nativePrivateClean + otherPrivateClean;
238 }
239
240 /**
241 * Return total shared clean memory usage in kB.
242 */
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700243 public int getTotalSharedClean() {
244 return dalvikSharedClean + nativeSharedClean + otherSharedClean;
245 }
246
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700247 /**
248 * Return total swapped out memory in kB.
249 * @hide
250 */
251 public int getTotalSwappedOut() {
252 return dalvikSwappedOut + nativeSwappedOut + otherSwappedOut;
253 }
254
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700255 /** @hide */
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700256 public int getOtherPss(int which) {
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700257 return otherStats[which*NUM_CATEGORIES + offsetPss];
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700258 }
259
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700260
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700261 /** @hide */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700262 public int getOtherSwappablePss(int which) {
263 return otherStats[which*NUM_CATEGORIES + offsetSwappablePss];
264 }
265
266
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700267 /** @hide */
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700268 public int getOtherPrivateDirty(int which) {
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700269 return otherStats[which*NUM_CATEGORIES + offsetPrivateDirty];
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700270 }
271
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700272 /** @hide */
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700273 public int getOtherSharedDirty(int which) {
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700274 return otherStats[which*NUM_CATEGORIES + offsetSharedDirty];
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700275 }
276
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700277 /** @hide */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700278 public int getOtherPrivateClean(int which) {
279 return otherStats[which*NUM_CATEGORIES + offsetPrivateClean];
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700280 }
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700281
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700282 /** @hide */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700283 public int getOtherSharedClean(int which) {
284 return otherStats[which*NUM_CATEGORIES + offsetSharedClean];
285 }
286
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700287 /** @hide */
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700288 public int getOtherSwappedOut(int which) {
289 return otherStats[which*NUM_CATEGORIES + offsetSwappedOut];
290 }
291
292 /** @hide */
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700293 public static String getOtherLabel(int which) {
294 switch (which) {
Dianne Hackborn64770d12013-05-23 17:51:19 -0700295 case 0: return "Dalvik Other";
296 case 1: return "Stack";
297 case 2: return "Cursor";
298 case 3: return "Ashmem";
299 case 4: return "Other dev";
300 case 5: return ".so mmap";
301 case 6: return ".jar mmap";
302 case 7: return ".apk mmap";
303 case 8: return ".ttf mmap";
304 case 9: return ".dex mmap";
305 case 10: return "code mmap";
306 case 11: return "image mmap";
307 case 12: return "Other mmap";
Adam Lesinski5b4ef812013-09-23 10:06:09 -0700308 case 13: return "Graphics";
309 case 14: return "GL";
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700310 case 15: return "Memtrack";
Adam Lesinski5b4ef812013-09-23 10:06:09 -0700311 case 16: return ".Heap";
312 case 17: return ".LOS";
313 case 18: return ".LinearAlloc";
314 case 19: return ".GC";
315 case 20: return ".JITCache";
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700316 default: return "????";
317 }
318 }
319
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700320 public int describeContents() {
321 return 0;
322 }
323
324 public void writeToParcel(Parcel dest, int flags) {
325 dest.writeInt(dalvikPss);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700326 dest.writeInt(dalvikSwappablePss);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700327 dest.writeInt(dalvikPrivateDirty);
328 dest.writeInt(dalvikSharedDirty);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700329 dest.writeInt(dalvikPrivateClean);
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700330 dest.writeInt(dalvikSharedClean);
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700331 dest.writeInt(dalvikSwappedOut);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700332 dest.writeInt(nativePss);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700333 dest.writeInt(nativeSwappablePss);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700334 dest.writeInt(nativePrivateDirty);
335 dest.writeInt(nativeSharedDirty);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700336 dest.writeInt(nativePrivateClean);
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700337 dest.writeInt(nativeSharedClean);
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700338 dest.writeInt(nativeSwappedOut);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700339 dest.writeInt(otherPss);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700340 dest.writeInt(otherSwappablePss);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700341 dest.writeInt(otherPrivateDirty);
342 dest.writeInt(otherSharedDirty);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700343 dest.writeInt(otherPrivateClean);
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700344 dest.writeInt(otherSharedClean);
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700345 dest.writeInt(otherSwappedOut);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700346 dest.writeIntArray(otherStats);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700347 }
348
349 public void readFromParcel(Parcel source) {
350 dalvikPss = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700351 dalvikSwappablePss = source.readInt();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700352 dalvikPrivateDirty = source.readInt();
353 dalvikSharedDirty = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700354 dalvikPrivateClean = source.readInt();
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700355 dalvikSharedClean = source.readInt();
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700356 dalvikSwappedOut = source.readInt();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700357 nativePss = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700358 nativeSwappablePss = source.readInt();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700359 nativePrivateDirty = source.readInt();
360 nativeSharedDirty = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700361 nativePrivateClean = source.readInt();
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700362 nativeSharedClean = source.readInt();
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700363 nativeSwappedOut = source.readInt();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700364 otherPss = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700365 otherSwappablePss = source.readInt();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700366 otherPrivateDirty = source.readInt();
367 otherSharedDirty = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700368 otherPrivateClean = source.readInt();
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700369 otherSharedClean = source.readInt();
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700370 otherSwappedOut = source.readInt();
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700371 otherStats = source.createIntArray();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700372 }
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200373
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700374 public static final Creator<MemoryInfo> CREATOR = new Creator<MemoryInfo>() {
375 public MemoryInfo createFromParcel(Parcel source) {
376 return new MemoryInfo(source);
377 }
378 public MemoryInfo[] newArray(int size) {
379 return new MemoryInfo[size];
380 }
381 };
382
383 private MemoryInfo(Parcel source) {
384 readFromParcel(source);
385 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 }
387
388
389 /**
390 * Wait until a debugger attaches. As soon as the debugger attaches,
391 * this returns, so you will need to place a breakpoint after the
392 * waitForDebugger() call if you want to start tracing immediately.
393 */
394 public static void waitForDebugger() {
395 if (!VMDebug.isDebuggingEnabled()) {
396 //System.out.println("debugging not enabled, not waiting");
397 return;
398 }
399 if (isDebuggerConnected())
400 return;
401
402 // if DDMS is listening, inform them of our plight
403 System.out.println("Sending WAIT chunk");
404 byte[] data = new byte[] { 0 }; // 0 == "waiting for debugger"
405 Chunk waitChunk = new Chunk(ChunkHandler.type("WAIT"), data, 0, 1);
406 DdmServer.sendChunk(waitChunk);
407
408 mWaiting = true;
409 while (!isDebuggerConnected()) {
410 try { Thread.sleep(SPIN_DELAY); }
411 catch (InterruptedException ie) {}
412 }
413 mWaiting = false;
414
415 System.out.println("Debugger has connected");
416
417 /*
418 * There is no "ready to go" signal from the debugger, and we're
419 * not allowed to suspend ourselves -- the debugger expects us to
420 * be running happily, and gets confused if we aren't. We need to
421 * allow the debugger a chance to set breakpoints before we start
422 * running again.
423 *
424 * Sit and spin until the debugger has been idle for a short while.
425 */
426 while (true) {
427 long delta = VMDebug.lastDebuggerActivity();
428 if (delta < 0) {
429 System.out.println("debugger detached?");
430 break;
431 }
432
433 if (delta < MIN_DEBUGGER_IDLE) {
434 System.out.println("waiting for debugger to settle...");
435 try { Thread.sleep(SPIN_DELAY); }
436 catch (InterruptedException ie) {}
437 } else {
438 System.out.println("debugger has settled (" + delta + ")");
439 break;
440 }
441 }
442 }
443
444 /**
445 * Returns "true" if one or more threads is waiting for a debugger
446 * to attach.
447 */
448 public static boolean waitingForDebugger() {
449 return mWaiting;
450 }
451
452 /**
453 * Determine if a debugger is currently attached.
454 */
455 public static boolean isDebuggerConnected() {
456 return VMDebug.isDebuggerConnected();
457 }
458
459 /**
Andy McFaddene5772322010-01-22 07:23:31 -0800460 * Returns an array of strings that identify VM features. This is
461 * used by DDMS to determine what sorts of operations the VM can
462 * perform.
463 *
464 * @hide
465 */
466 public static String[] getVmFeatureList() {
467 return VMDebug.getVmFeatureList();
468 }
469
470 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 * Change the JDWP port.
472 *
473 * @deprecated no longer needed or useful
474 */
475 @Deprecated
476 public static void changeDebugPort(int port) {}
477
478 /**
479 * This is the pathname to the sysfs file that enables and disables
480 * tracing on the qemu emulator.
481 */
482 private static final String SYSFS_QEMU_TRACE_STATE = "/sys/qemu_trace/state";
483
484 /**
485 * Enable qemu tracing. For this to work requires running everything inside
486 * the qemu emulator; otherwise, this method will have no effect. The trace
487 * file is specified on the command line when the emulator is started. For
488 * example, the following command line <br />
489 * <code>emulator -trace foo</code><br />
490 * will start running the emulator and create a trace file named "foo". This
491 * method simply enables writing the trace records to the trace file.
492 *
493 * <p>
494 * The main differences between this and {@link #startMethodTracing()} are
495 * that tracing in the qemu emulator traces every cpu instruction of every
496 * process, including kernel code, so we have more complete information,
497 * including all context switches. We can also get more detailed information
498 * such as cache misses. The sequence of calls is determined by
499 * post-processing the instruction trace. The qemu tracing is also done
500 * without modifying the application or perturbing the timing of calls
501 * because no instrumentation is added to the application being traced.
502 * </p>
503 *
504 * <p>
505 * One limitation of using this method compared to using
506 * {@link #startMethodTracing()} on the real device is that the emulator
507 * does not model all of the real hardware effects such as memory and
508 * bus contention. The emulator also has a simple cache model and cannot
509 * capture all the complexities of a real cache.
510 * </p>
511 */
512 public static void startNativeTracing() {
513 // Open the sysfs file for writing and write "1" to it.
514 PrintWriter outStream = null;
515 try {
516 FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700517 outStream = new FastPrintWriter(fos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 outStream.println("1");
519 } catch (Exception e) {
520 } finally {
521 if (outStream != null)
522 outStream.close();
523 }
524
525 VMDebug.startEmulatorTracing();
526 }
527
528 /**
529 * Stop qemu tracing. See {@link #startNativeTracing()} to start tracing.
530 *
531 * <p>Tracing can be started and stopped as many times as desired. When
532 * the qemu emulator itself is stopped then the buffered trace records
533 * are flushed and written to the trace file. In fact, it is not necessary
534 * to call this method at all; simply killing qemu is sufficient. But
535 * starting and stopping a trace is useful for examining a specific
536 * region of code.</p>
537 */
538 public static void stopNativeTracing() {
539 VMDebug.stopEmulatorTracing();
540
541 // Open the sysfs file for writing and write "0" to it.
542 PrintWriter outStream = null;
543 try {
544 FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700545 outStream = new FastPrintWriter(fos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546 outStream.println("0");
547 } catch (Exception e) {
548 // We could print an error message here but we probably want
549 // to quietly ignore errors if we are not running in the emulator.
550 } finally {
551 if (outStream != null)
552 outStream.close();
553 }
554 }
555
556 /**
557 * Enable "emulator traces", in which information about the current
558 * method is made available to the "emulator -trace" feature. There
559 * is no corresponding "disable" call -- this is intended for use by
560 * the framework when tracing should be turned on and left that way, so
561 * that traces captured with F9/F10 will include the necessary data.
562 *
563 * This puts the VM into "profile" mode, which has performance
564 * consequences.
565 *
566 * To temporarily enable tracing, use {@link #startNativeTracing()}.
567 */
568 public static void enableEmulatorTraceOutput() {
569 VMDebug.startEmulatorTracing();
570 }
571
572 /**
573 * Start method tracing with default log name and buffer size. See <a
574href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
575 * information about reading these files. Call stopMethodTracing() to stop
576 * tracing.
577 */
578 public static void startMethodTracing() {
Jeff Haod02e60f2014-01-06 15:52:52 -0800579 VMDebug.startMethodTracing(DEFAULT_TRACE_FILE_PATH, 0, 0, false, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800580 }
581
582 /**
583 * Start method tracing, specifying the trace log file name. The trace
584 * file will be put under "/sdcard" unless an absolute path is given.
585 * See <a
586 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
587 * information about reading trace files.
588 *
589 * @param traceName Name for the trace log file to create.
Jeff Haod02e60f2014-01-06 15:52:52 -0800590 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace".
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591 * If the files already exist, they will be truncated.
592 * If the trace file given does not end in ".trace", it will be appended for you.
593 */
594 public static void startMethodTracing(String traceName) {
595 startMethodTracing(traceName, 0, 0);
596 }
597
598 /**
599 * Start method tracing, specifying the trace log file name and the
600 * buffer size. The trace files will be put under "/sdcard" unless an
601 * absolute path is given. See <a
602 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
603 * information about reading trace files.
604 * @param traceName Name for the trace log file to create.
Jeff Haod02e60f2014-01-06 15:52:52 -0800605 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace".
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 * If the files already exist, they will be truncated.
607 * If the trace file given does not end in ".trace", it will be appended for you.
608 *
609 * @param bufferSize The maximum amount of trace data we gather. If not given, it defaults to 8MB.
610 */
611 public static void startMethodTracing(String traceName, int bufferSize) {
612 startMethodTracing(traceName, bufferSize, 0);
613 }
614
615 /**
616 * Start method tracing, specifying the trace log file name and the
617 * buffer size. The trace files will be put under "/sdcard" unless an
618 * absolute path is given. See <a
619 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
620 * information about reading trace files.
621 *
622 * <p>
623 * When method tracing is enabled, the VM will run more slowly than
624 * usual, so the timings from the trace files should only be considered
625 * in relative terms (e.g. was run #1 faster than run #2). The times
626 * for native methods will not change, so don't try to use this to
627 * compare the performance of interpreted and native implementations of the
Jeff Haod02e60f2014-01-06 15:52:52 -0800628 * same method. As an alternative, consider using sampling-based method
629 * tracing via {@link #startMethodTracingSampling(String, int, int)} or
630 * "native" tracing in the emulator via {@link #startNativeTracing()}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800631 * </p>
632 *
633 * @param traceName Name for the trace log file to create.
Jeff Haod02e60f2014-01-06 15:52:52 -0800634 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace".
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 * If the files already exist, they will be truncated.
636 * If the trace file given does not end in ".trace", it will be appended for you.
637 * @param bufferSize The maximum amount of trace data we gather. If not given, it defaults to 8MB.
Jeff Haod02e60f2014-01-06 15:52:52 -0800638 * @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 -0800639 */
640 public static void startMethodTracing(String traceName, int bufferSize,
641 int flags) {
Jeff Haod02e60f2014-01-06 15:52:52 -0800642 VMDebug.startMethodTracing(fixTraceName(traceName), bufferSize, flags, false, 0);
643 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800644
Jeff Haod02e60f2014-01-06 15:52:52 -0800645 /**
646 * Start sampling-based method tracing, specifying the trace log file name,
647 * the buffer size, and the sampling interval. The trace files will be put
648 * under "/sdcard" unless an absolute path is given. See <a
649 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a>
650 * for information about reading trace files.
651 *
652 * @param traceName Name for the trace log file to create.
653 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace".
654 * If the files already exist, they will be truncated.
655 * If the trace file given does not end in ".trace", it will be appended for you.
656 * @param bufferSize The maximum amount of trace data we gather. If not given, it defaults to 8MB.
657 * @param intervalUs The amount of time between each sample in microseconds.
658 */
659 public static void startMethodTracingSampling(String traceName,
660 int bufferSize, int intervalUs) {
661 VMDebug.startMethodTracing(fixTraceName(traceName), bufferSize, 0, true, intervalUs);
662 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800663
Jeff Haod02e60f2014-01-06 15:52:52 -0800664 /**
665 * Formats name of trace log file for method tracing.
666 */
667 private static String fixTraceName(String traceName) {
668 if (traceName == null)
669 traceName = DEFAULT_TRACE_FILE_PATH;
670 if (traceName.charAt(0) != '/')
671 traceName = DEFAULT_TRACE_PATH_PREFIX + traceName;
672 if (!traceName.endsWith(DEFAULT_TRACE_EXTENSION))
673 traceName = traceName + DEFAULT_TRACE_EXTENSION;
674
675 return traceName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800676 }
677
678 /**
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700679 * Like startMethodTracing(String, int, int), but taking an already-opened
680 * FileDescriptor in which the trace is written. The file name is also
681 * supplied simply for logging. Makes a dup of the file descriptor.
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200682 *
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700683 * Not exposed in the SDK unless we are really comfortable with supporting
684 * this and find it would be useful.
685 * @hide
686 */
687 public static void startMethodTracing(String traceName, FileDescriptor fd,
688 int bufferSize, int flags) {
Jeff Haod02e60f2014-01-06 15:52:52 -0800689 VMDebug.startMethodTracing(traceName, fd, bufferSize, flags, false, 0);
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700690 }
691
692 /**
Andy McFadden72a20db0c2010-01-22 12:20:41 -0800693 * Starts method tracing without a backing file. When stopMethodTracing
694 * is called, the result is sent directly to DDMS. (If DDMS is not
695 * attached when tracing ends, the profiling data will be discarded.)
696 *
697 * @hide
698 */
Jeff Hao7be3a132013-08-22 15:53:12 -0700699 public static void startMethodTracingDdms(int bufferSize, int flags,
700 boolean samplingEnabled, int intervalUs) {
701 VMDebug.startMethodTracingDdms(bufferSize, flags, samplingEnabled, intervalUs);
Andy McFadden72a20db0c2010-01-22 12:20:41 -0800702 }
703
704 /**
Jeff Haoac277052013-08-29 11:19:39 -0700705 * Determine whether method tracing is currently active and what type is
706 * active.
707 *
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -0700708 * @hide
709 */
Jeff Haoac277052013-08-29 11:19:39 -0700710 public static int getMethodTracingMode() {
711 return VMDebug.getMethodTracingMode();
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -0700712 }
713
714 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800715 * Stop method tracing.
716 */
717 public static void stopMethodTracing() {
718 VMDebug.stopMethodTracing();
719 }
720
721 /**
722 * Get an indication of thread CPU usage. The value returned
723 * indicates the amount of time that the current thread has spent
724 * executing code or waiting for certain types of I/O.
725 *
726 * The time is expressed in nanoseconds, and is only meaningful
727 * when compared to the result from an earlier call. Note that
728 * nanosecond resolution does not imply nanosecond accuracy.
729 *
730 * On system which don't support this operation, the call returns -1.
731 */
732 public static long threadCpuTimeNanos() {
733 return VMDebug.threadCpuTimeNanos();
734 }
735
736 /**
Chet Haase2970c492010-11-09 13:58:04 -0800737 * Start counting the number and aggregate size of memory allocations.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738 *
Ian Rogersfe067a42013-02-22 19:59:23 -0800739 * <p>The {@link #startAllocCounting() start} method resets the counts and enables counting.
740 * The {@link #stopAllocCounting() stop} method disables the counting so that the analysis
741 * code doesn't cause additional allocations. The various <code>get</code> methods return
742 * the specified value. And the various <code>reset</code> methods reset the specified
Chet Haase2970c492010-11-09 13:58:04 -0800743 * count.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744 *
Ian Rogersfe067a42013-02-22 19:59:23 -0800745 * <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 -0800746 * The per-thread counts for threads other than the current thread
Chet Haase2970c492010-11-09 13:58:04 -0800747 * are not cleared by the "reset" or "start" calls.</p>
Ian Rogersfe067a42013-02-22 19:59:23 -0800748 *
749 * @deprecated Accurate counting is a burden on the runtime and may be removed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800750 */
Ian Rogersfe067a42013-02-22 19:59:23 -0800751 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800752 public static void startAllocCounting() {
753 VMDebug.startAllocCounting();
754 }
Chet Haase2970c492010-11-09 13:58:04 -0800755
756 /**
757 * Stop counting the number and aggregate size of memory allocations.
758 *
759 * @see #startAllocCounting()
760 */
Ian Rogersc2a3adb2013-04-19 11:31:48 -0700761 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762 public static void stopAllocCounting() {
763 VMDebug.stopAllocCounting();
764 }
765
Ian Rogersfe067a42013-02-22 19:59:23 -0800766 /**
767 * Returns the global count of objects allocated by the runtime between a
768 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
769 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800770 public static int getGlobalAllocCount() {
771 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS);
772 }
Ian Rogersfe067a42013-02-22 19:59:23 -0800773
774 /**
775 * Clears the global count of objects allocated.
776 * @see #getGlobalAllocCount()
777 */
778 public static void resetGlobalAllocCount() {
779 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS);
780 }
781
782 /**
783 * Returns the global size, in bytes, of objects allocated by the runtime between a
784 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
785 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 public static int getGlobalAllocSize() {
787 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES);
788 }
Ian Rogersfe067a42013-02-22 19:59:23 -0800789
790 /**
791 * Clears the global size of objects allocated.
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700792 * @see #getGlobalAllocSize()
Ian Rogersfe067a42013-02-22 19:59:23 -0800793 */
794 public static void resetGlobalAllocSize() {
795 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES);
796 }
797
798 /**
799 * Returns the global count of objects freed by the runtime between a
800 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
801 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802 public static int getGlobalFreedCount() {
803 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS);
804 }
Ian Rogersfe067a42013-02-22 19:59:23 -0800805
806 /**
807 * Clears the global count of objects freed.
808 * @see #getGlobalFreedCount()
809 */
810 public static void resetGlobalFreedCount() {
811 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS);
812 }
813
814 /**
815 * Returns the global size, in bytes, of objects freed by the runtime between a
816 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
817 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800818 public static int getGlobalFreedSize() {
819 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES);
820 }
Ian Rogersfe067a42013-02-22 19:59:23 -0800821
822 /**
823 * Clears the global size of objects freed.
824 * @see #getGlobalFreedSize()
825 */
826 public static void resetGlobalFreedSize() {
827 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES);
828 }
829
830 /**
831 * Returns the number of non-concurrent GC invocations between a
832 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
833 */
834 public static int getGlobalGcInvocationCount() {
835 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS);
836 }
837
838 /**
839 * Clears the count of non-concurrent GC invocations.
840 * @see #getGlobalGcInvocationCount()
841 */
842 public static void resetGlobalGcInvocationCount() {
843 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS);
844 }
845
846 /**
847 * Returns the number of classes successfully initialized (ie those that executed without
848 * throwing an exception) between a {@link #startAllocCounting() start} and
849 * {@link #stopAllocCounting() stop}.
850 */
Andy McFaddenc4e1bf72010-02-22 17:07:36 -0800851 public static int getGlobalClassInitCount() {
Andy McFaddenc4e1bf72010-02-22 17:07:36 -0800852 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT);
853 }
Ian Rogersfe067a42013-02-22 19:59:23 -0800854
855 /**
856 * Clears the count of classes initialized.
857 * @see #getGlobalClassInitCount()
858 */
859 public static void resetGlobalClassInitCount() {
860 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT);
861 }
862
863 /**
864 * Returns the time spent successfully initializing classes between a
865 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
866 */
Andy McFaddenc4e1bf72010-02-22 17:07:36 -0800867 public static int getGlobalClassInitTime() {
868 /* cumulative elapsed time for class initialization, in usec */
869 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME);
870 }
Carl Shapirob5961982010-12-22 15:54:53 -0800871
872 /**
Ian Rogersfe067a42013-02-22 19:59:23 -0800873 * Clears the count of time spent initializing classes.
874 * @see #getGlobalClassInitTime()
875 */
876 public static void resetGlobalClassInitTime() {
877 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME);
878 }
879
880 /**
Carl Shapiro7e942842011-01-12 17:17:45 -0800881 * This method exists for compatibility and always returns 0.
Carl Shapirob5961982010-12-22 15:54:53 -0800882 * @deprecated This method is now obsolete.
883 */
884 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885 public static int getGlobalExternalAllocCount() {
Carl Shapirob5961982010-12-22 15:54:53 -0800886 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 }
Carl Shapirob5961982010-12-22 15:54:53 -0800888
889 /**
Ian Rogersfe067a42013-02-22 19:59:23 -0800890 * This method exists for compatibility and has no effect.
891 * @deprecated This method is now obsolete.
892 */
893 @Deprecated
894 public static void resetGlobalExternalAllocSize() {}
895
896 /**
897 * This method exists for compatibility and has no effect.
898 * @deprecated This method is now obsolete.
899 */
900 @Deprecated
901 public static void resetGlobalExternalAllocCount() {}
902
903 /**
Carl Shapiro7e942842011-01-12 17:17:45 -0800904 * This method exists for compatibility and always returns 0.
Carl Shapirob5961982010-12-22 15:54:53 -0800905 * @deprecated This method is now obsolete.
906 */
907 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800908 public static int getGlobalExternalAllocSize() {
Carl Shapirob5961982010-12-22 15:54:53 -0800909 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910 }
Carl Shapirob5961982010-12-22 15:54:53 -0800911
912 /**
Ian Rogersfe067a42013-02-22 19:59:23 -0800913 * This method exists for compatibility and always returns 0.
Carl Shapirob5961982010-12-22 15:54:53 -0800914 * @deprecated This method is now obsolete.
915 */
916 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917 public static int getGlobalExternalFreedCount() {
Carl Shapirob5961982010-12-22 15:54:53 -0800918 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 }
Carl Shapirob5961982010-12-22 15:54:53 -0800920
921 /**
Ian Rogersfe067a42013-02-22 19:59:23 -0800922 * This method exists for compatibility and has no effect.
923 * @deprecated This method is now obsolete.
924 */
925 @Deprecated
926 public static void resetGlobalExternalFreedCount() {}
927
928 /**
929 * This method exists for compatibility and has no effect.
Carl Shapirob5961982010-12-22 15:54:53 -0800930 * @deprecated This method is now obsolete.
931 */
932 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 public static int getGlobalExternalFreedSize() {
Carl Shapirob5961982010-12-22 15:54:53 -0800934 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 }
Carl Shapirob5961982010-12-22 15:54:53 -0800936
Ian Rogersfe067a42013-02-22 19:59:23 -0800937 /**
938 * This method exists for compatibility and has no effect.
939 * @deprecated This method is now obsolete.
940 */
941 @Deprecated
942 public static void resetGlobalExternalFreedSize() {}
943
944 /**
945 * Returns the thread-local count of objects allocated by the runtime between a
946 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
947 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 public static int getThreadAllocCount() {
949 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS);
950 }
Ian Rogersfe067a42013-02-22 19:59:23 -0800951
952 /**
953 * Clears the thread-local count of objects allocated.
954 * @see #getThreadAllocCount()
955 */
956 public static void resetThreadAllocCount() {
957 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS);
958 }
959
960 /**
961 * Returns the thread-local size of objects allocated by the runtime between a
962 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
963 * @return The allocated size in bytes.
964 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800965 public static int getThreadAllocSize() {
966 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES);
967 }
Carl Shapirob5961982010-12-22 15:54:53 -0800968
969 /**
Ian Rogersfe067a42013-02-22 19:59:23 -0800970 * Clears the thread-local count of objects allocated.
971 * @see #getThreadAllocSize()
972 */
973 public static void resetThreadAllocSize() {
974 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES);
975 }
976
977 /**
978 * This method exists for compatibility and has no effect.
Carl Shapirob5961982010-12-22 15:54:53 -0800979 * @deprecated This method is now obsolete.
980 */
981 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 public static int getThreadExternalAllocCount() {
Carl Shapirob5961982010-12-22 15:54:53 -0800983 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 }
Carl Shapirob5961982010-12-22 15:54:53 -0800985
986 /**
Ian Rogersfe067a42013-02-22 19:59:23 -0800987 * This method exists for compatibility and has no effect.
988 * @deprecated This method is now obsolete.
989 */
990 @Deprecated
991 public static void resetThreadExternalAllocCount() {}
992
993 /**
994 * This method exists for compatibility and has no effect.
Carl Shapirob5961982010-12-22 15:54:53 -0800995 * @deprecated This method is now obsolete.
996 */
997 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800998 public static int getThreadExternalAllocSize() {
Carl Shapirob5961982010-12-22 15:54:53 -0800999 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 }
Carl Shapirob5961982010-12-22 15:54:53 -08001001
Carl Shapirob5961982010-12-22 15:54:53 -08001002 /**
Carl Shapiro7e942842011-01-12 17:17:45 -08001003 * This method exists for compatibility and has no effect.
Carl Shapirob5961982010-12-22 15:54:53 -08001004 * @deprecated This method is now obsolete.
1005 */
1006 @Deprecated
1007 public static void resetThreadExternalAllocSize() {}
1008
Ian Rogersfe067a42013-02-22 19:59:23 -08001009 /**
1010 * Returns the number of thread-local non-concurrent GC invocations between a
1011 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
1012 */
1013 public static int getThreadGcInvocationCount() {
1014 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS);
1015 }
1016
1017 /**
1018 * Clears the thread-local count of non-concurrent GC invocations.
1019 * @see #getThreadGcInvocationCount()
1020 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001021 public static void resetThreadGcInvocationCount() {
1022 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS);
1023 }
Ian Rogersfe067a42013-02-22 19:59:23 -08001024
1025 /**
1026 * Clears all the global and thread-local memory allocation counters.
1027 * @see #startAllocCounting()
1028 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001029 public static void resetAllCounts() {
1030 VMDebug.resetAllocCount(VMDebug.KIND_ALL_COUNTS);
1031 }
1032
1033 /**
1034 * Returns the size of the native heap.
1035 * @return The size of the native heap in bytes.
1036 */
1037 public static native long getNativeHeapSize();
1038
1039 /**
1040 * Returns the amount of allocated memory in the native heap.
1041 * @return The allocated size in bytes.
1042 */
1043 public static native long getNativeHeapAllocatedSize();
1044
1045 /**
1046 * Returns the amount of free memory in the native heap.
1047 * @return The freed size in bytes.
1048 */
1049 public static native long getNativeHeapFreeSize();
1050
1051 /**
1052 * Retrieves information about this processes memory usages. This information is broken down by
1053 * how much is in use by dalivk, the native heap, and everything else.
1054 */
1055 public static native void getMemoryInfo(MemoryInfo memoryInfo);
1056
1057 /**
Dianne Hackborn3025ef32009-08-31 21:31:47 -07001058 * Note: currently only works when the requested pid has the same UID
1059 * as the caller.
1060 * @hide
1061 */
1062 public static native void getMemoryInfo(int pid, MemoryInfo memoryInfo);
1063
1064 /**
Dianne Hackbornb437e092011-08-05 17:50:29 -07001065 * Retrieves the PSS memory used by the process as given by the
1066 * smaps.
1067 */
1068 public static native long getPss();
1069
1070 /**
1071 * Retrieves the PSS memory used by the process as given by the
Dianne Hackbornc8230512013-07-13 21:32:12 -07001072 * smaps. Optionally supply a long array of 1 entry to also
1073 * receive the uss of the process. @hide
Dianne Hackbornb437e092011-08-05 17:50:29 -07001074 */
Dianne Hackbornc8230512013-07-13 21:32:12 -07001075 public static native long getPss(int pid, long[] outUss);
Dianne Hackbornb437e092011-08-05 17:50:29 -07001076
Dianne Hackborn8e692572013-09-10 19:06:15 -07001077 /** @hide */
1078 public static final int MEMINFO_TOTAL = 0;
1079 /** @hide */
1080 public static final int MEMINFO_FREE = 1;
1081 /** @hide */
1082 public static final int MEMINFO_BUFFERS = 2;
1083 /** @hide */
1084 public static final int MEMINFO_CACHED = 3;
1085 /** @hide */
1086 public static final int MEMINFO_SHMEM = 4;
1087 /** @hide */
1088 public static final int MEMINFO_SLAB = 5;
1089 /** @hide */
Dianne Hackborncbd9a522013-09-24 23:10:14 -07001090 public static final int MEMINFO_SWAP_TOTAL = 6;
1091 /** @hide */
1092 public static final int MEMINFO_SWAP_FREE = 7;
1093 /** @hide */
1094 public static final int MEMINFO_ZRAM_TOTAL = 8;
1095 /** @hide */
1096 public static final int MEMINFO_COUNT = 9;
Dianne Hackborn8e692572013-09-10 19:06:15 -07001097
1098 /**
1099 * Retrieves /proc/meminfo. outSizes is filled with fields
1100 * as defined by MEMINFO_* offsets.
1101 * @hide
1102 */
1103 public static native void getMemInfo(long[] outSizes);
1104
Dianne Hackbornb437e092011-08-05 17:50:29 -07001105 /**
Carl Shapiro11073832011-01-12 16:28:57 -08001106 * Establish an object allocation limit in the current thread.
Carl Shapiro7e942842011-01-12 17:17:45 -08001107 * This feature was never enabled in release builds. The
1108 * allocation limits feature was removed in Honeycomb. This
1109 * method exists for compatibility and always returns -1 and has
1110 * no effect.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001111 *
Carl Shapiro11073832011-01-12 16:28:57 -08001112 * @deprecated This method is now obsolete.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 */
Carl Shapiro11073832011-01-12 16:28:57 -08001114 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001115 public static int setAllocationLimit(int limit) {
Carl Shapiro11073832011-01-12 16:28:57 -08001116 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 }
1118
1119 /**
Carl Shapiro11073832011-01-12 16:28:57 -08001120 * Establish a global object allocation limit. This feature was
Carl Shapiro7e942842011-01-12 17:17:45 -08001121 * never enabled in release builds. The allocation limits feature
1122 * was removed in Honeycomb. This method exists for compatibility
1123 * and always returns -1 and has no effect.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001124 *
Carl Shapiro11073832011-01-12 16:28:57 -08001125 * @deprecated This method is now obsolete.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001126 */
Carl Shapiro11073832011-01-12 16:28:57 -08001127 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001128 public static int setGlobalAllocationLimit(int limit) {
Carl Shapiro11073832011-01-12 16:28:57 -08001129 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001130 }
1131
1132 /**
1133 * Dump a list of all currently loaded class to the log file.
1134 *
1135 * @param flags See constants above.
1136 */
1137 public static void printLoadedClasses(int flags) {
1138 VMDebug.printLoadedClasses(flags);
1139 }
1140
1141 /**
1142 * Get the number of loaded classes.
1143 * @return the number of loaded classes.
1144 */
1145 public static int getLoadedClassCount() {
1146 return VMDebug.getLoadedClassCount();
1147 }
1148
1149 /**
Andy McFadden824c5102010-07-09 16:26:57 -07001150 * Dump "hprof" data to the specified file. This may cause a GC.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001151 *
1152 * @param fileName Full pathname of output file (e.g. "/sdcard/dump.hprof").
1153 * @throws UnsupportedOperationException if the VM was built without
1154 * HPROF support.
1155 * @throws IOException if an error occurs while opening or writing files.
1156 */
1157 public static void dumpHprofData(String fileName) throws IOException {
1158 VMDebug.dumpHprofData(fileName);
1159 }
1160
1161 /**
Andy McFadden824c5102010-07-09 16:26:57 -07001162 * Like dumpHprofData(String), but takes an already-opened
1163 * FileDescriptor to which the trace is written. The file name is also
1164 * supplied simply for logging. Makes a dup of the file descriptor.
1165 *
1166 * Primarily for use by the "am" shell command.
1167 *
1168 * @hide
1169 */
1170 public static void dumpHprofData(String fileName, FileDescriptor fd)
1171 throws IOException {
1172 VMDebug.dumpHprofData(fileName, fd);
1173 }
1174
1175 /**
1176 * Collect "hprof" and send it to DDMS. This may cause a GC.
Andy McFadden07a96612010-01-28 16:54:37 -08001177 *
1178 * @throws UnsupportedOperationException if the VM was built without
1179 * HPROF support.
Andy McFadden07a96612010-01-28 16:54:37 -08001180 * @hide
1181 */
1182 public static void dumpHprofDataDdms() {
1183 VMDebug.dumpHprofDataDdms();
1184 }
1185
1186 /**
Andy McFadden06a6b552010-07-13 16:28:09 -07001187 * Writes native heap data to the specified file descriptor.
1188 *
1189 * @hide
1190 */
1191 public static native void dumpNativeHeap(FileDescriptor fd);
1192
1193 /**
Brian Carlstromc21550a2010-10-05 21:34:06 -07001194 * Returns a count of the extant instances of a class.
1195 *
1196 * @hide
1197 */
1198 public static long countInstancesOfClass(Class cls) {
Brian Carlstrom7495cfa2010-11-30 18:06:00 -08001199 return VMDebug.countInstancesOfClass(cls, true);
Brian Carlstromc21550a2010-10-05 21:34:06 -07001200 }
1201
1202 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001203 * Returns the number of sent transactions from this process.
1204 * @return The number of sent transactions or -1 if it could not read t.
1205 */
1206 public static native int getBinderSentTransactions();
1207
1208 /**
1209 * Returns the number of received transactions from the binder driver.
1210 * @return The number of received transactions or -1 if it could not read the stats.
1211 */
1212 public static native int getBinderReceivedTransactions();
1213
1214 /**
1215 * Returns the number of active local Binder objects that exist in the
1216 * current process.
1217 */
1218 public static final native int getBinderLocalObjectCount();
1219
1220 /**
1221 * Returns the number of references to remote proxy Binder objects that
1222 * exist in the current process.
1223 */
1224 public static final native int getBinderProxyObjectCount();
1225
1226 /**
1227 * Returns the number of death notification links to Binder objects that
1228 * exist in the current process.
1229 */
1230 public static final native int getBinderDeathObjectCount();
1231
1232 /**
Andy McFadden599c9182009-04-08 00:35:56 -07001233 * Primes the register map cache.
1234 *
1235 * Only works for classes in the bootstrap class loader. Does not
1236 * cause classes to be loaded if they're not already present.
1237 *
1238 * The classAndMethodDesc argument is a concatentation of the VM-internal
1239 * class descriptor, method name, and method descriptor. Examples:
1240 * Landroid/os/Looper;.loop:()V
1241 * Landroid/app/ActivityThread;.main:([Ljava/lang/String;)V
1242 *
1243 * @param classAndMethodDesc the method to prepare
1244 *
1245 * @hide
1246 */
1247 public static final boolean cacheRegisterMap(String classAndMethodDesc) {
1248 return VMDebug.cacheRegisterMap(classAndMethodDesc);
1249 }
1250
1251 /**
Andy McFaddenbfd6d482009-10-22 17:25:57 -07001252 * Dumps the contents of VM reference tables (e.g. JNI locals and
1253 * globals) to the log file.
1254 *
1255 * @hide
1256 */
1257 public static final void dumpReferenceTables() {
1258 VMDebug.dumpReferenceTables();
1259 }
1260
1261 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001262 * API for gathering and querying instruction counts.
1263 *
1264 * Example usage:
Chet Haase2970c492010-11-09 13:58:04 -08001265 * <pre>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266 * Debug.InstructionCount icount = new Debug.InstructionCount();
1267 * icount.resetAndStart();
1268 * [... do lots of stuff ...]
1269 * if (icount.collect()) {
1270 * System.out.println("Total instructions executed: "
1271 * + icount.globalTotal());
1272 * System.out.println("Method invocations: "
1273 * + icount.globalMethodInvocations());
1274 * }
Chet Haase2970c492010-11-09 13:58:04 -08001275 * </pre>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001276 */
1277 public static class InstructionCount {
Dan Bornsteinb96f5892010-12-02 17:19:53 -08001278 private static final int NUM_INSTR =
1279 OpcodeInfo.MAXIMUM_PACKED_VALUE + 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001280
1281 private int[] mCounts;
1282
1283 public InstructionCount() {
1284 mCounts = new int[NUM_INSTR];
1285 }
1286
1287 /**
1288 * Reset counters and ensure counts are running. Counts may
1289 * have already been running.
1290 *
1291 * @return true if counting was started
1292 */
1293 public boolean resetAndStart() {
1294 try {
1295 VMDebug.startInstructionCounting();
1296 VMDebug.resetInstructionCount();
1297 } catch (UnsupportedOperationException uoe) {
1298 return false;
1299 }
1300 return true;
1301 }
1302
1303 /**
1304 * Collect instruction counts. May or may not stop the
1305 * counting process.
1306 */
1307 public boolean collect() {
1308 try {
1309 VMDebug.stopInstructionCounting();
1310 VMDebug.getInstructionCount(mCounts);
1311 } catch (UnsupportedOperationException uoe) {
1312 return false;
1313 }
1314 return true;
1315 }
1316
1317 /**
1318 * Return the total number of instructions executed globally (i.e. in
1319 * all threads).
1320 */
1321 public int globalTotal() {
1322 int count = 0;
Dan Bornstein1d99b062010-11-30 12:26:52 -08001323
1324 for (int i = 0; i < NUM_INSTR; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001325 count += mCounts[i];
Dan Bornstein1d99b062010-11-30 12:26:52 -08001326 }
1327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001328 return count;
1329 }
1330
1331 /**
1332 * Return the total number of method-invocation instructions
1333 * executed globally.
1334 */
1335 public int globalMethodInvocations() {
1336 int count = 0;
1337
Dan Bornstein1d99b062010-11-30 12:26:52 -08001338 for (int i = 0; i < NUM_INSTR; i++) {
1339 if (OpcodeInfo.isInvoke(i)) {
1340 count += mCounts[i];
1341 }
1342 }
1343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001344 return count;
1345 }
Dave Bort1ce5bd32009-04-22 17:36:56 -07001346 }
1347
Dave Bort1ce5bd32009-04-22 17:36:56 -07001348 /**
1349 * A Map of typed debug properties.
1350 */
1351 private static final TypedProperties debugProperties;
1352
1353 /*
1354 * Load the debug properties from the standard files into debugProperties.
1355 */
1356 static {
Joe Onorato43a17652011-04-06 19:22:23 -07001357 if (false) {
Dave Bort1ce5bd32009-04-22 17:36:56 -07001358 final String TAG = "DebugProperties";
1359 final String[] files = { "/system/debug.prop", "/debug.prop", "/data/debug.prop" };
1360 final TypedProperties tp = new TypedProperties();
1361
1362 // Read the properties from each of the files, if present.
Dave Borte9bfd9b2009-05-04 14:35:23 -07001363 for (String file : files) {
Dave Bort1ce5bd32009-04-22 17:36:56 -07001364 Reader r;
1365 try {
1366 r = new FileReader(file);
1367 } catch (FileNotFoundException ex) {
1368 // It's ok if a file is missing.
1369 continue;
1370 }
1371
Dave Bort1ce5bd32009-04-22 17:36:56 -07001372 try {
1373 tp.load(r);
Dave Borte9bfd9b2009-05-04 14:35:23 -07001374 } catch (Exception ex) {
1375 throw new RuntimeException("Problem loading " + file, ex);
1376 } finally {
1377 try {
1378 r.close();
1379 } catch (IOException ex) {
1380 // Ignore this error.
1381 }
Dave Bort1ce5bd32009-04-22 17:36:56 -07001382 }
1383 }
1384
1385 debugProperties = tp.isEmpty() ? null : tp;
1386 } else {
1387 debugProperties = null;
1388 }
1389 }
1390
1391
1392 /**
1393 * Returns true if the type of the field matches the specified class.
1394 * Handles the case where the class is, e.g., java.lang.Boolean, but
1395 * the field is of the primitive "boolean" type. Also handles all of
1396 * the java.lang.Number subclasses.
1397 */
1398 private static boolean fieldTypeMatches(Field field, Class<?> cl) {
1399 Class<?> fieldClass = field.getType();
1400 if (fieldClass == cl) {
1401 return true;
1402 }
1403 Field primitiveTypeField;
1404 try {
1405 /* All of the classes we care about (Boolean, Integer, etc.)
1406 * have a Class field called "TYPE" that points to the corresponding
1407 * primitive class.
1408 */
1409 primitiveTypeField = cl.getField("TYPE");
1410 } catch (NoSuchFieldException ex) {
1411 return false;
1412 }
1413 try {
Dave Borte9bfd9b2009-05-04 14:35:23 -07001414 return fieldClass == (Class<?>) primitiveTypeField.get(null);
Dave Bort1ce5bd32009-04-22 17:36:56 -07001415 } catch (IllegalAccessException ex) {
1416 return false;
1417 }
1418 }
1419
1420
1421 /**
1422 * Looks up the property that corresponds to the field, and sets the field's value
1423 * if the types match.
1424 */
Dave Borte9bfd9b2009-05-04 14:35:23 -07001425 private static void modifyFieldIfSet(final Field field, final TypedProperties properties,
1426 final String propertyName) {
Dave Bort1ce5bd32009-04-22 17:36:56 -07001427 if (field.getType() == java.lang.String.class) {
Dave Borte9bfd9b2009-05-04 14:35:23 -07001428 int stringInfo = properties.getStringInfo(propertyName);
Dave Bort1ce5bd32009-04-22 17:36:56 -07001429 switch (stringInfo) {
Dave Borte9bfd9b2009-05-04 14:35:23 -07001430 case TypedProperties.STRING_SET:
1431 // Handle as usual below.
1432 break;
1433 case TypedProperties.STRING_NULL:
1434 try {
1435 field.set(null, null); // null object for static fields; null string
1436 } catch (IllegalAccessException ex) {
1437 throw new IllegalArgumentException(
1438 "Cannot set field for " + propertyName, ex);
1439 }
1440 return;
1441 case TypedProperties.STRING_NOT_SET:
1442 return;
1443 case TypedProperties.STRING_TYPE_MISMATCH:
Dave Bort1ce5bd32009-04-22 17:36:56 -07001444 throw new IllegalArgumentException(
Dave Borte9bfd9b2009-05-04 14:35:23 -07001445 "Type of " + propertyName + " " +
1446 " does not match field type (" + field.getType() + ")");
1447 default:
1448 throw new IllegalStateException(
1449 "Unexpected getStringInfo(" + propertyName + ") return value " +
1450 stringInfo);
Dave Bort1ce5bd32009-04-22 17:36:56 -07001451 }
1452 }
Dave Borte9bfd9b2009-05-04 14:35:23 -07001453 Object value = properties.get(propertyName);
Dave Bort1ce5bd32009-04-22 17:36:56 -07001454 if (value != null) {
1455 if (!fieldTypeMatches(field, value.getClass())) {
1456 throw new IllegalArgumentException(
1457 "Type of " + propertyName + " (" + value.getClass() + ") " +
1458 " does not match field type (" + field.getType() + ")");
1459 }
1460 try {
1461 field.set(null, value); // null object for static fields
1462 } catch (IllegalAccessException ex) {
1463 throw new IllegalArgumentException(
1464 "Cannot set field for " + propertyName, ex);
1465 }
1466 }
1467 }
1468
1469
1470 /**
Romain Guyc4b11a72009-05-13 15:46:37 -07001471 * Equivalent to <code>setFieldsOn(cl, false)</code>.
1472 *
1473 * @see #setFieldsOn(Class, boolean)
Romain Guyd4103d02009-05-14 12:24:21 -07001474 *
1475 * @hide
Romain Guyc4b11a72009-05-13 15:46:37 -07001476 */
1477 public static void setFieldsOn(Class<?> cl) {
1478 setFieldsOn(cl, false);
1479 }
1480
1481 /**
Dave Bort1ce5bd32009-04-22 17:36:56 -07001482 * Reflectively sets static fields of a class based on internal debugging
Joe Onorato43a17652011-04-06 19:22:23 -07001483 * properties. This method is a no-op if false is
Dave Bort1ce5bd32009-04-22 17:36:56 -07001484 * false.
1485 * <p>
Joe Onorato43a17652011-04-06 19:22:23 -07001486 * <strong>NOTE TO APPLICATION DEVELOPERS</strong>: false will
Dave Bort1ce5bd32009-04-22 17:36:56 -07001487 * always be false in release builds. This API is typically only useful
1488 * for platform developers.
1489 * </p>
1490 * Class setup: define a class whose only fields are non-final, static
1491 * primitive types (except for "char") or Strings. In a static block
1492 * after the field definitions/initializations, pass the class to
Romain Guyc4b11a72009-05-13 15:46:37 -07001493 * this method, Debug.setFieldsOn(). Example:
Dave Bort1ce5bd32009-04-22 17:36:56 -07001494 * <pre>
1495 * package com.example;
1496 *
1497 * import android.os.Debug;
1498 *
1499 * public class MyDebugVars {
1500 * public static String s = "a string";
1501 * public static String s2 = "second string";
1502 * public static String ns = null;
1503 * public static boolean b = false;
1504 * public static int i = 5;
Romain Guyc4b11a72009-05-13 15:46:37 -07001505 * @Debug.DebugProperty
Dave Bort1ce5bd32009-04-22 17:36:56 -07001506 * public static float f = 0.1f;
Romain Guyc4b11a72009-05-13 15:46:37 -07001507 * @@Debug.DebugProperty
Dave Bort1ce5bd32009-04-22 17:36:56 -07001508 * public static double d = 0.5d;
1509 *
1510 * // This MUST appear AFTER all fields are defined and initialized!
1511 * static {
Romain Guyc4b11a72009-05-13 15:46:37 -07001512 * // Sets all the fields
Dave Borte9bfd9b2009-05-04 14:35:23 -07001513 * Debug.setFieldsOn(MyDebugVars.class);
Christian Mehlmauer798e2d32010-06-17 18:24:07 +02001514 *
Romain Guyc4b11a72009-05-13 15:46:37 -07001515 * // Sets only the fields annotated with @Debug.DebugProperty
1516 * // Debug.setFieldsOn(MyDebugVars.class, true);
Dave Bort1ce5bd32009-04-22 17:36:56 -07001517 * }
1518 * }
1519 * </pre>
Dave Borte9bfd9b2009-05-04 14:35:23 -07001520 * setFieldsOn() may override the value of any field in the class based
Dave Bort1ce5bd32009-04-22 17:36:56 -07001521 * on internal properties that are fixed at boot time.
1522 * <p>
1523 * These properties are only set during platform debugging, and are not
1524 * meant to be used as a general-purpose properties store.
1525 *
1526 * {@hide}
1527 *
1528 * @param cl The class to (possibly) modify
Romain Guyc4b11a72009-05-13 15:46:37 -07001529 * @param partial If false, sets all static fields, otherwise, only set
1530 * fields with the {@link android.os.Debug.DebugProperty}
1531 * annotation
Dave Bort1ce5bd32009-04-22 17:36:56 -07001532 * @throws IllegalArgumentException if any fields are final or non-static,
1533 * or if the type of the field does not match the type of
1534 * the internal debugging property value.
1535 */
Romain Guyc4b11a72009-05-13 15:46:37 -07001536 public static void setFieldsOn(Class<?> cl, boolean partial) {
Joe Onorato43a17652011-04-06 19:22:23 -07001537 if (false) {
Dave Bort1ce5bd32009-04-22 17:36:56 -07001538 if (debugProperties != null) {
1539 /* Only look for fields declared directly by the class,
1540 * so we don't mysteriously change static fields in superclasses.
1541 */
1542 for (Field field : cl.getDeclaredFields()) {
Romain Guyc4b11a72009-05-13 15:46:37 -07001543 if (!partial || field.getAnnotation(DebugProperty.class) != null) {
1544 final String propertyName = cl.getName() + "." + field.getName();
1545 boolean isStatic = Modifier.isStatic(field.getModifiers());
1546 boolean isFinal = Modifier.isFinal(field.getModifiers());
1547
1548 if (!isStatic || isFinal) {
1549 throw new IllegalArgumentException(propertyName +
1550 " must be static and non-final");
1551 }
1552 modifyFieldIfSet(field, debugProperties, propertyName);
Dave Bort1ce5bd32009-04-22 17:36:56 -07001553 }
Dave Bort1ce5bd32009-04-22 17:36:56 -07001554 }
1555 }
1556 } else {
Dan Egnor3eda9792010-03-05 13:28:36 -08001557 Log.wtf(TAG,
Dave Borte9bfd9b2009-05-04 14:35:23 -07001558 "setFieldsOn(" + (cl == null ? "null" : cl.getName()) +
Dave Bort1ce5bd32009-04-22 17:36:56 -07001559 ") called in non-DEBUG build");
1560 }
1561 }
Romain Guyc4b11a72009-05-13 15:46:37 -07001562
1563 /**
1564 * Annotation to put on fields you want to set with
1565 * {@link Debug#setFieldsOn(Class, boolean)}.
1566 *
1567 * @hide
1568 */
1569 @Target({ ElementType.FIELD })
1570 @Retention(RetentionPolicy.RUNTIME)
1571 public @interface DebugProperty {
1572 }
Dan Egnor3eda9792010-03-05 13:28:36 -08001573
1574 /**
1575 * Get a debugging dump of a system service by name.
1576 *
1577 * <p>Most services require the caller to hold android.permission.DUMP.
1578 *
1579 * @param name of the service to dump
1580 * @param fd to write dump output to (usually an output log file)
1581 * @param args to pass to the service's dump method, may be null
1582 * @return true if the service was dumped successfully, false if
1583 * the service could not be found or had an error while dumping
1584 */
1585 public static boolean dumpService(String name, FileDescriptor fd, String[] args) {
1586 IBinder service = ServiceManager.getService(name);
1587 if (service == null) {
1588 Log.e(TAG, "Can't find service to dump: " + name);
1589 return false;
1590 }
1591
1592 try {
1593 service.dump(fd, args);
1594 return true;
1595 } catch (RemoteException e) {
1596 Log.e(TAG, "Can't dump service: " + name, e);
1597 return false;
1598 }
1599 }
Craig Mautnera51a9562012-04-17 17:05:26 -07001600
1601 /**
Dianne Hackbornf72467a2012-06-08 17:23:59 -07001602 * Have the stack traces of the given native process dumped to the
1603 * specified file. Will be appended to the file.
1604 * @hide
1605 */
1606 public static native void dumpNativeBacktraceToFile(int pid, String file);
1607
1608 /**
Craig Mautnera51a9562012-04-17 17:05:26 -07001609 * Return a String describing the calling method and location at a particular stack depth.
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -07001610 * @param callStack the Thread stack
Craig Mautnera51a9562012-04-17 17:05:26 -07001611 * @param depth the depth of stack to return information for.
1612 * @return the String describing the caller at that depth.
1613 */
1614 private static String getCaller(StackTraceElement callStack[], int depth) {
1615 // callStack[4] is the caller of the method that called getCallers()
1616 if (4 + depth >= callStack.length) {
1617 return "<bottom of call stack>";
1618 }
1619 StackTraceElement caller = callStack[4 + depth];
1620 return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber();
1621 }
1622
1623 /**
1624 * Return a string consisting of methods and locations at multiple call stack levels.
1625 * @param depth the number of levels to return, starting with the immediate caller.
1626 * @return a string describing the call stack.
1627 * {@hide}
1628 */
1629 public static String getCallers(final int depth) {
1630 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
1631 StringBuffer sb = new StringBuffer();
1632 for (int i = 0; i < depth; i++) {
1633 sb.append(getCaller(callStack, i)).append(" ");
1634 }
1635 return sb.toString();
1636 }
1637
1638 /**
Dianne Hackbornfd6c7b12013-10-03 10:42:26 -07001639 * Return a string consisting of methods and locations at multiple call stack levels.
1640 * @param depth the number of levels to return, starting with the immediate caller.
1641 * @return a string describing the call stack.
1642 * {@hide}
1643 */
1644 public static String getCallers(final int start, int depth) {
1645 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
1646 StringBuffer sb = new StringBuffer();
1647 depth += start;
1648 for (int i = start; i < depth; i++) {
1649 sb.append(getCaller(callStack, i)).append(" ");
1650 }
1651 return sb.toString();
1652 }
1653
1654 /**
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001655 * Like {@link #getCallers(int)}, but each location is append to the string
1656 * as a new line with <var>linePrefix</var> in front of it.
1657 * @param depth the number of levels to return, starting with the immediate caller.
1658 * @param linePrefix prefix to put in front of each location.
1659 * @return a string describing the call stack.
1660 * {@hide}
1661 */
1662 public static String getCallers(final int depth, String linePrefix) {
1663 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
1664 StringBuffer sb = new StringBuffer();
1665 for (int i = 0; i < depth; i++) {
1666 sb.append(linePrefix).append(getCaller(callStack, i)).append("\n");
1667 }
1668 return sb.toString();
1669 }
1670
1671 /**
Ian Rogersfe067a42013-02-22 19:59:23 -08001672 * @return a String describing the immediate caller of the calling method.
Craig Mautnera51a9562012-04-17 17:05:26 -07001673 * {@hide}
1674 */
1675 public static String getCaller() {
1676 return getCaller(Thread.currentThread().getStackTrace(), 0);
1677 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678}