Debug.java revision 8b9f49415f7c95f6e8949a3987cde59bf9a89169
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 android.os; 18 19import com.android.internal.util.FastPrintWriter; 20import com.android.internal.util.TypedProperties; 21 22import android.util.Log; 23 24import java.io.FileDescriptor; 25import java.io.FileNotFoundException; 26import java.io.FileOutputStream; 27import java.io.FileReader; 28import java.io.IOException; 29import java.io.PrintWriter; 30import java.io.Reader; 31import java.lang.reflect.Field; 32import java.lang.reflect.Modifier; 33import java.lang.annotation.Target; 34import java.lang.annotation.ElementType; 35import java.lang.annotation.Retention; 36import java.lang.annotation.RetentionPolicy; 37import java.util.HashMap; 38import java.util.Map; 39 40import org.apache.harmony.dalvik.ddmc.Chunk; 41import org.apache.harmony.dalvik.ddmc.ChunkHandler; 42import org.apache.harmony.dalvik.ddmc.DdmServer; 43 44import dalvik.bytecode.OpcodeInfo; 45import dalvik.system.VMDebug; 46 47 48/** 49 * Provides various debugging methods for Android applications, including 50 * tracing and allocation counts. 51 * <p><strong>Logging Trace Files</strong></p> 52 * <p>Debug can create log files that give details about an application, such as 53 * a call stack and start/stop times for any running methods. See <a 54href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for 55 * information about reading trace files. To start logging trace files, call one 56 * of the startMethodTracing() methods. To stop tracing, call 57 * {@link #stopMethodTracing()}. 58 */ 59public final class Debug 60{ 61 private static final String TAG = "Debug"; 62 63 /** 64 * Flags for startMethodTracing(). These can be ORed together. 65 * 66 * TRACE_COUNT_ALLOCS adds the results from startAllocCounting to the 67 * trace key file. 68 * 69 * @deprecated Accurate counting is a burden on the runtime and may be removed. 70 */ 71 @Deprecated 72 public static final int TRACE_COUNT_ALLOCS = VMDebug.TRACE_COUNT_ALLOCS; 73 74 /** 75 * Flags for printLoadedClasses(). Default behavior is to only show 76 * the class name. 77 */ 78 public static final int SHOW_FULL_DETAIL = 1; 79 public static final int SHOW_CLASSLOADER = (1 << 1); 80 public static final int SHOW_INITIALIZED = (1 << 2); 81 82 // set/cleared by waitForDebugger() 83 private static volatile boolean mWaiting = false; 84 85 private Debug() {} 86 87 /* 88 * How long to wait for the debugger to finish sending requests. I've 89 * seen this hit 800msec on the device while waiting for a response 90 * to travel over USB and get processed, so we take that and add 91 * half a second. 92 */ 93 private static final int MIN_DEBUGGER_IDLE = 1300; // msec 94 95 /* how long to sleep when polling for activity */ 96 private static final int SPIN_DELAY = 200; // msec 97 98 /** 99 * Default trace file path and file 100 */ 101 private static final String DEFAULT_TRACE_BODY = "dmtrace"; 102 private static final String DEFAULT_TRACE_EXTENSION = ".trace"; 103 private static class NoPreloadHolder { 104 private static final String DEFAULT_TRACE_PATH_PREFIX = 105 Environment.getLegacyExternalStorageDirectory().getPath() + "/"; 106 private static final String DEFAULT_TRACE_FILE_PATH = 107 DEFAULT_TRACE_PATH_PREFIX + DEFAULT_TRACE_BODY 108 + DEFAULT_TRACE_EXTENSION; 109 } 110 111 112 /** 113 * This class is used to retrieved various statistics about the memory mappings for this 114 * process. The returned info is broken down by dalvik, native, and other. All results are in kB. 115 */ 116 public static class MemoryInfo implements Parcelable { 117 /** The proportional set size for dalvik heap. (Doesn't include other Dalvik overhead.) */ 118 public int dalvikPss; 119 /** The proportional set size that is swappable for dalvik heap. */ 120 /** @hide We may want to expose this, eventually. */ 121 public int dalvikSwappablePss; 122 /** The private dirty pages used by dalvik heap. */ 123 public int dalvikPrivateDirty; 124 /** The shared dirty pages used by dalvik heap. */ 125 public int dalvikSharedDirty; 126 /** The private clean pages used by dalvik heap. */ 127 /** @hide We may want to expose this, eventually. */ 128 public int dalvikPrivateClean; 129 /** The shared clean pages used by dalvik heap. */ 130 /** @hide We may want to expose this, eventually. */ 131 public int dalvikSharedClean; 132 /** The dirty dalvik pages that have been swapped out. */ 133 /** @hide We may want to expose this, eventually. */ 134 public int dalvikSwappedOut; 135 /** The dirty dalvik pages that have been swapped out, proportional. */ 136 /** @hide We may want to expose this, eventually. */ 137 public int dalvikSwappedOutPss; 138 139 /** The proportional set size for the native heap. */ 140 public int nativePss; 141 /** The proportional set size that is swappable for the native heap. */ 142 /** @hide We may want to expose this, eventually. */ 143 public int nativeSwappablePss; 144 /** The private dirty pages used by the native heap. */ 145 public int nativePrivateDirty; 146 /** The shared dirty pages used by the native heap. */ 147 public int nativeSharedDirty; 148 /** The private clean pages used by the native heap. */ 149 /** @hide We may want to expose this, eventually. */ 150 public int nativePrivateClean; 151 /** The shared clean pages used by the native heap. */ 152 /** @hide We may want to expose this, eventually. */ 153 public int nativeSharedClean; 154 /** The dirty native pages that have been swapped out. */ 155 /** @hide We may want to expose this, eventually. */ 156 public int nativeSwappedOut; 157 /** The dirty native pages that have been swapped out, proportional. */ 158 /** @hide We may want to expose this, eventually. */ 159 public int nativeSwappedOutPss; 160 161 /** The proportional set size for everything else. */ 162 public int otherPss; 163 /** The proportional set size that is swappable for everything else. */ 164 /** @hide We may want to expose this, eventually. */ 165 public int otherSwappablePss; 166 /** The private dirty pages used by everything else. */ 167 public int otherPrivateDirty; 168 /** The shared dirty pages used by everything else. */ 169 public int otherSharedDirty; 170 /** The private clean pages used by everything else. */ 171 /** @hide We may want to expose this, eventually. */ 172 public int otherPrivateClean; 173 /** The shared clean pages used by everything else. */ 174 /** @hide We may want to expose this, eventually. */ 175 public int otherSharedClean; 176 /** The dirty pages used by anyting else that have been swapped out. */ 177 /** @hide We may want to expose this, eventually. */ 178 public int otherSwappedOut; 179 /** The dirty pages used by anyting else that have been swapped out, proportional. */ 180 /** @hide We may want to expose this, eventually. */ 181 public int otherSwappedOutPss; 182 183 /** Whether the kernel reports proportional swap usage */ 184 /** @hide */ 185 public boolean hasSwappedOutPss; 186 187 /** @hide */ 188 public static final int HEAP_UNKNOWN = 0; 189 /** @hide */ 190 public static final int HEAP_DALVIK = 1; 191 /** @hide */ 192 public static final int HEAP_NATIVE = 2; 193 194 /** @hide */ 195 public static final int OTHER_DALVIK_OTHER = 0; 196 /** @hide */ 197 public static final int OTHER_STACK = 1; 198 /** @hide */ 199 public static final int OTHER_CURSOR = 2; 200 /** @hide */ 201 public static final int OTHER_ASHMEM = 3; 202 /** @hide */ 203 public static final int OTHER_GL_DEV = 4; 204 /** @hide */ 205 public static final int OTHER_UNKNOWN_DEV = 5; 206 /** @hide */ 207 public static final int OTHER_SO = 6; 208 /** @hide */ 209 public static final int OTHER_JAR = 7; 210 /** @hide */ 211 public static final int OTHER_APK = 8; 212 /** @hide */ 213 public static final int OTHER_TTF = 9; 214 /** @hide */ 215 public static final int OTHER_DEX = 10; 216 /** @hide */ 217 public static final int OTHER_OAT = 11; 218 /** @hide */ 219 public static final int OTHER_ART = 12; 220 /** @hide */ 221 public static final int OTHER_UNKNOWN_MAP = 13; 222 /** @hide */ 223 public static final int OTHER_GRAPHICS = 14; 224 /** @hide */ 225 public static final int OTHER_GL = 15; 226 /** @hide */ 227 public static final int OTHER_OTHER_MEMTRACK = 16; 228 229 /** @hide */ 230 public static final int OTHER_DALVIK_NORMAL = 17; 231 /** @hide */ 232 public static final int OTHER_DALVIK_LARGE = 18; 233 /** @hide */ 234 public static final int OTHER_DALVIK_LINEARALLOC = 19; 235 /** @hide */ 236 public static final int OTHER_DALVIK_ACCOUNTING = 20; 237 /** @hide */ 238 public static final int OTHER_DALVIK_CODE_CACHE = 21; 239 /** @hide */ 240 public static final int OTHER_DALVIK_ZYGOTE = 22; 241 /** @hide */ 242 public static final int OTHER_DALVIK_NON_MOVING = 23; 243 /** @hide */ 244 public static final int OTHER_DALVIK_INDIRECT_REFERENCE_TABLE = 24; 245 246 /** @hide */ 247 public static final int NUM_OTHER_STATS = 17; 248 249 /** @hide */ 250 public static final int NUM_DVK_STATS = 8; 251 252 /** @hide */ 253 public static final int NUM_CATEGORIES = 8; 254 255 /** @hide */ 256 public static final int offsetPss = 0; 257 /** @hide */ 258 public static final int offsetSwappablePss = 1; 259 /** @hide */ 260 public static final int offsetPrivateDirty = 2; 261 /** @hide */ 262 public static final int offsetSharedDirty = 3; 263 /** @hide */ 264 public static final int offsetPrivateClean = 4; 265 /** @hide */ 266 public static final int offsetSharedClean = 5; 267 /** @hide */ 268 public static final int offsetSwappedOut = 6; 269 /** @hide */ 270 public static final int offsetSwappedOutPss = 7; 271 272 private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES]; 273 274 public MemoryInfo() { 275 } 276 277 /** 278 * Return total PSS memory usage in kB. 279 */ 280 public int getTotalPss() { 281 return dalvikPss + nativePss + otherPss + getTotalSwappedOutPss(); 282 } 283 284 /** 285 * @hide Return total PSS memory usage in kB. 286 */ 287 public int getTotalUss() { 288 return dalvikPrivateClean + dalvikPrivateDirty 289 + nativePrivateClean + nativePrivateDirty 290 + otherPrivateClean + otherPrivateDirty; 291 } 292 293 /** 294 * Return total PSS memory usage in kB mapping a file of one of the following extension: 295 * .so, .jar, .apk, .ttf, .dex, .odex, .oat, .art . 296 */ 297 public int getTotalSwappablePss() { 298 return dalvikSwappablePss + nativeSwappablePss + otherSwappablePss; 299 } 300 301 /** 302 * Return total private dirty memory usage in kB. 303 */ 304 public int getTotalPrivateDirty() { 305 return dalvikPrivateDirty + nativePrivateDirty + otherPrivateDirty; 306 } 307 308 /** 309 * Return total shared dirty memory usage in kB. 310 */ 311 public int getTotalSharedDirty() { 312 return dalvikSharedDirty + nativeSharedDirty + otherSharedDirty; 313 } 314 315 /** 316 * Return total shared clean memory usage in kB. 317 */ 318 public int getTotalPrivateClean() { 319 return dalvikPrivateClean + nativePrivateClean + otherPrivateClean; 320 } 321 322 /** 323 * Return total shared clean memory usage in kB. 324 */ 325 public int getTotalSharedClean() { 326 return dalvikSharedClean + nativeSharedClean + otherSharedClean; 327 } 328 329 /** 330 * Return total swapped out memory in kB. 331 * @hide 332 */ 333 public int getTotalSwappedOut() { 334 return dalvikSwappedOut + nativeSwappedOut + otherSwappedOut; 335 } 336 337 /** 338 * Return total swapped out memory in kB, proportional. 339 * @hide 340 */ 341 public int getTotalSwappedOutPss() { 342 return dalvikSwappedOutPss + nativeSwappedOutPss + otherSwappedOutPss; 343 } 344 345 /** @hide */ 346 public int getOtherPss(int which) { 347 return otherStats[which*NUM_CATEGORIES + offsetPss]; 348 } 349 350 351 /** @hide */ 352 public int getOtherSwappablePss(int which) { 353 return otherStats[which*NUM_CATEGORIES + offsetSwappablePss]; 354 } 355 356 357 /** @hide */ 358 public int getOtherPrivateDirty(int which) { 359 return otherStats[which*NUM_CATEGORIES + offsetPrivateDirty]; 360 } 361 362 /** @hide */ 363 public int getOtherSharedDirty(int which) { 364 return otherStats[which*NUM_CATEGORIES + offsetSharedDirty]; 365 } 366 367 /** @hide */ 368 public int getOtherPrivateClean(int which) { 369 return otherStats[which*NUM_CATEGORIES + offsetPrivateClean]; 370 } 371 372 /** @hide */ 373 public int getOtherPrivate(int which) { 374 return getOtherPrivateClean(which) + getOtherPrivateDirty(which); 375 } 376 377 /** @hide */ 378 public int getOtherSharedClean(int which) { 379 return otherStats[which*NUM_CATEGORIES + offsetSharedClean]; 380 } 381 382 /** @hide */ 383 public int getOtherSwappedOut(int which) { 384 return otherStats[which*NUM_CATEGORIES + offsetSwappedOut]; 385 } 386 387 /** @hide */ 388 public int getOtherSwappedOutPss(int which) { 389 return otherStats[which*NUM_CATEGORIES + offsetSwappedOutPss]; 390 } 391 392 /** @hide */ 393 public static String getOtherLabel(int which) { 394 switch (which) { 395 case OTHER_DALVIK_OTHER: return "Dalvik Other"; 396 case OTHER_STACK: return "Stack"; 397 case OTHER_CURSOR: return "Cursor"; 398 case OTHER_ASHMEM: return "Ashmem"; 399 case OTHER_GL_DEV: return "Gfx dev"; 400 case OTHER_UNKNOWN_DEV: return "Other dev"; 401 case OTHER_SO: return ".so mmap"; 402 case OTHER_JAR: return ".jar mmap"; 403 case OTHER_APK: return ".apk mmap"; 404 case OTHER_TTF: return ".ttf mmap"; 405 case OTHER_DEX: return ".dex mmap"; 406 case OTHER_OAT: return ".oat mmap"; 407 case OTHER_ART: return ".art mmap"; 408 case OTHER_UNKNOWN_MAP: return "Other mmap"; 409 case OTHER_GRAPHICS: return "EGL mtrack"; 410 case OTHER_GL: return "GL mtrack"; 411 case OTHER_OTHER_MEMTRACK: return "Other mtrack"; 412 case OTHER_DALVIK_NORMAL: return ".Heap"; 413 case OTHER_DALVIK_LARGE: return ".LOS"; 414 case OTHER_DALVIK_LINEARALLOC: return ".LinearAlloc"; 415 case OTHER_DALVIK_ACCOUNTING: return ".GC"; 416 case OTHER_DALVIK_CODE_CACHE: return ".JITCache"; 417 case OTHER_DALVIK_ZYGOTE: return ".Zygote"; 418 case OTHER_DALVIK_NON_MOVING: return ".NonMoving"; 419 case OTHER_DALVIK_INDIRECT_REFERENCE_TABLE: return ".IndirectRef"; 420 default: return "????"; 421 } 422 } 423 424 /** 425 * Returns the value of a particular memory statistic or {@code null} if no 426 * such memory statistic exists. 427 * 428 * <p>The following table lists the memory statistics that are supported. 429 * Note that memory statistics may be added or removed in a future API level.</p> 430 * 431 * <table> 432 * <thead> 433 * <tr> 434 * <th>Memory statistic name</th> 435 * <th>Meaning</th> 436 * <th>Example</th> 437 * <th>Supported (API Levels)</th> 438 * </tr> 439 * </thead> 440 * <tbody> 441 * <tr> 442 * <td>summary.java-heap</td> 443 * <td>The private Java Heap usage in kB. This corresponds to the Java Heap field 444 * in the App Summary section output by dumpsys meminfo.</td> 445 * <td>{@code 1442}</td> 446 * <td>23</td> 447 * </tr> 448 * <tr> 449 * <td>summary.native-heap</td> 450 * <td>The private Native Heap usage in kB. This corresponds to the Native Heap 451 * field in the App Summary section output by dumpsys meminfo.</td> 452 * <td>{@code 1442}</td> 453 * <td>23</td> 454 * </tr> 455 * <tr> 456 * <td>summary.code</td> 457 * <td>The memory usage for static code and resources in kB. This corresponds to 458 * the Code field in the App Summary section output by dumpsys meminfo.</td> 459 * <td>{@code 1442}</td> 460 * <td>23</td> 461 * </tr> 462 * <tr> 463 * <td>summary.stack</td> 464 * <td>The stack usage in kB. This corresponds to the Stack field in the 465 * App Summary section output by dumpsys meminfo.</td> 466 * <td>{@code 1442}</td> 467 * <td>23</td> 468 * </tr> 469 * <tr> 470 * <td>summary.graphics</td> 471 * <td>The graphics usage in kB. This corresponds to the Graphics field in the 472 * App Summary section output by dumpsys meminfo.</td> 473 * <td>{@code 1442}</td> 474 * <td>23</td> 475 * </tr> 476 * <tr> 477 * <td>summary.private-other</td> 478 * <td>Other private memory usage in kB. This corresponds to the Private Other 479 * field output in the App Summary section by dumpsys meminfo.</td> 480 * <td>{@code 1442}</td> 481 * <td>23</td> 482 * </tr> 483 * <tr> 484 * <td>summary.system</td> 485 * <td>Shared and system memory usage in kB. This corresponds to the System 486 * field output in the App Summary section by dumpsys meminfo.</td> 487 * <td>{@code 1442}</td> 488 * <td>23</td> 489 * </tr> 490 * <tr> 491 * <td>summary.total-pss</td> 492 * <td>Total PPS memory usage in kB.</td> 493 * <td>{@code 1442}</td> 494 * <td>23</td> 495 * </tr> 496 * <tr> 497 * <td>summary.total-swap</td> 498 * <td>Total swap usage in kB.</td> 499 * <td>{@code 1442}</td> 500 * <td>23</td> 501 * </tr> 502 * </tbody> 503 * </table> 504 */ 505 public String getMemoryStat(String statName) { 506 switch(statName) { 507 case "summary.java-heap": 508 return Integer.toString(getSummaryJavaHeap()); 509 case "summary.native-heap": 510 return Integer.toString(getSummaryNativeHeap()); 511 case "summary.code": 512 return Integer.toString(getSummaryCode()); 513 case "summary.stack": 514 return Integer.toString(getSummaryStack()); 515 case "summary.graphics": 516 return Integer.toString(getSummaryGraphics()); 517 case "summary.private-other": 518 return Integer.toString(getSummaryPrivateOther()); 519 case "summary.system": 520 return Integer.toString(getSummarySystem()); 521 case "summary.total-pss": 522 return Integer.toString(getSummaryTotalPss()); 523 case "summary.total-swap": 524 return Integer.toString(getSummaryTotalSwap()); 525 default: 526 return null; 527 } 528 } 529 530 /** 531 * Returns a map of the names/values of the memory statistics 532 * that {@link #getMemoryStat(String)} supports. 533 * 534 * @return a map of the names/values of the supported memory statistics. 535 */ 536 public Map<String, String> getMemoryStats() { 537 Map<String, String> stats = new HashMap<String, String>(); 538 stats.put("summary.java-heap", Integer.toString(getSummaryJavaHeap())); 539 stats.put("summary.native-heap", Integer.toString(getSummaryNativeHeap())); 540 stats.put("summary.code", Integer.toString(getSummaryCode())); 541 stats.put("summary.stack", Integer.toString(getSummaryStack())); 542 stats.put("summary.graphics", Integer.toString(getSummaryGraphics())); 543 stats.put("summary.private-other", Integer.toString(getSummaryPrivateOther())); 544 stats.put("summary.system", Integer.toString(getSummarySystem())); 545 stats.put("summary.total-pss", Integer.toString(getSummaryTotalPss())); 546 stats.put("summary.total-swap", Integer.toString(getSummaryTotalSwap())); 547 return stats; 548 } 549 550 /** 551 * Pss of Java Heap bytes in KB due to the application. 552 * Notes: 553 * * OTHER_ART is the boot image. Anything private here is blamed on 554 * the application, not the system. 555 * * dalvikPrivateDirty includes private zygote, which means the 556 * application dirtied something allocated by the zygote. We blame 557 * the application for that memory, not the system. 558 * * Does not include OTHER_DALVIK_OTHER, which is considered VM 559 * Overhead and lumped into Private Other. 560 * * We don't include dalvikPrivateClean, because there should be no 561 * such thing as private clean for the Java Heap. 562 * @hide 563 */ 564 public int getSummaryJavaHeap() { 565 return dalvikPrivateDirty + getOtherPrivate(OTHER_ART); 566 } 567 568 /** 569 * Pss of Native Heap bytes in KB due to the application. 570 * Notes: 571 * * Includes private dirty malloc space. 572 * * We don't include nativePrivateClean, because there should be no 573 * such thing as private clean for the Native Heap. 574 * @hide 575 */ 576 public int getSummaryNativeHeap() { 577 return nativePrivateDirty; 578 } 579 580 /** 581 * Pss of code and other static resource bytes in KB due to 582 * the application. 583 * @hide 584 */ 585 public int getSummaryCode() { 586 return getOtherPrivate(OTHER_SO) 587 + getOtherPrivate(OTHER_JAR) 588 + getOtherPrivate(OTHER_APK) 589 + getOtherPrivate(OTHER_TTF) 590 + getOtherPrivate(OTHER_DEX) 591 + getOtherPrivate(OTHER_OAT); 592 } 593 594 /** 595 * Pss in KB of the stack due to the application. 596 * Notes: 597 * * Includes private dirty stack, which includes both Java and Native 598 * stack. 599 * * Does not include private clean stack, because there should be no 600 * such thing as private clean for the stack. 601 * @hide 602 */ 603 public int getSummaryStack() { 604 return getOtherPrivateDirty(OTHER_STACK); 605 } 606 607 /** 608 * Pss in KB of graphics due to the application. 609 * Notes: 610 * * Includes private Gfx, EGL, and GL. 611 * * Warning: These numbers can be misreported by the graphics drivers. 612 * * We don't include shared graphics. It may make sense to, because 613 * shared graphics are likely buffers due to the application 614 * anyway, but it's simpler to implement to just group all shared 615 * memory into the System category. 616 * @hide 617 */ 618 public int getSummaryGraphics() { 619 return getOtherPrivate(OTHER_GL_DEV) 620 + getOtherPrivate(OTHER_GRAPHICS) 621 + getOtherPrivate(OTHER_GL); 622 } 623 624 /** 625 * Pss in KB due to the application that haven't otherwise been 626 * accounted for. 627 * @hide 628 */ 629 public int getSummaryPrivateOther() { 630 return getTotalPrivateClean() 631 + getTotalPrivateDirty() 632 - getSummaryJavaHeap() 633 - getSummaryNativeHeap() 634 - getSummaryCode() 635 - getSummaryStack() 636 - getSummaryGraphics(); 637 } 638 639 /** 640 * Pss in KB due to the system. 641 * Notes: 642 * * Includes all shared memory. 643 * @hide 644 */ 645 public int getSummarySystem() { 646 return getTotalPss() 647 - getTotalPrivateClean() 648 - getTotalPrivateDirty(); 649 } 650 651 /** 652 * Total Pss in KB. 653 * @hide 654 */ 655 public int getSummaryTotalPss() { 656 return getTotalPss(); 657 } 658 659 /** 660 * Total Swap in KB. 661 * Notes: 662 * * Some of this memory belongs in other categories, but we don't 663 * know if the Swap memory is shared or private, so we don't know 664 * what to blame on the application and what on the system. 665 * For now, just lump all the Swap in one place. 666 * For kernels reporting SwapPss {@link #getSummaryTotalSwapPss()} 667 * will report the application proportional Swap. 668 * @hide 669 */ 670 public int getSummaryTotalSwap() { 671 return getTotalSwappedOut(); 672 } 673 674 /** 675 * Total proportional Swap in KB. 676 * Notes: 677 * * Always 0 if {@link #hasSwappedOutPss} is false. 678 * @hide 679 */ 680 public int getSummaryTotalSwapPss() { 681 return getTotalSwappedOutPss(); 682 } 683 684 public int describeContents() { 685 return 0; 686 } 687 688 public void writeToParcel(Parcel dest, int flags) { 689 dest.writeInt(dalvikPss); 690 dest.writeInt(dalvikSwappablePss); 691 dest.writeInt(dalvikPrivateDirty); 692 dest.writeInt(dalvikSharedDirty); 693 dest.writeInt(dalvikPrivateClean); 694 dest.writeInt(dalvikSharedClean); 695 dest.writeInt(dalvikSwappedOut); 696 dest.writeInt(nativePss); 697 dest.writeInt(nativeSwappablePss); 698 dest.writeInt(nativePrivateDirty); 699 dest.writeInt(nativeSharedDirty); 700 dest.writeInt(nativePrivateClean); 701 dest.writeInt(nativeSharedClean); 702 dest.writeInt(nativeSwappedOut); 703 dest.writeInt(otherPss); 704 dest.writeInt(otherSwappablePss); 705 dest.writeInt(otherPrivateDirty); 706 dest.writeInt(otherSharedDirty); 707 dest.writeInt(otherPrivateClean); 708 dest.writeInt(otherSharedClean); 709 dest.writeInt(otherSwappedOut); 710 dest.writeInt(hasSwappedOutPss ? 1 : 0); 711 dest.writeInt(otherSwappedOutPss); 712 dest.writeIntArray(otherStats); 713 } 714 715 public void readFromParcel(Parcel source) { 716 dalvikPss = source.readInt(); 717 dalvikSwappablePss = source.readInt(); 718 dalvikPrivateDirty = source.readInt(); 719 dalvikSharedDirty = source.readInt(); 720 dalvikPrivateClean = source.readInt(); 721 dalvikSharedClean = source.readInt(); 722 dalvikSwappedOut = source.readInt(); 723 nativePss = source.readInt(); 724 nativeSwappablePss = source.readInt(); 725 nativePrivateDirty = source.readInt(); 726 nativeSharedDirty = source.readInt(); 727 nativePrivateClean = source.readInt(); 728 nativeSharedClean = source.readInt(); 729 nativeSwappedOut = source.readInt(); 730 otherPss = source.readInt(); 731 otherSwappablePss = source.readInt(); 732 otherPrivateDirty = source.readInt(); 733 otherSharedDirty = source.readInt(); 734 otherPrivateClean = source.readInt(); 735 otherSharedClean = source.readInt(); 736 otherSwappedOut = source.readInt(); 737 hasSwappedOutPss = source.readInt() != 0; 738 otherSwappedOutPss = source.readInt(); 739 otherStats = source.createIntArray(); 740 } 741 742 public static final Creator<MemoryInfo> CREATOR = new Creator<MemoryInfo>() { 743 public MemoryInfo createFromParcel(Parcel source) { 744 return new MemoryInfo(source); 745 } 746 public MemoryInfo[] newArray(int size) { 747 return new MemoryInfo[size]; 748 } 749 }; 750 751 private MemoryInfo(Parcel source) { 752 readFromParcel(source); 753 } 754 } 755 756 757 /** 758 * Wait until a debugger attaches. As soon as the debugger attaches, 759 * this returns, so you will need to place a breakpoint after the 760 * waitForDebugger() call if you want to start tracing immediately. 761 */ 762 public static void waitForDebugger() { 763 if (!VMDebug.isDebuggingEnabled()) { 764 //System.out.println("debugging not enabled, not waiting"); 765 return; 766 } 767 if (isDebuggerConnected()) 768 return; 769 770 // if DDMS is listening, inform them of our plight 771 System.out.println("Sending WAIT chunk"); 772 byte[] data = new byte[] { 0 }; // 0 == "waiting for debugger" 773 Chunk waitChunk = new Chunk(ChunkHandler.type("WAIT"), data, 0, 1); 774 DdmServer.sendChunk(waitChunk); 775 776 mWaiting = true; 777 while (!isDebuggerConnected()) { 778 try { Thread.sleep(SPIN_DELAY); } 779 catch (InterruptedException ie) {} 780 } 781 mWaiting = false; 782 783 System.out.println("Debugger has connected"); 784 785 /* 786 * There is no "ready to go" signal from the debugger, and we're 787 * not allowed to suspend ourselves -- the debugger expects us to 788 * be running happily, and gets confused if we aren't. We need to 789 * allow the debugger a chance to set breakpoints before we start 790 * running again. 791 * 792 * Sit and spin until the debugger has been idle for a short while. 793 */ 794 while (true) { 795 long delta = VMDebug.lastDebuggerActivity(); 796 if (delta < 0) { 797 System.out.println("debugger detached?"); 798 break; 799 } 800 801 if (delta < MIN_DEBUGGER_IDLE) { 802 System.out.println("waiting for debugger to settle..."); 803 try { Thread.sleep(SPIN_DELAY); } 804 catch (InterruptedException ie) {} 805 } else { 806 System.out.println("debugger has settled (" + delta + ")"); 807 break; 808 } 809 } 810 } 811 812 /** 813 * Returns "true" if one or more threads is waiting for a debugger 814 * to attach. 815 */ 816 public static boolean waitingForDebugger() { 817 return mWaiting; 818 } 819 820 /** 821 * Determine if a debugger is currently attached. 822 */ 823 public static boolean isDebuggerConnected() { 824 return VMDebug.isDebuggerConnected(); 825 } 826 827 /** 828 * Returns an array of strings that identify VM features. This is 829 * used by DDMS to determine what sorts of operations the VM can 830 * perform. 831 * 832 * @hide 833 */ 834 public static String[] getVmFeatureList() { 835 return VMDebug.getVmFeatureList(); 836 } 837 838 /** 839 * Change the JDWP port. 840 * 841 * @deprecated no longer needed or useful 842 */ 843 @Deprecated 844 public static void changeDebugPort(int port) {} 845 846 /** 847 * This is the pathname to the sysfs file that enables and disables 848 * tracing on the qemu emulator. 849 */ 850 private static final String SYSFS_QEMU_TRACE_STATE = "/sys/qemu_trace/state"; 851 852 /** 853 * Enable qemu tracing. For this to work requires running everything inside 854 * the qemu emulator; otherwise, this method will have no effect. The trace 855 * file is specified on the command line when the emulator is started. For 856 * example, the following command line <br /> 857 * <code>emulator -trace foo</code><br /> 858 * will start running the emulator and create a trace file named "foo". This 859 * method simply enables writing the trace records to the trace file. 860 * 861 * <p> 862 * The main differences between this and {@link #startMethodTracing()} are 863 * that tracing in the qemu emulator traces every cpu instruction of every 864 * process, including kernel code, so we have more complete information, 865 * including all context switches. We can also get more detailed information 866 * such as cache misses. The sequence of calls is determined by 867 * post-processing the instruction trace. The qemu tracing is also done 868 * without modifying the application or perturbing the timing of calls 869 * because no instrumentation is added to the application being traced. 870 * </p> 871 * 872 * <p> 873 * One limitation of using this method compared to using 874 * {@link #startMethodTracing()} on the real device is that the emulator 875 * does not model all of the real hardware effects such as memory and 876 * bus contention. The emulator also has a simple cache model and cannot 877 * capture all the complexities of a real cache. 878 * </p> 879 */ 880 public static void startNativeTracing() { 881 // Open the sysfs file for writing and write "1" to it. 882 PrintWriter outStream = null; 883 try { 884 FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE); 885 outStream = new FastPrintWriter(fos); 886 outStream.println("1"); 887 } catch (Exception e) { 888 } finally { 889 if (outStream != null) 890 outStream.close(); 891 } 892 893 VMDebug.startEmulatorTracing(); 894 } 895 896 /** 897 * Stop qemu tracing. See {@link #startNativeTracing()} to start tracing. 898 * 899 * <p>Tracing can be started and stopped as many times as desired. When 900 * the qemu emulator itself is stopped then the buffered trace records 901 * are flushed and written to the trace file. In fact, it is not necessary 902 * to call this method at all; simply killing qemu is sufficient. But 903 * starting and stopping a trace is useful for examining a specific 904 * region of code.</p> 905 */ 906 public static void stopNativeTracing() { 907 VMDebug.stopEmulatorTracing(); 908 909 // Open the sysfs file for writing and write "0" to it. 910 PrintWriter outStream = null; 911 try { 912 FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE); 913 outStream = new FastPrintWriter(fos); 914 outStream.println("0"); 915 } catch (Exception e) { 916 // We could print an error message here but we probably want 917 // to quietly ignore errors if we are not running in the emulator. 918 } finally { 919 if (outStream != null) 920 outStream.close(); 921 } 922 } 923 924 /** 925 * Enable "emulator traces", in which information about the current 926 * method is made available to the "emulator -trace" feature. There 927 * is no corresponding "disable" call -- this is intended for use by 928 * the framework when tracing should be turned on and left that way, so 929 * that traces captured with F9/F10 will include the necessary data. 930 * 931 * This puts the VM into "profile" mode, which has performance 932 * consequences. 933 * 934 * To temporarily enable tracing, use {@link #startNativeTracing()}. 935 */ 936 public static void enableEmulatorTraceOutput() { 937 VMDebug.startEmulatorTracing(); 938 } 939 940 /** 941 * Start method tracing with default log name and buffer size. See <a 942href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for 943 * information about reading these files. Call stopMethodTracing() to stop 944 * tracing. 945 */ 946 public static void startMethodTracing() { 947 VMDebug.startMethodTracing(fixTraceName(null), 0, 0, false, 0); 948 } 949 950 /** 951 * Start method tracing, specifying the trace log file name. The trace 952 * file will be put under "/sdcard" unless an absolute path is given. 953 * See <a 954 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for 955 * information about reading trace files. 956 * 957 * @param traceName Name for the trace log file to create. 958 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace". 959 * If the files already exist, they will be truncated. 960 * If the trace file given does not end in ".trace", it will be appended for you. 961 */ 962 public static void startMethodTracing(String traceName) { 963 startMethodTracing(traceName, 0, 0); 964 } 965 966 /** 967 * Start method tracing, specifying the trace log file name and the 968 * buffer size. The trace files will be put under "/sdcard" unless an 969 * absolute path is given. See <a 970 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for 971 * information about reading trace files. 972 * @param traceName Name for the trace log file to create. 973 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace". 974 * If the files already exist, they will be truncated. 975 * If the trace file given does not end in ".trace", it will be appended for you. 976 * 977 * @param bufferSize The maximum amount of trace data we gather. If not given, it defaults to 8MB. 978 */ 979 public static void startMethodTracing(String traceName, int bufferSize) { 980 startMethodTracing(traceName, bufferSize, 0); 981 } 982 983 /** 984 * Start method tracing, specifying the trace log file name and the 985 * buffer size. The trace files will be put under "/sdcard" unless an 986 * absolute path is given. See <a 987 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for 988 * information about reading trace files. 989 * 990 * <p> 991 * When method tracing is enabled, the VM will run more slowly than 992 * usual, so the timings from the trace files should only be considered 993 * in relative terms (e.g. was run #1 faster than run #2). The times 994 * for native methods will not change, so don't try to use this to 995 * compare the performance of interpreted and native implementations of the 996 * same method. As an alternative, consider using sampling-based method 997 * tracing via {@link #startMethodTracingSampling(String, int, int)} or 998 * "native" tracing in the emulator via {@link #startNativeTracing()}. 999 * </p> 1000 * 1001 * @param traceName Name for the trace log file to create. 1002 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace". 1003 * If the files already exist, they will be truncated. 1004 * If the trace file given does not end in ".trace", it will be appended for you. 1005 * @param bufferSize The maximum amount of trace data we gather. If not given, it defaults to 8MB. 1006 * @param flags Flags to control method tracing. The only one that is currently defined is {@link #TRACE_COUNT_ALLOCS}. 1007 */ 1008 public static void startMethodTracing(String traceName, int bufferSize, 1009 int flags) { 1010 VMDebug.startMethodTracing(fixTraceName(traceName), bufferSize, flags, false, 0); 1011 } 1012 1013 /** 1014 * Start sampling-based method tracing, specifying the trace log file name, 1015 * the buffer size, and the sampling interval. The trace files will be put 1016 * under "/sdcard" unless an absolute path is given. See <a 1017 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> 1018 * for information about reading trace files. 1019 * 1020 * @param traceName Name for the trace log file to create. 1021 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace". 1022 * If the files already exist, they will be truncated. 1023 * If the trace file given does not end in ".trace", it will be appended for you. 1024 * @param bufferSize The maximum amount of trace data we gather. If not given, it defaults to 8MB. 1025 * @param intervalUs The amount of time between each sample in microseconds. 1026 */ 1027 public static void startMethodTracingSampling(String traceName, 1028 int bufferSize, int intervalUs) { 1029 VMDebug.startMethodTracing(fixTraceName(traceName), bufferSize, 0, true, intervalUs); 1030 } 1031 1032 /** 1033 * Formats name of trace log file for method tracing. 1034 */ 1035 private static String fixTraceName(String traceName) { 1036 if (traceName == null) 1037 traceName = NoPreloadHolder.DEFAULT_TRACE_FILE_PATH; 1038 if (traceName.charAt(0) != '/') 1039 traceName = NoPreloadHolder.DEFAULT_TRACE_PATH_PREFIX + traceName; 1040 if (!traceName.endsWith(DEFAULT_TRACE_EXTENSION)) 1041 traceName = traceName + DEFAULT_TRACE_EXTENSION; 1042 1043 return traceName; 1044 } 1045 1046 /** 1047 * Like startMethodTracing(String, int, int), but taking an already-opened 1048 * FileDescriptor in which the trace is written. The file name is also 1049 * supplied simply for logging. Makes a dup of the file descriptor. 1050 * 1051 * Not exposed in the SDK unless we are really comfortable with supporting 1052 * this and find it would be useful. 1053 * @hide 1054 */ 1055 public static void startMethodTracing(String traceName, FileDescriptor fd, 1056 int bufferSize, int flags) { 1057 VMDebug.startMethodTracing(traceName, fd, bufferSize, flags, false, 0); 1058 } 1059 1060 /** 1061 * Starts method tracing without a backing file. When stopMethodTracing 1062 * is called, the result is sent directly to DDMS. (If DDMS is not 1063 * attached when tracing ends, the profiling data will be discarded.) 1064 * 1065 * @hide 1066 */ 1067 public static void startMethodTracingDdms(int bufferSize, int flags, 1068 boolean samplingEnabled, int intervalUs) { 1069 VMDebug.startMethodTracingDdms(bufferSize, flags, samplingEnabled, intervalUs); 1070 } 1071 1072 /** 1073 * Determine whether method tracing is currently active and what type is 1074 * active. 1075 * 1076 * @hide 1077 */ 1078 public static int getMethodTracingMode() { 1079 return VMDebug.getMethodTracingMode(); 1080 } 1081 1082 /** 1083 * Stop method tracing. 1084 */ 1085 public static void stopMethodTracing() { 1086 VMDebug.stopMethodTracing(); 1087 } 1088 1089 /** 1090 * Get an indication of thread CPU usage. The value returned 1091 * indicates the amount of time that the current thread has spent 1092 * executing code or waiting for certain types of I/O. 1093 * 1094 * The time is expressed in nanoseconds, and is only meaningful 1095 * when compared to the result from an earlier call. Note that 1096 * nanosecond resolution does not imply nanosecond accuracy. 1097 * 1098 * On system which don't support this operation, the call returns -1. 1099 */ 1100 public static long threadCpuTimeNanos() { 1101 return VMDebug.threadCpuTimeNanos(); 1102 } 1103 1104 /** 1105 * Start counting the number and aggregate size of memory allocations. 1106 * 1107 * <p>The {@link #startAllocCounting() start} method resets the counts and enables counting. 1108 * The {@link #stopAllocCounting() stop} method disables the counting so that the analysis 1109 * code doesn't cause additional allocations. The various <code>get</code> methods return 1110 * the specified value. And the various <code>reset</code> methods reset the specified 1111 * count.</p> 1112 * 1113 * <p>Counts are kept for the system as a whole (global) and for each thread. 1114 * The per-thread counts for threads other than the current thread 1115 * are not cleared by the "reset" or "start" calls.</p> 1116 * 1117 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1118 */ 1119 @Deprecated 1120 public static void startAllocCounting() { 1121 VMDebug.startAllocCounting(); 1122 } 1123 1124 /** 1125 * Stop counting the number and aggregate size of memory allocations. 1126 * 1127 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1128 */ 1129 @Deprecated 1130 public static void stopAllocCounting() { 1131 VMDebug.stopAllocCounting(); 1132 } 1133 1134 /** 1135 * Returns the global count of objects allocated by the runtime between a 1136 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1137 * 1138 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1139 */ 1140 @Deprecated 1141 public static int getGlobalAllocCount() { 1142 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS); 1143 } 1144 1145 /** 1146 * Clears the global count of objects allocated. 1147 * @see #getGlobalAllocCount() 1148 * 1149 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1150 */ 1151 @Deprecated 1152 public static void resetGlobalAllocCount() { 1153 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS); 1154 } 1155 1156 /** 1157 * Returns the global size, in bytes, of objects allocated by the runtime between a 1158 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1159 * 1160 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1161 */ 1162 @Deprecated 1163 public static int getGlobalAllocSize() { 1164 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES); 1165 } 1166 1167 /** 1168 * Clears the global size of objects allocated. 1169 * @see #getGlobalAllocSize() 1170 * 1171 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1172 */ 1173 @Deprecated 1174 public static void resetGlobalAllocSize() { 1175 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES); 1176 } 1177 1178 /** 1179 * Returns the global count of objects freed by the runtime between a 1180 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1181 * 1182 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1183 */ 1184 @Deprecated 1185 public static int getGlobalFreedCount() { 1186 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS); 1187 } 1188 1189 /** 1190 * Clears the global count of objects freed. 1191 * @see #getGlobalFreedCount() 1192 * 1193 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1194 */ 1195 @Deprecated 1196 public static void resetGlobalFreedCount() { 1197 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS); 1198 } 1199 1200 /** 1201 * Returns the global size, in bytes, of objects freed by the runtime between a 1202 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1203 * 1204 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1205 */ 1206 @Deprecated 1207 public static int getGlobalFreedSize() { 1208 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES); 1209 } 1210 1211 /** 1212 * Clears the global size of objects freed. 1213 * @see #getGlobalFreedSize() 1214 * 1215 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1216 */ 1217 @Deprecated 1218 public static void resetGlobalFreedSize() { 1219 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES); 1220 } 1221 1222 /** 1223 * Returns the number of non-concurrent GC invocations between a 1224 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1225 * 1226 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1227 */ 1228 @Deprecated 1229 public static int getGlobalGcInvocationCount() { 1230 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS); 1231 } 1232 1233 /** 1234 * Clears the count of non-concurrent GC invocations. 1235 * @see #getGlobalGcInvocationCount() 1236 * 1237 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1238 */ 1239 @Deprecated 1240 public static void resetGlobalGcInvocationCount() { 1241 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS); 1242 } 1243 1244 /** 1245 * Returns the number of classes successfully initialized (ie those that executed without 1246 * throwing an exception) between a {@link #startAllocCounting() start} and 1247 * {@link #stopAllocCounting() stop}. 1248 * 1249 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1250 */ 1251 @Deprecated 1252 public static int getGlobalClassInitCount() { 1253 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT); 1254 } 1255 1256 /** 1257 * Clears the count of classes initialized. 1258 * @see #getGlobalClassInitCount() 1259 * 1260 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1261 */ 1262 @Deprecated 1263 public static void resetGlobalClassInitCount() { 1264 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT); 1265 } 1266 1267 /** 1268 * Returns the time spent successfully initializing classes between a 1269 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1270 * 1271 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1272 */ 1273 @Deprecated 1274 public static int getGlobalClassInitTime() { 1275 /* cumulative elapsed time for class initialization, in usec */ 1276 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME); 1277 } 1278 1279 /** 1280 * Clears the count of time spent initializing classes. 1281 * @see #getGlobalClassInitTime() 1282 * 1283 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1284 */ 1285 @Deprecated 1286 public static void resetGlobalClassInitTime() { 1287 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME); 1288 } 1289 1290 /** 1291 * This method exists for compatibility and always returns 0. 1292 * @deprecated This method is now obsolete. 1293 */ 1294 @Deprecated 1295 public static int getGlobalExternalAllocCount() { 1296 return 0; 1297 } 1298 1299 /** 1300 * This method exists for compatibility and has no effect. 1301 * @deprecated This method is now obsolete. 1302 */ 1303 @Deprecated 1304 public static void resetGlobalExternalAllocSize() {} 1305 1306 /** 1307 * This method exists for compatibility and has no effect. 1308 * @deprecated This method is now obsolete. 1309 */ 1310 @Deprecated 1311 public static void resetGlobalExternalAllocCount() {} 1312 1313 /** 1314 * This method exists for compatibility and always returns 0. 1315 * @deprecated This method is now obsolete. 1316 */ 1317 @Deprecated 1318 public static int getGlobalExternalAllocSize() { 1319 return 0; 1320 } 1321 1322 /** 1323 * This method exists for compatibility and always returns 0. 1324 * @deprecated This method is now obsolete. 1325 */ 1326 @Deprecated 1327 public static int getGlobalExternalFreedCount() { 1328 return 0; 1329 } 1330 1331 /** 1332 * This method exists for compatibility and has no effect. 1333 * @deprecated This method is now obsolete. 1334 */ 1335 @Deprecated 1336 public static void resetGlobalExternalFreedCount() {} 1337 1338 /** 1339 * This method exists for compatibility and has no effect. 1340 * @deprecated This method is now obsolete. 1341 */ 1342 @Deprecated 1343 public static int getGlobalExternalFreedSize() { 1344 return 0; 1345 } 1346 1347 /** 1348 * This method exists for compatibility and has no effect. 1349 * @deprecated This method is now obsolete. 1350 */ 1351 @Deprecated 1352 public static void resetGlobalExternalFreedSize() {} 1353 1354 /** 1355 * Returns the thread-local count of objects allocated by the runtime between a 1356 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1357 * 1358 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1359 */ 1360 @Deprecated 1361 public static int getThreadAllocCount() { 1362 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS); 1363 } 1364 1365 /** 1366 * Clears the thread-local count of objects allocated. 1367 * @see #getThreadAllocCount() 1368 * 1369 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1370 */ 1371 @Deprecated 1372 public static void resetThreadAllocCount() { 1373 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS); 1374 } 1375 1376 /** 1377 * Returns the thread-local size of objects allocated by the runtime between a 1378 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1379 * @return The allocated size in bytes. 1380 * 1381 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1382 */ 1383 @Deprecated 1384 public static int getThreadAllocSize() { 1385 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES); 1386 } 1387 1388 /** 1389 * Clears the thread-local count of objects allocated. 1390 * @see #getThreadAllocSize() 1391 * 1392 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1393 */ 1394 @Deprecated 1395 public static void resetThreadAllocSize() { 1396 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES); 1397 } 1398 1399 /** 1400 * This method exists for compatibility and has no effect. 1401 * @deprecated This method is now obsolete. 1402 */ 1403 @Deprecated 1404 public static int getThreadExternalAllocCount() { 1405 return 0; 1406 } 1407 1408 /** 1409 * This method exists for compatibility and has no effect. 1410 * @deprecated This method is now obsolete. 1411 */ 1412 @Deprecated 1413 public static void resetThreadExternalAllocCount() {} 1414 1415 /** 1416 * This method exists for compatibility and has no effect. 1417 * @deprecated This method is now obsolete. 1418 */ 1419 @Deprecated 1420 public static int getThreadExternalAllocSize() { 1421 return 0; 1422 } 1423 1424 /** 1425 * This method exists for compatibility and has no effect. 1426 * @deprecated This method is now obsolete. 1427 */ 1428 @Deprecated 1429 public static void resetThreadExternalAllocSize() {} 1430 1431 /** 1432 * Returns the number of thread-local non-concurrent GC invocations between a 1433 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1434 * 1435 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1436 */ 1437 @Deprecated 1438 public static int getThreadGcInvocationCount() { 1439 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS); 1440 } 1441 1442 /** 1443 * Clears the thread-local count of non-concurrent GC invocations. 1444 * @see #getThreadGcInvocationCount() 1445 * 1446 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1447 */ 1448 @Deprecated 1449 public static void resetThreadGcInvocationCount() { 1450 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS); 1451 } 1452 1453 /** 1454 * Clears all the global and thread-local memory allocation counters. 1455 * @see #startAllocCounting() 1456 * 1457 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1458 */ 1459 @Deprecated 1460 public static void resetAllCounts() { 1461 VMDebug.resetAllocCount(VMDebug.KIND_ALL_COUNTS); 1462 } 1463 1464 /** 1465 * Returns the value of a particular runtime statistic or {@code null} if no 1466 * such runtime statistic exists. 1467 * 1468 * <p>The following table lists the runtime statistics that the runtime supports. 1469 * Note runtime statistics may be added or removed in a future API level.</p> 1470 * 1471 * <table> 1472 * <thead> 1473 * <tr> 1474 * <th>Runtime statistic name</th> 1475 * <th>Meaning</th> 1476 * <th>Example</th> 1477 * <th>Supported (API Levels)</th> 1478 * </tr> 1479 * </thead> 1480 * <tbody> 1481 * <tr> 1482 * <td>art.gc.gc-count</td> 1483 * <td>The number of garbage collection runs.</td> 1484 * <td>{@code 164}</td> 1485 * <td>23</td> 1486 * </tr> 1487 * <tr> 1488 * <td>art.gc.gc-time</td> 1489 * <td>The total duration of garbage collection runs in ms.</td> 1490 * <td>{@code 62364}</td> 1491 * <td>23</td> 1492 * </tr> 1493 * <tr> 1494 * <td>art.gc.bytes-allocated</td> 1495 * <td>The total number of bytes that the application allocated.</td> 1496 * <td>{@code 1463948408}</td> 1497 * <td>23</td> 1498 * </tr> 1499 * <tr> 1500 * <td>art.gc.bytes-freed</td> 1501 * <td>The total number of bytes that garbage collection reclaimed.</td> 1502 * <td>{@code 1313493084}</td> 1503 * <td>23</td> 1504 * </tr> 1505 * <tr> 1506 * <td>art.gc.blocking-gc-count</td> 1507 * <td>The number of blocking garbage collection runs.</td> 1508 * <td>{@code 2}</td> 1509 * <td>23</td> 1510 * </tr> 1511 * <tr> 1512 * <td>art.gc.blocking-gc-time</td> 1513 * <td>The total duration of blocking garbage collection runs in ms.</td> 1514 * <td>{@code 804}</td> 1515 * <td>23</td> 1516 * </tr> 1517 * <tr> 1518 * <td>art.gc.gc-count-rate-histogram</td> 1519 * <td>Every 10 seconds, the gc-count-rate is computed as the number of garbage 1520 * collection runs that have occurred over the last 10 1521 * seconds. art.gc.gc-count-rate-histogram is a histogram of the gc-count-rate 1522 * samples taken since the process began. The histogram can be used to identify 1523 * instances of high rates of garbage collection runs. For example, a histogram 1524 * of "0:34503,1:45350,2:11281,3:8088,4:43,5:8" shows that most of the time 1525 * there are between 0 and 2 garbage collection runs every 10 seconds, but there 1526 * were 8 distinct 10-second intervals in which 5 garbage collection runs 1527 * occurred.</td> 1528 * <td>{@code 0:34503,1:45350,2:11281,3:8088,4:43,5:8}</td> 1529 * <td>23</td> 1530 * </tr> 1531 * <tr> 1532 * <td>art.gc.blocking-gc-count-rate-histogram</td> 1533 * <td>Every 10 seconds, the blocking-gc-count-rate is computed as the number of 1534 * blocking garbage collection runs that have occurred over the last 10 1535 * seconds. art.gc.blocking-gc-count-rate-histogram is a histogram of the 1536 * blocking-gc-count-rate samples taken since the process began. The histogram 1537 * can be used to identify instances of high rates of blocking garbage 1538 * collection runs. For example, a histogram of "0:99269,1:1,2:1" shows that 1539 * most of the time there are zero blocking garbage collection runs every 10 1540 * seconds, but there was one 10-second interval in which one blocking garbage 1541 * collection run occurred, and there was one interval in which two blocking 1542 * garbage collection runs occurred.</td> 1543 * <td>{@code 0:99269,1:1,2:1}</td> 1544 * <td>23</td> 1545 * </tr> 1546 * </tbody> 1547 * </table> 1548 * 1549 * @param statName 1550 * the name of the runtime statistic to look up. 1551 * @return the value of the specified runtime statistic or {@code null} if the 1552 * runtime statistic doesn't exist. 1553 */ 1554 public static String getRuntimeStat(String statName) { 1555 return VMDebug.getRuntimeStat(statName); 1556 } 1557 1558 /** 1559 * Returns a map of the names/values of the runtime statistics 1560 * that {@link #getRuntimeStat(String)} supports. 1561 * 1562 * @return a map of the names/values of the supported runtime statistics. 1563 */ 1564 public static Map<String, String> getRuntimeStats() { 1565 return VMDebug.getRuntimeStats(); 1566 } 1567 1568 /** 1569 * Returns the size of the native heap. 1570 * @return The size of the native heap in bytes. 1571 */ 1572 public static native long getNativeHeapSize(); 1573 1574 /** 1575 * Returns the amount of allocated memory in the native heap. 1576 * @return The allocated size in bytes. 1577 */ 1578 public static native long getNativeHeapAllocatedSize(); 1579 1580 /** 1581 * Returns the amount of free memory in the native heap. 1582 * @return The freed size in bytes. 1583 */ 1584 public static native long getNativeHeapFreeSize(); 1585 1586 /** 1587 * Retrieves information about this processes memory usages. This information is broken down by 1588 * how much is in use by dalvik, the native heap, and everything else. 1589 * 1590 * <p><b>Note:</b> this method directly retrieves memory information for the give process 1591 * from low-level data available to it. It may not be able to retrieve information about 1592 * some protected allocations, such as graphics. If you want to be sure you can see 1593 * all information about allocations by the process, use instead 1594 * {@link android.app.ActivityManager#getProcessMemoryInfo(int[])}.</p> 1595 */ 1596 public static native void getMemoryInfo(MemoryInfo memoryInfo); 1597 1598 /** 1599 * Note: currently only works when the requested pid has the same UID 1600 * as the caller. 1601 * @hide 1602 */ 1603 public static native void getMemoryInfo(int pid, MemoryInfo memoryInfo); 1604 1605 /** 1606 * Retrieves the PSS memory used by the process as given by the 1607 * smaps. 1608 */ 1609 public static native long getPss(); 1610 1611 /** 1612 * Retrieves the PSS memory used by the process as given by the 1613 * smaps. Optionally supply a long array of 2 entries to also 1614 * receive the Uss and SwapPss of the process, and another array to also 1615 * retrieve the separate memtrack size. 1616 * @hide 1617 */ 1618 public static native long getPss(int pid, long[] outUssSwapPss, long[] outMemtrack); 1619 1620 /** @hide */ 1621 public static final int MEMINFO_TOTAL = 0; 1622 /** @hide */ 1623 public static final int MEMINFO_FREE = 1; 1624 /** @hide */ 1625 public static final int MEMINFO_BUFFERS = 2; 1626 /** @hide */ 1627 public static final int MEMINFO_CACHED = 3; 1628 /** @hide */ 1629 public static final int MEMINFO_SHMEM = 4; 1630 /** @hide */ 1631 public static final int MEMINFO_SLAB = 5; 1632 /** @hide */ 1633 public static final int MEMINFO_SWAP_TOTAL = 6; 1634 /** @hide */ 1635 public static final int MEMINFO_SWAP_FREE = 7; 1636 /** @hide */ 1637 public static final int MEMINFO_ZRAM_TOTAL = 8; 1638 /** @hide */ 1639 public static final int MEMINFO_MAPPED = 9; 1640 /** @hide */ 1641 public static final int MEMINFO_VM_ALLOC_USED = 10; 1642 /** @hide */ 1643 public static final int MEMINFO_PAGE_TABLES = 11; 1644 /** @hide */ 1645 public static final int MEMINFO_KERNEL_STACK = 12; 1646 /** @hide */ 1647 public static final int MEMINFO_COUNT = 13; 1648 1649 /** 1650 * Retrieves /proc/meminfo. outSizes is filled with fields 1651 * as defined by MEMINFO_* offsets. 1652 * @hide 1653 */ 1654 public static native void getMemInfo(long[] outSizes); 1655 1656 /** 1657 * Establish an object allocation limit in the current thread. 1658 * This feature was never enabled in release builds. The 1659 * allocation limits feature was removed in Honeycomb. This 1660 * method exists for compatibility and always returns -1 and has 1661 * no effect. 1662 * 1663 * @deprecated This method is now obsolete. 1664 */ 1665 @Deprecated 1666 public static int setAllocationLimit(int limit) { 1667 return -1; 1668 } 1669 1670 /** 1671 * Establish a global object allocation limit. This feature was 1672 * never enabled in release builds. The allocation limits feature 1673 * was removed in Honeycomb. This method exists for compatibility 1674 * and always returns -1 and has no effect. 1675 * 1676 * @deprecated This method is now obsolete. 1677 */ 1678 @Deprecated 1679 public static int setGlobalAllocationLimit(int limit) { 1680 return -1; 1681 } 1682 1683 /** 1684 * Dump a list of all currently loaded class to the log file. 1685 * 1686 * @param flags See constants above. 1687 */ 1688 public static void printLoadedClasses(int flags) { 1689 VMDebug.printLoadedClasses(flags); 1690 } 1691 1692 /** 1693 * Get the number of loaded classes. 1694 * @return the number of loaded classes. 1695 */ 1696 public static int getLoadedClassCount() { 1697 return VMDebug.getLoadedClassCount(); 1698 } 1699 1700 /** 1701 * Dump "hprof" data to the specified file. This may cause a GC. 1702 * 1703 * @param fileName Full pathname of output file (e.g. "/sdcard/dump.hprof"). 1704 * @throws UnsupportedOperationException if the VM was built without 1705 * HPROF support. 1706 * @throws IOException if an error occurs while opening or writing files. 1707 */ 1708 public static void dumpHprofData(String fileName) throws IOException { 1709 VMDebug.dumpHprofData(fileName); 1710 } 1711 1712 /** 1713 * Like dumpHprofData(String), but takes an already-opened 1714 * FileDescriptor to which the trace is written. The file name is also 1715 * supplied simply for logging. Makes a dup of the file descriptor. 1716 * 1717 * Primarily for use by the "am" shell command. 1718 * 1719 * @hide 1720 */ 1721 public static void dumpHprofData(String fileName, FileDescriptor fd) 1722 throws IOException { 1723 VMDebug.dumpHprofData(fileName, fd); 1724 } 1725 1726 /** 1727 * Collect "hprof" and send it to DDMS. This may cause a GC. 1728 * 1729 * @throws UnsupportedOperationException if the VM was built without 1730 * HPROF support. 1731 * @hide 1732 */ 1733 public static void dumpHprofDataDdms() { 1734 VMDebug.dumpHprofDataDdms(); 1735 } 1736 1737 /** 1738 * Writes native heap data to the specified file descriptor. 1739 * 1740 * @hide 1741 */ 1742 public static native void dumpNativeHeap(FileDescriptor fd); 1743 1744 /** 1745 * Returns a count of the extant instances of a class. 1746 * 1747 * @hide 1748 */ 1749 public static long countInstancesOfClass(Class cls) { 1750 return VMDebug.countInstancesOfClass(cls, true); 1751 } 1752 1753 /** 1754 * Returns the number of sent transactions from this process. 1755 * @return The number of sent transactions or -1 if it could not read t. 1756 */ 1757 public static native int getBinderSentTransactions(); 1758 1759 /** 1760 * Returns the number of received transactions from the binder driver. 1761 * @return The number of received transactions or -1 if it could not read the stats. 1762 */ 1763 public static native int getBinderReceivedTransactions(); 1764 1765 /** 1766 * Returns the number of active local Binder objects that exist in the 1767 * current process. 1768 */ 1769 public static final native int getBinderLocalObjectCount(); 1770 1771 /** 1772 * Returns the number of references to remote proxy Binder objects that 1773 * exist in the current process. 1774 */ 1775 public static final native int getBinderProxyObjectCount(); 1776 1777 /** 1778 * Returns the number of death notification links to Binder objects that 1779 * exist in the current process. 1780 */ 1781 public static final native int getBinderDeathObjectCount(); 1782 1783 /** 1784 * Primes the register map cache. 1785 * 1786 * Only works for classes in the bootstrap class loader. Does not 1787 * cause classes to be loaded if they're not already present. 1788 * 1789 * The classAndMethodDesc argument is a concatentation of the VM-internal 1790 * class descriptor, method name, and method descriptor. Examples: 1791 * Landroid/os/Looper;.loop:()V 1792 * Landroid/app/ActivityThread;.main:([Ljava/lang/String;)V 1793 * 1794 * @param classAndMethodDesc the method to prepare 1795 * 1796 * @hide 1797 */ 1798 public static final boolean cacheRegisterMap(String classAndMethodDesc) { 1799 return VMDebug.cacheRegisterMap(classAndMethodDesc); 1800 } 1801 1802 /** 1803 * Dumps the contents of VM reference tables (e.g. JNI locals and 1804 * globals) to the log file. 1805 * 1806 * @hide 1807 */ 1808 public static final void dumpReferenceTables() { 1809 VMDebug.dumpReferenceTables(); 1810 } 1811 1812 /** 1813 * API for gathering and querying instruction counts. 1814 * 1815 * Example usage: 1816 * <pre> 1817 * Debug.InstructionCount icount = new Debug.InstructionCount(); 1818 * icount.resetAndStart(); 1819 * [... do lots of stuff ...] 1820 * if (icount.collect()) { 1821 * System.out.println("Total instructions executed: " 1822 * + icount.globalTotal()); 1823 * System.out.println("Method invocations: " 1824 * + icount.globalMethodInvocations()); 1825 * } 1826 * </pre> 1827 * 1828 * @deprecated Instruction counting is no longer supported. 1829 */ 1830 @Deprecated 1831 public static class InstructionCount { 1832 private static final int NUM_INSTR = 1833 OpcodeInfo.MAXIMUM_PACKED_VALUE + 1; 1834 1835 private int[] mCounts; 1836 1837 public InstructionCount() { 1838 mCounts = new int[NUM_INSTR]; 1839 } 1840 1841 /** 1842 * Reset counters and ensure counts are running. Counts may 1843 * have already been running. 1844 * 1845 * @return true if counting was started 1846 */ 1847 public boolean resetAndStart() { 1848 try { 1849 VMDebug.startInstructionCounting(); 1850 VMDebug.resetInstructionCount(); 1851 } catch (UnsupportedOperationException uoe) { 1852 return false; 1853 } 1854 return true; 1855 } 1856 1857 /** 1858 * Collect instruction counts. May or may not stop the 1859 * counting process. 1860 */ 1861 public boolean collect() { 1862 try { 1863 VMDebug.stopInstructionCounting(); 1864 VMDebug.getInstructionCount(mCounts); 1865 } catch (UnsupportedOperationException uoe) { 1866 return false; 1867 } 1868 return true; 1869 } 1870 1871 /** 1872 * Return the total number of instructions executed globally (i.e. in 1873 * all threads). 1874 */ 1875 public int globalTotal() { 1876 int count = 0; 1877 1878 for (int i = 0; i < NUM_INSTR; i++) { 1879 count += mCounts[i]; 1880 } 1881 1882 return count; 1883 } 1884 1885 /** 1886 * Return the total number of method-invocation instructions 1887 * executed globally. 1888 */ 1889 public int globalMethodInvocations() { 1890 int count = 0; 1891 1892 for (int i = 0; i < NUM_INSTR; i++) { 1893 if (OpcodeInfo.isInvoke(i)) { 1894 count += mCounts[i]; 1895 } 1896 } 1897 1898 return count; 1899 } 1900 } 1901 1902 /** 1903 * A Map of typed debug properties. 1904 */ 1905 private static final TypedProperties debugProperties; 1906 1907 /* 1908 * Load the debug properties from the standard files into debugProperties. 1909 */ 1910 static { 1911 if (false) { 1912 final String TAG = "DebugProperties"; 1913 final String[] files = { "/system/debug.prop", "/debug.prop", "/data/debug.prop" }; 1914 final TypedProperties tp = new TypedProperties(); 1915 1916 // Read the properties from each of the files, if present. 1917 for (String file : files) { 1918 Reader r; 1919 try { 1920 r = new FileReader(file); 1921 } catch (FileNotFoundException ex) { 1922 // It's ok if a file is missing. 1923 continue; 1924 } 1925 1926 try { 1927 tp.load(r); 1928 } catch (Exception ex) { 1929 throw new RuntimeException("Problem loading " + file, ex); 1930 } finally { 1931 try { 1932 r.close(); 1933 } catch (IOException ex) { 1934 // Ignore this error. 1935 } 1936 } 1937 } 1938 1939 debugProperties = tp.isEmpty() ? null : tp; 1940 } else { 1941 debugProperties = null; 1942 } 1943 } 1944 1945 1946 /** 1947 * Returns true if the type of the field matches the specified class. 1948 * Handles the case where the class is, e.g., java.lang.Boolean, but 1949 * the field is of the primitive "boolean" type. Also handles all of 1950 * the java.lang.Number subclasses. 1951 */ 1952 private static boolean fieldTypeMatches(Field field, Class<?> cl) { 1953 Class<?> fieldClass = field.getType(); 1954 if (fieldClass == cl) { 1955 return true; 1956 } 1957 Field primitiveTypeField; 1958 try { 1959 /* All of the classes we care about (Boolean, Integer, etc.) 1960 * have a Class field called "TYPE" that points to the corresponding 1961 * primitive class. 1962 */ 1963 primitiveTypeField = cl.getField("TYPE"); 1964 } catch (NoSuchFieldException ex) { 1965 return false; 1966 } 1967 try { 1968 return fieldClass == (Class<?>) primitiveTypeField.get(null); 1969 } catch (IllegalAccessException ex) { 1970 return false; 1971 } 1972 } 1973 1974 1975 /** 1976 * Looks up the property that corresponds to the field, and sets the field's value 1977 * if the types match. 1978 */ 1979 private static void modifyFieldIfSet(final Field field, final TypedProperties properties, 1980 final String propertyName) { 1981 if (field.getType() == java.lang.String.class) { 1982 int stringInfo = properties.getStringInfo(propertyName); 1983 switch (stringInfo) { 1984 case TypedProperties.STRING_SET: 1985 // Handle as usual below. 1986 break; 1987 case TypedProperties.STRING_NULL: 1988 try { 1989 field.set(null, null); // null object for static fields; null string 1990 } catch (IllegalAccessException ex) { 1991 throw new IllegalArgumentException( 1992 "Cannot set field for " + propertyName, ex); 1993 } 1994 return; 1995 case TypedProperties.STRING_NOT_SET: 1996 return; 1997 case TypedProperties.STRING_TYPE_MISMATCH: 1998 throw new IllegalArgumentException( 1999 "Type of " + propertyName + " " + 2000 " does not match field type (" + field.getType() + ")"); 2001 default: 2002 throw new IllegalStateException( 2003 "Unexpected getStringInfo(" + propertyName + ") return value " + 2004 stringInfo); 2005 } 2006 } 2007 Object value = properties.get(propertyName); 2008 if (value != null) { 2009 if (!fieldTypeMatches(field, value.getClass())) { 2010 throw new IllegalArgumentException( 2011 "Type of " + propertyName + " (" + value.getClass() + ") " + 2012 " does not match field type (" + field.getType() + ")"); 2013 } 2014 try { 2015 field.set(null, value); // null object for static fields 2016 } catch (IllegalAccessException ex) { 2017 throw new IllegalArgumentException( 2018 "Cannot set field for " + propertyName, ex); 2019 } 2020 } 2021 } 2022 2023 2024 /** 2025 * Equivalent to <code>setFieldsOn(cl, false)</code>. 2026 * 2027 * @see #setFieldsOn(Class, boolean) 2028 * 2029 * @hide 2030 */ 2031 public static void setFieldsOn(Class<?> cl) { 2032 setFieldsOn(cl, false); 2033 } 2034 2035 /** 2036 * Reflectively sets static fields of a class based on internal debugging 2037 * properties. This method is a no-op if false is 2038 * false. 2039 * <p> 2040 * <strong>NOTE TO APPLICATION DEVELOPERS</strong>: false will 2041 * always be false in release builds. This API is typically only useful 2042 * for platform developers. 2043 * </p> 2044 * Class setup: define a class whose only fields are non-final, static 2045 * primitive types (except for "char") or Strings. In a static block 2046 * after the field definitions/initializations, pass the class to 2047 * this method, Debug.setFieldsOn(). Example: 2048 * <pre> 2049 * package com.example; 2050 * 2051 * import android.os.Debug; 2052 * 2053 * public class MyDebugVars { 2054 * public static String s = "a string"; 2055 * public static String s2 = "second string"; 2056 * public static String ns = null; 2057 * public static boolean b = false; 2058 * public static int i = 5; 2059 * @Debug.DebugProperty 2060 * public static float f = 0.1f; 2061 * @@Debug.DebugProperty 2062 * public static double d = 0.5d; 2063 * 2064 * // This MUST appear AFTER all fields are defined and initialized! 2065 * static { 2066 * // Sets all the fields 2067 * Debug.setFieldsOn(MyDebugVars.class); 2068 * 2069 * // Sets only the fields annotated with @Debug.DebugProperty 2070 * // Debug.setFieldsOn(MyDebugVars.class, true); 2071 * } 2072 * } 2073 * </pre> 2074 * setFieldsOn() may override the value of any field in the class based 2075 * on internal properties that are fixed at boot time. 2076 * <p> 2077 * These properties are only set during platform debugging, and are not 2078 * meant to be used as a general-purpose properties store. 2079 * 2080 * {@hide} 2081 * 2082 * @param cl The class to (possibly) modify 2083 * @param partial If false, sets all static fields, otherwise, only set 2084 * fields with the {@link android.os.Debug.DebugProperty} 2085 * annotation 2086 * @throws IllegalArgumentException if any fields are final or non-static, 2087 * or if the type of the field does not match the type of 2088 * the internal debugging property value. 2089 */ 2090 public static void setFieldsOn(Class<?> cl, boolean partial) { 2091 if (false) { 2092 if (debugProperties != null) { 2093 /* Only look for fields declared directly by the class, 2094 * so we don't mysteriously change static fields in superclasses. 2095 */ 2096 for (Field field : cl.getDeclaredFields()) { 2097 if (!partial || field.getAnnotation(DebugProperty.class) != null) { 2098 final String propertyName = cl.getName() + "." + field.getName(); 2099 boolean isStatic = Modifier.isStatic(field.getModifiers()); 2100 boolean isFinal = Modifier.isFinal(field.getModifiers()); 2101 2102 if (!isStatic || isFinal) { 2103 throw new IllegalArgumentException(propertyName + 2104 " must be static and non-final"); 2105 } 2106 modifyFieldIfSet(field, debugProperties, propertyName); 2107 } 2108 } 2109 } 2110 } else { 2111 Log.wtf(TAG, 2112 "setFieldsOn(" + (cl == null ? "null" : cl.getName()) + 2113 ") called in non-DEBUG build"); 2114 } 2115 } 2116 2117 /** 2118 * Annotation to put on fields you want to set with 2119 * {@link Debug#setFieldsOn(Class, boolean)}. 2120 * 2121 * @hide 2122 */ 2123 @Target({ ElementType.FIELD }) 2124 @Retention(RetentionPolicy.RUNTIME) 2125 public @interface DebugProperty { 2126 } 2127 2128 /** 2129 * Get a debugging dump of a system service by name. 2130 * 2131 * <p>Most services require the caller to hold android.permission.DUMP. 2132 * 2133 * @param name of the service to dump 2134 * @param fd to write dump output to (usually an output log file) 2135 * @param args to pass to the service's dump method, may be null 2136 * @return true if the service was dumped successfully, false if 2137 * the service could not be found or had an error while dumping 2138 */ 2139 public static boolean dumpService(String name, FileDescriptor fd, String[] args) { 2140 IBinder service = ServiceManager.getService(name); 2141 if (service == null) { 2142 Log.e(TAG, "Can't find service to dump: " + name); 2143 return false; 2144 } 2145 2146 try { 2147 service.dump(fd, args); 2148 return true; 2149 } catch (RemoteException e) { 2150 Log.e(TAG, "Can't dump service: " + name, e); 2151 return false; 2152 } 2153 } 2154 2155 /** 2156 * Have the stack traces of the given native process dumped to the 2157 * specified file. Will be appended to the file. 2158 * @hide 2159 */ 2160 public static native void dumpNativeBacktraceToFile(int pid, String file); 2161 2162 /** 2163 * Return a String describing the calling method and location at a particular stack depth. 2164 * @param callStack the Thread stack 2165 * @param depth the depth of stack to return information for. 2166 * @return the String describing the caller at that depth. 2167 */ 2168 private static String getCaller(StackTraceElement callStack[], int depth) { 2169 // callStack[4] is the caller of the method that called getCallers() 2170 if (4 + depth >= callStack.length) { 2171 return "<bottom of call stack>"; 2172 } 2173 StackTraceElement caller = callStack[4 + depth]; 2174 return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber(); 2175 } 2176 2177 /** 2178 * Return a string consisting of methods and locations at multiple call stack levels. 2179 * @param depth the number of levels to return, starting with the immediate caller. 2180 * @return a string describing the call stack. 2181 * {@hide} 2182 */ 2183 public static String getCallers(final int depth) { 2184 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace(); 2185 StringBuffer sb = new StringBuffer(); 2186 for (int i = 0; i < depth; i++) { 2187 sb.append(getCaller(callStack, i)).append(" "); 2188 } 2189 return sb.toString(); 2190 } 2191 2192 /** 2193 * Return a string consisting of methods and locations at multiple call stack levels. 2194 * @param depth the number of levels to return, starting with the immediate caller. 2195 * @return a string describing the call stack. 2196 * {@hide} 2197 */ 2198 public static String getCallers(final int start, int depth) { 2199 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace(); 2200 StringBuffer sb = new StringBuffer(); 2201 depth += start; 2202 for (int i = start; i < depth; i++) { 2203 sb.append(getCaller(callStack, i)).append(" "); 2204 } 2205 return sb.toString(); 2206 } 2207 2208 /** 2209 * Like {@link #getCallers(int)}, but each location is append to the string 2210 * as a new line with <var>linePrefix</var> in front of it. 2211 * @param depth the number of levels to return, starting with the immediate caller. 2212 * @param linePrefix prefix to put in front of each location. 2213 * @return a string describing the call stack. 2214 * {@hide} 2215 */ 2216 public static String getCallers(final int depth, String linePrefix) { 2217 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace(); 2218 StringBuffer sb = new StringBuffer(); 2219 for (int i = 0; i < depth; i++) { 2220 sb.append(linePrefix).append(getCaller(callStack, i)).append("\n"); 2221 } 2222 return sb.toString(); 2223 } 2224 2225 /** 2226 * @return a String describing the immediate caller of the calling method. 2227 * {@hide} 2228 */ 2229 public static String getCaller() { 2230 return getCaller(Thread.currentThread().getStackTrace(), 0); 2231 } 2232} 2233