VMDebug.java revision 2e386d4b586dba464ec59be93c0720b6b973ab96
1/*
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 dalvik.system;
18
19import java.io.FileDescriptor;
20import java.io.IOException;
21
22/**
23 * Provides access to some VM-specific debug features. Though this class and
24 * many of its members are public, this class is meant to be wrapped in a more
25 * friendly way for use by application developers. On the Android platform, the
26 * recommended way to access this functionality is through the class
27 * <code>android.os.Debug</code>.
28 *
29 * @cts Please complete the spec.
30 *
31 * @hide
32 */
33public final class VMDebug {
34    /**
35     * Specifies the default method trace data file name.
36     *
37     * @deprecated only used in one place, which is unused and deprecated
38     */
39    static public final String DEFAULT_METHOD_TRACE_FILE_NAME = "/sdcard/dmtrace.trace";
40
41    /**
42     * flag for startMethodTracing(), which adds the results from
43     * startAllocCounting to the trace key file.
44     */
45    public static final int TRACE_COUNT_ALLOCS = 1;
46
47    /* constants for getAllocCount */
48    private static final int KIND_ALLOCATED_OBJECTS     = 1<<0;
49    private static final int KIND_ALLOCATED_BYTES       = 1<<1;
50    private static final int KIND_FREED_OBJECTS         = 1<<2;
51    private static final int KIND_FREED_BYTES           = 1<<3;
52    private static final int KIND_GC_INVOCATIONS        = 1<<4;
53    private static final int KIND_CLASS_INIT_COUNT      = 1<<5;
54    private static final int KIND_CLASS_INIT_TIME       = 1<<6;
55    private static final int KIND_EXT_ALLOCATED_OBJECTS = 1<<12;
56    private static final int KIND_EXT_ALLOCATED_BYTES   = 1<<13;
57    private static final int KIND_EXT_FREED_OBJECTS     = 1<<14;
58    private static final int KIND_EXT_FREED_BYTES       = 1<<15;
59
60    public static final int KIND_GLOBAL_ALLOCATED_OBJECTS =
61        KIND_ALLOCATED_OBJECTS;
62    public static final int KIND_GLOBAL_ALLOCATED_BYTES =
63        KIND_ALLOCATED_BYTES;
64    public static final int KIND_GLOBAL_FREED_OBJECTS =
65        KIND_FREED_OBJECTS;
66    public static final int KIND_GLOBAL_FREED_BYTES =
67        KIND_FREED_BYTES;
68    public static final int KIND_GLOBAL_GC_INVOCATIONS =
69        KIND_GC_INVOCATIONS;
70    public static final int KIND_GLOBAL_CLASS_INIT_COUNT =
71        KIND_CLASS_INIT_COUNT;
72    public static final int KIND_GLOBAL_CLASS_INIT_TIME =
73        KIND_CLASS_INIT_TIME;
74    public static final int KIND_GLOBAL_EXT_ALLOCATED_OBJECTS =
75        KIND_EXT_ALLOCATED_OBJECTS;
76    public static final int KIND_GLOBAL_EXT_ALLOCATED_BYTES =
77        KIND_EXT_ALLOCATED_BYTES;
78    public static final int KIND_GLOBAL_EXT_FREED_OBJECTS =
79        KIND_EXT_FREED_OBJECTS;
80    public static final int KIND_GLOBAL_EXT_FREED_BYTES =
81        KIND_EXT_FREED_BYTES;
82
83    public static final int KIND_THREAD_ALLOCATED_OBJECTS =
84        KIND_ALLOCATED_OBJECTS << 16;
85    public static final int KIND_THREAD_ALLOCATED_BYTES =
86        KIND_ALLOCATED_BYTES << 16;
87    public static final int KIND_THREAD_FREED_OBJECTS =
88        KIND_FREED_OBJECTS << 16;
89    public static final int KIND_THREAD_FREED_BYTES =
90        KIND_FREED_BYTES << 16;
91    public static final int KIND_THREAD_GC_INVOCATIONS =
92        KIND_GC_INVOCATIONS << 16;
93    public static final int KIND_THREAD_CLASS_INIT_COUNT =
94        KIND_CLASS_INIT_COUNT << 16;
95    public static final int KIND_THREAD_CLASS_INIT_TIME =
96        KIND_CLASS_INIT_TIME << 16;
97    public static final int KIND_THREAD_EXT_ALLOCATED_OBJECTS =
98        KIND_EXT_ALLOCATED_OBJECTS << 16;
99    public static final int KIND_THREAD_EXT_ALLOCATED_BYTES =
100        KIND_EXT_ALLOCATED_BYTES << 16;
101    public static final int KIND_THREAD_EXT_FREED_OBJECTS =
102        KIND_EXT_FREED_OBJECTS << 16;
103    public static final int KIND_THREAD_EXT_FREED_BYTES =
104        KIND_EXT_FREED_BYTES << 16;
105
106    public static final int KIND_ALL_COUNTS = 0xffffffff;
107
108    /* all methods are static */
109    private VMDebug() {}
110
111    /**
112     * Returns the time since the last known debugger activity.
113     *
114     * @return the time in milliseconds, or -1 if the debugger is not connected
115     */
116    public static native long lastDebuggerActivity();
117
118    /**
119     * Determines if debugging is enabled in this VM.  If debugging is not
120     * enabled, a debugger cannot be attached.
121     *
122     * @return true if debugging is enabled
123     */
124    public static native boolean isDebuggingEnabled();
125
126    /**
127     * Determines if a debugger is currently attached.
128     *
129     * @return true if (and only if) a debugger is connected
130     */
131    public static native boolean isDebuggerConnected();
132
133    /**
134     * Returns an array of strings that identify VM features.  This is
135     * used by DDMS to determine what sorts of operations the VM can
136     * perform.
137     *
138     * @hide
139     */
140    public static native String[] getVmFeatureList();
141
142    /**
143     * Start method tracing with default name, size, and with <code>0</code>
144     * flags.
145     *
146     * @deprecated not used, not needed
147     */
148    public static void startMethodTracing() {
149        startMethodTracing(DEFAULT_METHOD_TRACE_FILE_NAME, 0, 0);
150    }
151
152    /**
153     * Start method tracing, specifying a file name as well as a default
154     * buffer size. See <a
155     * href="{@docRoot}guide/developing/tools/traceview.html"> Running the
156     * Traceview Debugging Program</a> for information about reading
157     * trace files.
158     *
159     * <p>You can use either a fully qualified path and
160     * name, or just a name. If only a name is specified, the file will
161     * be created under the /sdcard/ directory. If a name is not given,
162     * the default is /sdcard/dmtrace.trace.</p>
163     *
164     * @param traceFileName name to give the trace file
165     * @param bufferSize the maximum size of both files combined. If passed
166     * as <code>0</code>, it defaults to 8MB.
167     * @param flags flags to control method tracing. The only one that
168     * is currently defined is {@link #TRACE_COUNT_ALLOCS}.
169     */
170    public static void startMethodTracing(String traceFileName,
171        int bufferSize, int flags) {
172
173        if (traceFileName == null) {
174            throw new NullPointerException();
175        }
176
177        startMethodTracingNative(traceFileName, null, bufferSize, flags);
178    }
179
180    /**
181     * Like startMethodTracing(String, int, int), but taking an already-opened
182     * FileDescriptor in which the trace is written.  The file name is also
183     * supplied simply for logging.  Makes a dup of the file descriptor.
184     *
185     * Not exposed in the SDK unless we are really comfortable with supporting
186     * this and find it would be useful.
187     * @hide
188     */
189    public static void startMethodTracing(String traceFileName,
190        FileDescriptor fd, int bufferSize, int flags)
191    {
192        if (traceFileName == null || fd == null) {
193            throw new NullPointerException();
194        }
195
196        startMethodTracingNative(traceFileName, fd, bufferSize, flags);
197    }
198
199    /**
200     * Starts method tracing without a backing file.  When stopMethodTracing
201     * is called, the result is sent directly to DDMS.  (If DDMS is not
202     * attached when tracing ends, the profiling data will be discarded.)
203     *
204     * @hide
205     */
206    public static void startMethodTracingDdms(int bufferSize, int flags) {
207        startMethodTracingNative(null, null, bufferSize, flags);
208    }
209
210    /**
211     * Implements all startMethodTracing variants.
212     *
213     * @hide
214     */
215    private static native void startMethodTracingNative(String traceFileName,
216        FileDescriptor fd, int bufferSize, int flags);
217
218    /**
219     * Determine whether method tracing is currently active.
220     * @hide
221     */
222    public static native boolean isMethodTracingActive();
223
224    /**
225     * Stops method tracing.
226     */
227    public static native void stopMethodTracing();
228
229    /**
230     * Starts sending Dalvik method trace info to the emulator.
231     */
232    public static native void startEmulatorTracing();
233
234    /**
235     * Stops sending Dalvik method trace info to the emulator.
236     */
237    public static native void stopEmulatorTracing();
238
239    /**
240     * Get an indication of thread CPU usage. The value returned indicates the
241     * amount of time that the current thread has spent executing code or
242     * waiting for certain types of I/O.
243     * <p>
244     * The time is expressed in nanoseconds, and is only meaningful when
245     * compared to the result from an earlier call. Note that nanosecond
246     * resolution does not imply nanosecond accuracy.
247     *
248     * @return the CPU usage. A value of -1 means the system does not support
249     *         this feature.
250     */
251    public static native long threadCpuTimeNanos();
252
253    /**
254     * Count the number and aggregate size of memory allocations between
255     * two points.
256     */
257    public static native void startAllocCounting();
258    public static native void stopAllocCounting();
259    public static native int getAllocCount(int kind);
260    public static native void resetAllocCount(int kinds);
261
262    /**
263     * Establishes an object allocation limit in the current thread. Useful for
264     * catching regressions in code that is expected to operate without causing
265     * any allocations. The limit is valid from the return of this method until
266     * it is either changed or the thread terminates.
267     *
268     * @param limit
269     *            the new limit. A value of 0 means not a single new object may
270     *            be allocated. A value of -1 disables the limit.
271     *
272     * @return the previous limit, or -1 if no limit was set
273     *
274     * @see #setGlobalAllocationLimit(int)
275     */
276    public static native int setAllocationLimit(int limit);
277
278    /**
279     * Establishes an object allocation limit for the entire VM. Useful for
280     * catching regressions in code that is expected to operate without causing
281     * any allocations. The limit is valid from the return of this method until
282     * it is either changed or the thread terminates.
283     *
284     * @param limit
285     *            the new limit. A value of 0 means not a single new object may
286     *            be allocated. A value of -1 disables the limit.
287     *
288     * @return the previous limit, or -1 if no limit was set
289     *
290     * @see #setAllocationLimit(int)
291     */
292    public static native int setGlobalAllocationLimit(int limit);
293
294    /**
295     * Count the number of instructions executed between two points.
296     */
297    public static native void startInstructionCounting();
298    public static native void stopInstructionCounting();
299    public static native void getInstructionCount(int[] counts);
300    public static native void resetInstructionCount();
301
302    /**
303     * Dumps a list of loaded class to the log file.
304     */
305    public static native void printLoadedClasses(int flags);
306
307    /**
308     * Gets the number of loaded classes.
309     *
310     * @return the number of loaded classes
311     */
312    public static native int getLoadedClassCount();
313
314    /**
315     * Dumps "hprof" data to the specified file.  This may cause a GC.
316     *
317     * The VM may create a temporary file in the same directory.
318     *
319     * @param fileName Full pathname of output file (e.g. "/sdcard/dump.hprof").
320     * @throws UnsupportedOperationException if the VM was built without
321     *         HPROF support.
322     * @throws IOException if an error occurs while opening or writing files.
323     */
324    public static void dumpHprofData(String fileName) throws IOException {
325        if (fileName == null)
326            throw new NullPointerException();
327        dumpHprofData(fileName, null);
328    }
329
330    /**
331     * Collects "hprof" heap data and sends it to DDMS.  This may cause a GC.
332     *
333     * @throws UnsupportedOperationException if the VM was built without
334     *         HPROF support.
335     *
336     * @hide
337     */
338    public static native void dumpHprofDataDdms();
339
340    /**
341     * Dumps "hprof" heap data to a file, by name or descriptor.
342     *
343     * @param fileName Name of output file.  If fd is non-null, the
344     *        file name is only used in log messages (and may be null).
345     * @param fd Descriptor of open file that will receive the output.
346     *        If this is null, the fileName is used instead.
347     *
348     * @hide
349     */
350    public static native void dumpHprofData(String fileName, FileDescriptor fd)
351            throws IOException;
352
353    /**
354     * Primes the register map cache.
355     *
356     * @hide
357     */
358    public static native boolean cacheRegisterMap(String classAndMethodDesc);
359
360    /**
361     * Dumps the contents of the VM reference tables (e.g. JNI locals and
362     * globals) to the log file.
363     *
364     * @hide
365     */
366    public static native void dumpReferenceTables();
367
368    /**
369     * Crashes the VM.  Seriously.  Dumps the interpreter stack trace for
370     * the current thread and then aborts the VM so you can see the native
371     * stack trace.  Useful for figuring out how you got somewhere when
372     * lots of native code is involved.
373     *
374     * @hide
375     */
376    public static native void crash();
377
378    /**
379     * Together with gdb, provide a handy way to stop the VM at user-tagged
380     * locations.
381     *
382     * @hide
383     */
384    public static native void infopoint(int id);
385
386    /*
387     * Fake method, inserted into dmtrace output when the garbage collector
388     * runs.  Not actually called.
389     */
390    private static void startGC() {}
391
392    /*
393     * Fake method, inserted into dmtrace output during class preparation
394     * (loading and linking, but not verification or initialization).  Not
395     * actually called.
396     */
397    private static void startClassPrep() {}
398
399    /**
400      * Returns a count of the extant instances of a class.
401     *
402     * @hide
403     */
404    public static native long countInstancesOfClass(Class cls);
405}
406