1231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn/* 2231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Copyright (C) 2008 The Android Open Source Project 3231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * 4231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * you may not use this file except in compliance with the License. 6231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * You may obtain a copy of the License at 7231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * 8231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * 10231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 11231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * See the License for the specific language governing permissions and 14231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * limitations under the License. 15231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 16231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 17231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn/** 18231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * One line from the loaded-classes file. 19231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 20231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornclass Record { 21231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 22231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 23231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * The delimiter character we use, {@code :}, conflicts with some other 24231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * names. In that case, manually replace the delimiter with something else. 25231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 26231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static final String[] REPLACE_CLASSES = { 27231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "com.google.android.apps.maps:FriendService", 28231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "com.google.android.apps.maps\\u003AFriendService", 29231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "com.google.android.apps.maps:driveabout", 30231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "com.google.android.apps.maps\\u003Adriveabout", 31763631cd247e21b167063023e7dd1395e05ebbf6Jeff Brown "com.google.android.apps.maps:GoogleLocationService", 32763631cd247e21b167063023e7dd1395e05ebbf6Jeff Brown "com.google.android.apps.maps\\u003AGoogleLocationService", 33763631cd247e21b167063023e7dd1395e05ebbf6Jeff Brown "com.google.android.apps.maps:LocationFriendService", 34763631cd247e21b167063023e7dd1395e05ebbf6Jeff Brown "com.google.android.apps.maps\\u003ALocationFriendService", 35763631cd247e21b167063023e7dd1395e05ebbf6Jeff Brown "com.google.android.apps.maps:MapsBackgroundService", 36763631cd247e21b167063023e7dd1395e05ebbf6Jeff Brown "com.google.android.apps.maps\\u003AMapsBackgroundService", 37763631cd247e21b167063023e7dd1395e05ebbf6Jeff Brown "com.google.android.apps.maps:NetworkLocationService", 38763631cd247e21b167063023e7dd1395e05ebbf6Jeff Brown "com.google.android.apps.maps\\u003ANetworkLocationService", 39763631cd247e21b167063023e7dd1395e05ebbf6Jeff Brown "com.android.chrome:sandboxed_process", 40763631cd247e21b167063023e7dd1395e05ebbf6Jeff Brown "com.android.chrome\\u003Asandboxed_process", 41763631cd247e21b167063023e7dd1395e05ebbf6Jeff Brown "com.android.fakeoemfeatures:background", 42231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "com.android.fakeoemfeatures\\u003Abackground", 43231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "com.android.fakeoemfeatures:core", 44231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "com.android.fakeoemfeatures\\u003Acore", 45231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "com.google.android.music:main", 46231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "com.google.android.music\\u003Amain", 47231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "com.google.android.music:ui", 48231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "com.google.android.music\\u003Aui", 49231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "com.google.android.setupwarlock:broker", 50231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "com.google.android.setupwarlock\\u003Abroker", 51231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "android:ui", 52231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "android\\u003Aui", 53231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn }; 54231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 55231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn enum Type { 56231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Start of initialization. */ 57231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn START_LOAD, 58231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 591afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn /** End of initialization. */ 60231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn END_LOAD, 61231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 62231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Start of initialization. */ 63231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn START_INIT, 641afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn 651afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn /** End of initialization. */ 66231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn END_INIT 67231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 68231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 69231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Parent process ID. */ 70231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int ppid; 71231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 72231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Process ID. */ 73231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int pid; 74231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 75231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Thread ID. */ 76231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int tid; 77231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 78231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Process name. */ 79231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final String processName; 80231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 81231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Class loader pointer. */ 82231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int classLoader; 83231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 84231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Type of record. */ 85231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final Type type; 86231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 87231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Name of loaded class. */ 88231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final String className; 89231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 90231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Record time (ns). */ 918bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn final long time; 92231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 93231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Source file line# */ 94231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int sourceLineNumber; 95231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 96231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 97231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Parses a line from the loaded-classes file. 98231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 99231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Record(String line, int lineNum) { 100231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn char typeChar = line.charAt(0); 101231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn switch (typeChar) { 102231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn case '>': type = Type.START_LOAD; break; 1038bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn case '<': type = Type.END_LOAD; break; 104231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn case '+': type = Type.START_INIT; break; 105231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn case '-': type = Type.END_INIT; break; 106231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn default: throw new AssertionError("Bad line: " + line); 107231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 108231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 109231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn sourceLineNumber = lineNum; 110231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 111231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn for (int i = 0; i < REPLACE_CLASSES.length; i+= 2) { 112231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn line = line.replace(REPLACE_CLASSES[i], REPLACE_CLASSES[i+1]); 113231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 114231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 115231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn line = line.substring(1); 116231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String[] parts = line.split(":"); 117231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 118231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ppid = Integer.parseInt(parts[0]); 119231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pid = Integer.parseInt(parts[1]); 120231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn tid = Integer.parseInt(parts[2]); 121231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 122231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn processName = decode(parts[3]).intern(); 123231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 124231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn classLoader = Integer.parseInt(parts[4]); 1258bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn className = vmTypeToLanguage(decode(parts[5])).intern(); 126231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 127231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn time = Long.parseLong(parts[6]); 128231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 129231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 130231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 131231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Decode any escaping that may have been written to the log line. 132231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * 133231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Supports unicode-style escaping: \\uXXXX = character in hex 134231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * 135231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * @param rawField the field as it was written into the log 136231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * @result the same field with any escaped characters replaced 137231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 138231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String decode(String rawField) { 139231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String result = rawField; 140231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int offset = result.indexOf("\\u"); 141231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (offset >= 0) { 142231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String before = result.substring(0, offset); 143231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String escaped = result.substring(offset+2, offset+6); 144231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String after = result.substring(offset+6); 145231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 146231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn result = String.format("%s%c%s", before, Integer.parseInt(escaped, 16), after); 147231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 148231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // find another but don't recurse 149231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn offset = result.indexOf("\\u", offset + 1); 150231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 151231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return result; 152231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 153231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 154231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 155231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Converts a VM-style name to a language-style name. 156231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 157231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String vmTypeToLanguage(String typeName) { 158231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // if the typename is (null), just return it as-is. This is probably in dexopt and 159231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // will be discarded anyway. NOTE: This corresponds to the case in dalvik/vm/oo/Class.c 160231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // where dvmLinkClass() returns false and we clean up and exit. 161231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if ("(null)".equals(typeName)) { 162231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return typeName; 163231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 164231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 165231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (!typeName.startsWith("L") || !typeName.endsWith(";") ) { 166231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn throw new AssertionError("Bad name: " + typeName + " in line " + sourceLineNumber); 167231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 168231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 169 typeName = typeName.substring(1, typeName.length() - 1); 170 return typeName.replace("/", "."); 171 } 172} 173