• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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 
17 import java.io.File;
18 import java.io.IOException;
19 import java.lang.reflect.Method;
20 import java.util.Map;
21 
22 public class Main {
main(String[] args)23     public static void main(String[] args) throws Exception {
24         String name = System.getProperty("java.vm.name");
25         if (!"Dalvik".equals(name)) {
26             System.out.println("This test is not supported on " + name);
27             return;
28         }
29         testMethodTracing();
30         testRuntimeStat();
31     }
32 
createTempFile()33     private static File createTempFile() throws Exception {
34         try {
35             return  File.createTempFile("test", ".trace");
36         } catch (IOException e) {
37             System.setProperty("java.io.tmpdir", "/data/local/tmp");
38             try {
39                 return File.createTempFile("test", ".trace");
40             } catch (IOException e2) {
41                 System.setProperty("java.io.tmpdir", "/sdcard");
42                 return File.createTempFile("test", ".trace");
43             }
44         }
45     }
46 
testMethodTracing()47     private static void testMethodTracing() throws Exception {
48         File tempFile = createTempFile();
49         tempFile.deleteOnExit();
50         String tempFileName = tempFile.getPath();
51 
52         if (VMDebug.getMethodTracingMode() != 0) {
53             VMDebug.stopMethodTracing();
54         }
55 
56         System.out.println("Confirm enable/disable");
57         System.out.println("status=" + VMDebug.getMethodTracingMode());
58         VMDebug.startMethodTracing(tempFileName, 0, 0, false, 0);
59         System.out.println("status=" + VMDebug.getMethodTracingMode());
60         VMDebug.stopMethodTracing();
61         System.out.println("status=" + VMDebug.getMethodTracingMode());
62         if (tempFile.length() == 0) {
63             System.out.println("ERROR: tracing output file is empty");
64         }
65 
66         System.out.println("Confirm sampling");
67         VMDebug.startMethodTracing(tempFileName, 0, 0, true, 1000);
68         System.out.println("status=" + VMDebug.getMethodTracingMode());
69         VMDebug.stopMethodTracing();
70         System.out.println("status=" + VMDebug.getMethodTracingMode());
71         if (tempFile.length() == 0) {
72             System.out.println("ERROR: sample tracing output file is empty");
73         }
74 
75         System.out.println("Test starting when already started");
76         VMDebug.startMethodTracing(tempFileName, 0, 0, false, 0);
77         System.out.println("status=" + VMDebug.getMethodTracingMode());
78         VMDebug.startMethodTracing(tempFileName, 0, 0, false, 0);
79         System.out.println("status=" + VMDebug.getMethodTracingMode());
80 
81         System.out.println("Test stopping when already stopped");
82         VMDebug.stopMethodTracing();
83         System.out.println("status=" + VMDebug.getMethodTracingMode());
84         VMDebug.stopMethodTracing();
85         System.out.println("status=" + VMDebug.getMethodTracingMode());
86 
87         System.out.println("Test tracing with empty filename");
88         try {
89             VMDebug.startMethodTracing("", 0, 0, false, 0);
90             System.out.println("Should have thrown an exception");
91         } catch (Exception e) {
92             System.out.println("Got expected exception");
93         }
94 
95         System.out.println("Test tracing with bogus (< 1024 && != 0) filesize");
96         try {
97             VMDebug.startMethodTracing(tempFileName, 1000, 0, false, 0);
98             System.out.println("Should have thrown an exception");
99         } catch (Exception e) {
100             System.out.println("Got expected exception");
101         }
102 
103         System.out.println("Test sampling with bogus (<= 0) interval");
104         try {
105             VMDebug.startMethodTracing(tempFileName, 0, 0, true, 0);
106             System.out.println("Should have thrown an exception");
107         } catch (Exception e) {
108             System.out.println("Got expected exception");
109         }
110 
111         tempFile.delete();
112     }
113 
checkNumber(String s)114     private static void checkNumber(String s) throws Exception {
115         if (s == null) {
116             System.out.println("Got null string");
117             return;
118         }
119         long n = Long.valueOf(s);
120         if (n < 0) {
121             System.out.println("Got negative number " + n);
122         }
123     }
124 
checkHistogram(String s)125     private static void checkHistogram(String s) throws Exception {
126         if (s == null || s.length() == 0) {
127             System.out.println("Got null or empty string");
128             return;
129         }
130         String[] buckets = s.split(",");
131         long last_key = 0;
132         for (int i = 0; i < buckets.length; ++i) {
133             String bucket = buckets[i];
134             if (bucket.length() == 0) {
135                 System.out.println("Got empty bucket");
136                 continue;
137             }
138             String[] kv = bucket.split(":");
139             if (kv.length != 2 || kv[0].length() == 0 || kv[1].length() == 0) {
140                 System.out.println("Got bad bucket " + bucket);
141                 continue;
142             }
143             long key = Long.valueOf(kv[0]);
144             long value = Long.valueOf(kv[1]);
145             if (key < 0 || value < 0) {
146                 System.out.println("Got negative key or value " + bucket);
147                 continue;
148             }
149             if (key < last_key) {
150                 System.out.println("Got decreasing key " + bucket);
151                 continue;
152             }
153             last_key = key;
154         }
155     }
156 
testRuntimeStat()157     private static void testRuntimeStat() throws Exception {
158         // Invoke at least one GC and wait for 20 seconds or so so we get at
159         // least one bucket in the histograms.
160         for (int i = 0; i < 20; ++i) {
161           Runtime.getRuntime().gc();
162           Thread.sleep(1000L);
163         }
164         String gc_count = VMDebug.getRuntimeStat("art.gc.gc-count");
165         String gc_time = VMDebug.getRuntimeStat("art.gc.gc-time");
166         String bytes_allocated = VMDebug.getRuntimeStat("art.gc.bytes-allocated");
167         String bytes_freed = VMDebug.getRuntimeStat("art.gc.bytes-freed");
168         String blocking_gc_count = VMDebug.getRuntimeStat("art.gc.blocking-gc-count");
169         String blocking_gc_time = VMDebug.getRuntimeStat("art.gc.blocking-gc-time");
170         String gc_count_rate_histogram = VMDebug.getRuntimeStat("art.gc.gc-count-rate-histogram");
171         String blocking_gc_count_rate_histogram =
172             VMDebug.getRuntimeStat("art.gc.blocking-gc-count-rate-histogram");
173         checkNumber(gc_count);
174         checkNumber(gc_time);
175         checkNumber(bytes_allocated);
176         checkNumber(bytes_freed);
177         checkNumber(blocking_gc_count);
178         checkNumber(blocking_gc_time);
179         checkHistogram(gc_count_rate_histogram);
180         checkHistogram(blocking_gc_count_rate_histogram);
181     }
182 
testRuntimeStats()183     private static void testRuntimeStats() throws Exception {
184         // Invoke at least one GC and wait for 20 seconds or so so we get at
185         // least one bucket in the histograms.
186         for (int i = 0; i < 20; ++i) {
187           Runtime.getRuntime().gc();
188           Thread.sleep(1000L);
189         }
190         Map<String, String> map = VMDebug.getRuntimeStats();
191         String gc_count = map.get("art.gc.gc-count");
192         String gc_time = map.get("art.gc.gc-time");
193         String bytes_allocated = map.get("art.gc.bytes-allocated");
194         String bytes_freed = map.get("art.gc.bytes-freed");
195         String blocking_gc_count = map.get("art.gc.blocking-gc-count");
196         String blocking_gc_time = map.get("art.gc.blocking-gc-time");
197         String gc_count_rate_histogram = map.get("art.gc.gc-count-rate-histogram");
198         String blocking_gc_count_rate_histogram =
199             map.get("art.gc.blocking-gc-count-rate-histogram");
200         checkNumber(gc_count);
201         checkNumber(gc_time);
202         checkNumber(bytes_allocated);
203         checkNumber(bytes_freed);
204         checkNumber(blocking_gc_count);
205         checkNumber(blocking_gc_time);
206         checkHistogram(gc_count_rate_histogram);
207         checkHistogram(blocking_gc_count_rate_histogram);
208     }
209 
210     private static class VMDebug {
211         private static final Method startMethodTracingMethod;
212         private static final Method stopMethodTracingMethod;
213         private static final Method getMethodTracingModeMethod;
214         private static final Method getRuntimeStatMethod;
215         private static final Method getRuntimeStatsMethod;
216         static {
217             try {
218                 Class c = Class.forName("dalvik.system.VMDebug");
219                 startMethodTracingMethod = c.getDeclaredMethod("startMethodTracing", String.class,
220                         Integer.TYPE, Integer.TYPE, Boolean.TYPE, Integer.TYPE);
221                 stopMethodTracingMethod = c.getDeclaredMethod("stopMethodTracing");
222                 getMethodTracingModeMethod = c.getDeclaredMethod("getMethodTracingMode");
223                 getRuntimeStatMethod = c.getDeclaredMethod("getRuntimeStat", String.class);
224                 getRuntimeStatsMethod = c.getDeclaredMethod("getRuntimeStats");
225             } catch (Exception e) {
226                 throw new RuntimeException(e);
227             }
228         }
229 
startMethodTracing(String filename, int bufferSize, int flags, boolean samplingEnabled, int intervalUs)230         public static void startMethodTracing(String filename, int bufferSize, int flags,
231                 boolean samplingEnabled, int intervalUs) throws Exception {
232             startMethodTracingMethod.invoke(null, filename, bufferSize, flags, samplingEnabled,
233                     intervalUs);
234         }
stopMethodTracing()235         public static void stopMethodTracing() throws Exception {
236             stopMethodTracingMethod.invoke(null);
237         }
getMethodTracingMode()238         public static int getMethodTracingMode() throws Exception {
239             return (int) getMethodTracingModeMethod.invoke(null);
240         }
getRuntimeStat(String statName)241         public static String getRuntimeStat(String statName) throws Exception {
242             return (String) getRuntimeStatMethod.invoke(null, statName);
243         }
getRuntimeStats()244         public static Map<String, String> getRuntimeStats() throws Exception {
245             return (Map<String, String>) getRuntimeStatsMethod.invoke(null);
246         }
247     }
248 }
249