1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 162867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Miscellaneous utility functions. 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h" 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h> 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stddef.h> 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h> 2510b0b7a8a1b91556b13c9156140f6ff7061b9f8cCarl Shapiro#include <strings.h> 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <ctype.h> 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <time.h> 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <sys/time.h> 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <fcntl.h> 306e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes#include <cutils/ashmem.h> 316e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes#include <sys/mman.h> 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Print a hex dump in this format: 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project01234567: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 0123456789abcdef\n 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "mode" is kHexDumpLocal, we start at offset zero, and show a full 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 16 bytes on the first line. If it's kHexDumpMem, we make this look 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * like a memory dump, using the actual address, outputting a partial line 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if "vaddr" isn't aligned on a 16-byte boundary. 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "priority" and "tag" determine the values passed to the log calls. 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Does not use printf() or other string-formatting calls. 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmPrintHexDumpEx(int priority, const char* tag, const void* vaddr, 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t length, HexDumpMode mode) 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static const char gHexDigit[] = "0123456789abcdef"; 51fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro const unsigned char* addr = (const unsigned char*)vaddr; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char out[77]; /* exact fit */ 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int offset; /* offset to show while printing */ 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* hex; 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* asc; 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int gap; 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //int trickle = 0; 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mode == kHexDumpLocal) 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = 0; 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = (int) addr; 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(out, ' ', sizeof(out)-1); 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out[8] = ':'; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out[sizeof(out)-2] = '\n'; 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out[sizeof(out)-1] = '\0'; 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gap = (int) offset & 0x0f; 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (length) { 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int lineOffset = offset & ~0x0f; 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, count; 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hex = out; 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project asc = out + 59; 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < 8; i++) { 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *hex++ = gHexDigit[lineOffset >> 28]; 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lineOffset <<= 4; 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hex++; 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hex++; 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count = ((int)length > 16-gap) ? 16-gap : (int)length; /* cap length */ 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(count != 0); 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(count+gap <= 16); 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gap) { 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* only on first line */ 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hex += gap * 3; 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project asc += gap; 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = gap ; i < count+gap; i++) { 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *hex++ = gHexDigit[*addr >> 4]; 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *hex++ = gHexDigit[*addr & 0x0f]; 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hex++; 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*addr >= 0x20 && *addr < 0x7f /*isprint(*addr)*/) 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *asc++ = *addr; 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *asc++ = '.'; 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addr++; 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for ( ; i < 16; i++) { 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* erase extra stuff; only happens on last line */ 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *hex++ = ' '; 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *hex++ = ' '; 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hex++; 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *asc++ = ' '; 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_PRI(priority, tag, "%s", out); 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 //def HAVE_ANDROID_OS 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can overrun logcat easily by writing at full speed. On the 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * other hand, we can make Eclipse time out if we're showing 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * packet dumps while debugging JDWP. 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (trickle++ == 8) { 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project trickle = 0; 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project usleep(20000); 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gap = 0; 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length -= count; 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset += count; 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Fill out a DebugOutputTarget, suitable for printing to the log. 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmCreateLogOutputTarget(DebugOutputTarget* target, int priority, 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* tag) 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(target != NULL); 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(tag != NULL); 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project target->which = kDebugTargetLog; 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project target->data.log.priority = priority; 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project target->data.log.tag = tag; 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Fill out a DebugOutputTarget suitable for printing to a file pointer. 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmCreateFileOutputTarget(DebugOutputTarget* target, FILE* fp) 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(target != NULL); 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(fp != NULL); 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project target->which = kDebugTargetFile; 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project target->data.file.fp = fp; 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free "target" and any associated data. 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmFreeOutputTarget(DebugOutputTarget* target) 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(target); 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Print a debug message, to either a file or the log. 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmPrintDebugMessage(const DebugOutputTarget* target, const char* format, 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ...) 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project va_list args; 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project va_start(args, format); 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (target->which) { 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDebugTargetLog: 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOG_PRI_VA(target->data.log.priority, target->data.log.tag, 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project format, args); 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDebugTargetFile: 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vfprintf(target->data.file.fp, format, args); 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 187c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("unexpected 'which' %d", target->which); 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project va_end(args); 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a newly-allocated string in which all occurrences of '.' have 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * been changed to '/'. If we find a '/' in the original string, NULL 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is returned to avoid ambiguity. 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDotToSlash(const char* str) 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* newStr = strdup(str); 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* cp = newStr; 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 205f905853a8ae31d433032cf01fa3eeecafc8aa6c6Andy McFadden if (newStr == NULL) 206f905853a8ae31d433032cf01fa3eeecafc8aa6c6Andy McFadden return NULL; 207f905853a8ae31d433032cf01fa3eeecafc8aa6c6Andy McFadden 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*cp != '\0') { 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*cp == '/') { 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*cp == '.') 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *cp = '/'; 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp++; 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return newStr; 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 221b08e2b6017770e887f6072c1520b2d7f2ef6916cElliott Hughesstd::string dvmHumanReadableDescriptor(const char* descriptor) { 22298c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes // Count the number of '['s to get the dimensionality. 22398c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes const char* c = descriptor; 2245016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes size_t dim = 0; 2255016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes while (*c == '[') { 2265016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes dim++; 2275016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes c++; 2285016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes } 22998c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes 230b08e2b6017770e887f6072c1520b2d7f2ef6916cElliott Hughes // Reference or primitive? 2315016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes if (*c == 'L') { 23298c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes // "[[La/b/C;" -> "a.b.C[][]". 23398c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes c++; // Skip the 'L'. 2345016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes } else { 23598c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes // "[[B" -> "byte[][]". 23698c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes // To make life easier, we make primitives look like unqualified 23798c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes // reference types. 2385016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes switch (*c) { 23998c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes case 'B': c = "byte;"; break; 24098c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes case 'C': c = "char;"; break; 24198c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes case 'D': c = "double;"; break; 24298c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes case 'F': c = "float;"; break; 24398c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes case 'I': c = "int;"; break; 24498c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes case 'J': c = "long;"; break; 24598c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes case 'S': c = "short;"; break; 24698c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes case 'Z': c = "boolean;"; break; 247b08e2b6017770e887f6072c1520b2d7f2ef6916cElliott Hughes default: return descriptor; 2485016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes } 2495016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes } 2505016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes 25198c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes // At this point, 'c' is a string of the form "fully/qualified/Type;" 25298c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes // or "primitive;". Rewrite the type with '.' instead of '/': 253b08e2b6017770e887f6072c1520b2d7f2ef6916cElliott Hughes std::string result; 25498c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes const char* p = c; 25598c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes while (*p != ';') { 25698c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes char ch = *p++; 25798c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes if (ch == '/') { 25898c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes ch = '.'; 25998c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes } 260b08e2b6017770e887f6072c1520b2d7f2ef6916cElliott Hughes result.push_back(ch); 26198c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes } 26298c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes // ...and replace the semicolon with 'dim' "[]" pairs: 2635016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes while (dim--) { 264b08e2b6017770e887f6072c1520b2d7f2ef6916cElliott Hughes result += "[]"; 2655016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes } 26698c3592ce74e1a516e7a2b93b82525c92918b0e4Elliott Hughes return result; 2675016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes} 2685016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes 269fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughesstd::string dvmHumanReadableType(const Object* obj) 270fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughes{ 271fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughes if (obj == NULL) { 2723ff838ee3920ef819d207cbf4148cc9c7939ef69Jesse Wilson return "null"; 273fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughes } 274fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughes if (obj->clazz == NULL) { 275fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughes /* should only be possible right after a plain dvmMalloc() */ 276fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughes return "(raw)"; 277fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughes } 278fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughes std::string result(dvmHumanReadableDescriptor(obj->clazz->descriptor)); 279fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughes if (dvmIsClassObject(obj)) { 280fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughes const ClassObject* clazz = reinterpret_cast<const ClassObject*>(obj); 281fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughes result += "<" + dvmHumanReadableDescriptor(clazz->descriptor) + ">"; 282fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughes } 283fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughes return result; 284fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughes} 285fe7f2b3920bf5d66eda262e643245b03df3e57c8Elliott Hughes 2865719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughesstd::string dvmHumanReadableField(const Field* field) 2875719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes{ 2885719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes if (field == NULL) { 2895719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes return "(null)"; 2905719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes } 2915719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes std::string result(dvmHumanReadableDescriptor(field->clazz->descriptor)); 2925719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes result += '.'; 2935719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes result += field->name; 2945719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes return result; 2955719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes} 2965719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes 2975719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughesstd::string dvmHumanReadableMethod(const Method* method, bool withSignature) 2985719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes{ 2995719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes if (method == NULL) { 3005719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes return "(null)"; 3015719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes } 3025719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes std::string result(dvmHumanReadableDescriptor(method->clazz->descriptor)); 3035719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes result += '.'; 3045719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes result += method->name; 3055719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes if (withSignature) { 3065719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes // TODO: the types in this aren't human readable! 3075719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes char* signature = dexProtoCopyMethodDescriptor(&method->prototype); 3085719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes result += signature; 3095719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes free(signature); 3105719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes } 3115719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes return result; 3125719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes} 3135719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughes 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a newly-allocated string for the "dot version" of the class 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * name for the given type descriptor. That is, The initial "L" and 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * final ";" (if any) have been removed and all occurrences of '/' 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have been changed to '.'. 3195016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes * 3205016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes * "Dot version" names are used in the class loading machinery. 3215016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes * See also dvmHumanReadableDescriptor. 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDescriptorToDot(const char* str) 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t at = strlen(str); 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* newStr; 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((at >= 2) && (str[0] == 'L') && (str[at - 1] == ';')) { 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project at -= 2; /* Two fewer chars to copy. */ 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project str++; /* Skip the 'L'. */ 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 333fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro newStr = (char*)malloc(at + 1); /* Add one for the '\0'. */ 334f905853a8ae31d433032cf01fa3eeecafc8aa6c6Andy McFadden if (newStr == NULL) 335f905853a8ae31d433032cf01fa3eeecafc8aa6c6Andy McFadden return NULL; 336f905853a8ae31d433032cf01fa3eeecafc8aa6c6Andy McFadden 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newStr[at] = '\0'; 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (at > 0) { 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project at--; 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newStr[at] = (str[at] == '/') ? '.' : str[at]; 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return newStr; 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a newly-allocated string for the type descriptor 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * corresponding to the "dot version" of the given class name. That 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is, non-array names are surrounded by "L" and ";", and all 3515016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes * occurrences of '.' have been changed to '/'. 3525016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes * 3535016966b91f1bc36b2bd52ec13ecfd8de1c68209Elliott Hughes * "Dot version" names are used in the class loading machinery. 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDotToDescriptor(const char* str) 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t length = strlen(str); 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int wrapElSemi = 0; 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* newStr; 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* at; 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (str[0] != '[') { 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length += 2; /* for "L" and ";" */ 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project wrapElSemi = 1; 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 367fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro newStr = at = (char*)malloc(length + 1); /* + 1 for the '\0' */ 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newStr == NULL) { 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (wrapElSemi) { 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *(at++) = 'L'; 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*str) { 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char c = *(str++); 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (c == '.') { 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c = '/'; 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *(at++) = c; 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (wrapElSemi) { 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *(at++) = ';'; 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *at = '\0'; 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return newStr; 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a newly-allocated string for the internal-form class name for 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the given type descriptor. That is, the initial "L" and final ";" (if 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * any) have been removed. 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDescriptorToName(const char* str) 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (str[0] == 'L') { 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t length = strlen(str) - 1; 402fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro char* newStr = (char*)malloc(length); 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newStr == NULL) { 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strlcpy(newStr, str + 1, length); 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return newStr; 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return strdup(str); 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a newly-allocated string for the type descriptor for the given 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * internal-form class name. That is, a non-array class name will get 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * surrounded by "L" and ";", while array names are left as-is. 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmNameToDescriptor(const char* str) 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (str[0] != '[') { 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t length = strlen(str); 424fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro char* descriptor = (char*)malloc(length + 3); 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (descriptor == NULL) { 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project descriptor[0] = 'L'; 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strcpy(descriptor + 1, str); 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project descriptor[length + 1] = ';'; 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project descriptor[length + 2] = '\0'; 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return descriptor; 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return strdup(str); 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get a notion of the current time, in nanoseconds. This is meant for 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * computing durations (e.g. "operation X took 52nsec"), so the result 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * should not be used to get the current date/time. 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4461e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirou8 dvmGetRelativeTimeNsec() 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_CLOCKS 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct timespec now; 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clock_gettime(CLOCK_MONOTONIC, &now); 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (u8)now.tv_sec*1000000000LL + now.tv_nsec; 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct timeval now; 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gettimeofday(&now, NULL); 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (u8)now.tv_sec*1000000000LL + now.tv_usec * 1000LL; 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the per-thread CPU time, in nanoseconds. 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only useful for time deltas. 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4641e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirou8 dvmGetThreadCpuTimeNsec() 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_CLOCKS 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct timespec now; 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now); 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (u8)now.tv_sec*1000000000LL + now.tv_nsec; 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (u8) -1; 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the per-thread CPU time, in nanoseconds, for the specified thread. 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu8 dvmGetOtherThreadCpuTimeNsec(pthread_t thread) 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 /*def HAVE_POSIX_CLOCKS*/ 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int clockId; 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pthread_getcpuclockid(thread, &clockId) != 0) 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (u8) -1; 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct timespec now; 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clock_gettime(clockId, &now); 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (u8)now.tv_sec*1000000000LL + now.tv_nsec; 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (u8) -1; 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Call this repeatedly, with successively higher values for "iteration", 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to sleep for a period of time not to exceed "maxTotalSleep". 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For example, when called with iteration==0 we will sleep for a very 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * brief time. On the next call we will sleep for a longer time. When 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the sum total of all sleeps reaches "maxTotalSleep", this returns false. 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The initial start time value for "relStartTime" MUST come from the 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dvmGetRelativeTimeUsec call. On the device this must come from the 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * monotonic clock source, not the wall clock. 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This should be used wherever you might be tempted to call sched_yield() 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in a loop. The problem with sched_yield is that, for a high-priority 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * thread, the kernel might not actually transfer control elsewhere. 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "false" if we were unable to sleep because our time was up. 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmIterativeSleep(int iteration, int maxTotalSleep, u8 relStartTime) 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 51533c8ae5bb1bb8052680108d999c608df8c72a613Mathieu Chartier /* 51633c8ae5bb1bb8052680108d999c608df8c72a613Mathieu Chartier * Minimum sleep is one millisecond, it is important to keep this value 51733c8ae5bb1bb8052680108d999c608df8c72a613Mathieu Chartier * low to ensure short GC pauses since dvmSuspendAllThreads() uses this 51833c8ae5bb1bb8052680108d999c608df8c72a613Mathieu Chartier * function. 51933c8ae5bb1bb8052680108d999c608df8c72a613Mathieu Chartier */ 52033c8ae5bb1bb8052680108d999c608df8c72a613Mathieu Chartier const int minSleep = 1000; 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u8 curTime; 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int curDelay; 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get current time, and see if we've already exceeded the limit. 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project curTime = dvmGetRelativeTimeUsec(); 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (curTime >= relStartTime + maxTotalSleep) { 52960fc806b679a3655c228b4093058c59941a49cfeDan Bornstein LOGVV("exsl: sleep exceeded (start=%llu max=%d now=%llu)", 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project relStartTime, maxTotalSleep, curTime); 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Compute current delay. We're bounded by "maxTotalSleep", so no 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * real risk of overflow assuming "usleep" isn't returning early. 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (Besides, 2^30 usec is about 18 minutes by itself.) 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For iteration==0 we just call sched_yield(), so the first sleep 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * at iteration==1 is actually (minSleep * 2). 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project curDelay = minSleep; 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (iteration-- > 0) 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project curDelay *= 2; 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(curDelay > 0); 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (curTime + curDelay >= relStartTime + maxTotalSleep) { 54860fc806b679a3655c228b4093058c59941a49cfeDan Bornstein LOGVV("exsl: reduced delay from %d to %d", 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project curDelay, (int) ((relStartTime + maxTotalSleep) - curTime)); 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project curDelay = (int) ((relStartTime + maxTotalSleep) - curTime); 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (iteration == 0) { 55460fc806b679a3655c228b4093058c59941a49cfeDan Bornstein LOGVV("exsl: yield"); 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sched_yield(); 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 55760fc806b679a3655c228b4093058c59941a49cfeDan Bornstein LOGVV("exsl: sleep for %d", curDelay); 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project usleep(curDelay); 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the "close on exec" flag so we don't expose our file descriptors 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to processes launched by us. 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmSetCloseOnExec(int fd) 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int flags; 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * There's presently only one flag defined, so getting the previous 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * value of the fd flags is probably unnecessary. 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project flags = fcntl(fd, F_GETFD); 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (flags < 0) { 578e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block ALOGW("Unable to get fd flags for fd %d", fd); 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) { 582e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block ALOGW("Unable to set close-on-exec for fd %d", fd); 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if (!HAVE_STRLCPY) 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Implementation of strlcpy() for platforms that don't already have it. */ 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectsize_t strlcpy(char *dst, const char *src, size_t size) { 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t srcLength = strlen(src); 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t copyLength = srcLength; 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (srcLength > (size - 1)) { 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyLength = size - 1; 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (size != 0) { 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strncpy(dst, src, copyLength); 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dst[copyLength] = '\0'; 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return srcLength; 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 6066e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes 6076e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes/* 6086e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes * Allocates a memory region using ashmem and mmap, initialized to 6096e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes * zero. Actual allocation rounded up to page multiple. Returns 6106e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes * NULL on failure. 6116e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes */ 6124a7db9c47500ded9d2509185a01e081bf03b64d4Brian Carlstromvoid *dvmAllocRegion(size_t byteCount, int prot, const char *name) { 6136e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes void *base; 6146e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes int fd, ret; 6156e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes 6164a7db9c47500ded9d2509185a01e081bf03b64d4Brian Carlstrom byteCount = ALIGN_UP_TO_PAGE_SIZE(byteCount); 6174a7db9c47500ded9d2509185a01e081bf03b64d4Brian Carlstrom fd = ashmem_create_region(name, byteCount); 6186e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes if (fd == -1) { 6196e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes return NULL; 6206e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes } 6214a7db9c47500ded9d2509185a01e081bf03b64d4Brian Carlstrom base = mmap(NULL, byteCount, prot, MAP_PRIVATE, fd, 0); 6226e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes ret = close(fd); 6236e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes if (base == MAP_FAILED) { 6246e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes return NULL; 6256e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes } 6266e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes if (ret == -1) { 627a5e0812ac14be9c74ae78a27ab03bb7aa5af7adfYou Kim munmap(base, byteCount); 6286e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes return NULL; 6296e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes } 6306e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes return base; 6316e5cf6021b2f3e00e18ab402f23ab93b27c6061bBarry Hayes} 6320a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden 6330a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden/* 6340a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden * Get some per-thread stats. 6350a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden * 6360a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden * This is currently generated by opening the appropriate "stat" file 6370a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden * in /proc and reading the pile of stuff that comes out. 6380a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden */ 6390a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFaddenbool dvmGetThreadStats(ProcStatData* pData, pid_t tid) 6400a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden{ 6410a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden /* 6420a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden int pid; 6430a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden char comm[128]; 6440a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden char state; 6450a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden int ppid, pgrp, session, tty_nr, tpgid; 6460a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden unsigned long flags, minflt, cminflt, majflt, cmajflt, utime, stime; 6470a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden long cutime, cstime, priority, nice, zero, itrealvalue; 6480a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden unsigned long starttime, vsize; 6490a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden long rss; 6500a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden unsigned long rlim, startcode, endcode, startstack, kstkesp, kstkeip; 6510a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden unsigned long signal, blocked, sigignore, sigcatch, wchan, nswap, cnswap; 6520a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden int exit_signal, processor; 6530a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden unsigned long rt_priority, policy; 6540a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden 6550a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden scanf("%d %s %c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld " 6560a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden "%ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu " 6570a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden "%lu %lu %lu %d %d %lu %lu", 6580a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden &pid, comm, &state, &ppid, &pgrp, &session, &tty_nr, &tpgid, 6590a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden &flags, &minflt, &cminflt, &majflt, &cmajflt, &utime, &stime, 6600a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden &cutime, &cstime, &priority, &nice, &zero, &itrealvalue, 6610a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden &starttime, &vsize, &rss, &rlim, &startcode, &endcode, 6620a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden &startstack, &kstkesp, &kstkeip, &signal, &blocked, &sigignore, 6630a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden &sigcatch, &wchan, &nswap, &cnswap, &exit_signal, &processor, 6640a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden &rt_priority, &policy); 6650a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden 6660a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden (new: delayacct_blkio_ticks %llu (since Linux 2.6.18)) 6670a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden */ 6680a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden 6690a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden char nameBuf[64]; 6700a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden int i, fd; 6710a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden 6720a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden /* 6730a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden * Open and read the appropriate file. This is expected to work on 6740a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden * Linux but will fail on other platforms (e.g. Mac sim). 6750a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden */ 6760a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden sprintf(nameBuf, "/proc/self/task/%d/stat", (int) tid); 6770a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden fd = open(nameBuf, O_RDONLY); 6780a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden if (fd < 0) { 67992c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("Unable to open '%s': %s", nameBuf, strerror(errno)); 6800a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden return false; 6810a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden } 6820a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden 6830a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden char lineBuf[512]; /* > 2x typical */ 6840a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden int cc = read(fd, lineBuf, sizeof(lineBuf)-1); 6850a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden if (cc <= 0) { 6860a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden const char* msg = (cc == 0) ? "unexpected EOF" : strerror(errno); 6874308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI("Unable to read '%s': %s", nameBuf, msg); 6880a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden close(fd); 6890a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden return false; 6900a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden } 6910a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden close(fd); 6920a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden lineBuf[cc] = '\0'; 6930a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden 6940a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden /* 6950a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden * Skip whitespace-separated tokens. For the most part we can assume 6960a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden * that tokens do not contain spaces, and are separated by exactly one 6970a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden * space character. The only exception is the second field ("comm") 6980a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden * which may contain spaces but is surrounded by parenthesis. 6990a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden */ 7000a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden char* cp = strchr(lineBuf, ')'); 7010a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden if (cp == NULL) 7020a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden goto parse_fail; 703b3667a19f5c573b7785876979af4781292d27327Andy McFadden cp += 2; 704b3667a19f5c573b7785876979af4781292d27327Andy McFadden pData->state = *cp++; 705b3667a19f5c573b7785876979af4781292d27327Andy McFadden 706b3667a19f5c573b7785876979af4781292d27327Andy McFadden for (i = 3; i < 13; i++) { 7070a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden cp = strchr(cp+1, ' '); 7080a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden if (cp == NULL) 7090a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden goto parse_fail; 7100a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden } 7110a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden 7120a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden /* 7130a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden * Grab utime/stime. 7140a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden */ 7150a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden char* endp; 7160a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden pData->utime = strtoul(cp+1, &endp, 10); 7170a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden if (endp == cp+1) 7184308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI("Warning: strtoul failed on utime ('%.30s...')", cp); 7190a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden 7200a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden cp = strchr(cp+1, ' '); 7210a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden if (cp == NULL) 7220a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden goto parse_fail; 7230a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden 7240a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden pData->stime = strtoul(cp+1, &endp, 10); 7250a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden if (endp == cp+1) 7264308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI("Warning: strtoul failed on stime ('%.30s...')", cp); 7270a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden 7280a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden /* 7290a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden * Skip more stuff we don't care about. 7300a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden */ 7310a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden for (i = 14; i < 38; i++) { 7320a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden cp = strchr(cp+1, ' '); 7330a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden if (cp == NULL) 7340a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden goto parse_fail; 7350a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden } 7360a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden 7370a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden /* 7380a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden * Grab processor number. 7390a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden */ 7400a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden pData->processor = strtol(cp+1, &endp, 10); 7410a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden if (endp == cp+1) 7424308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI("Warning: strtoul failed on processor ('%.30s...')", cp); 7430a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden 7440a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden return true; 7450a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden 7460a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFaddenparse_fail: 7474308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI("stat parse failed (%s)", lineBuf); 7480a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden return false; 7490a3f698117bd6438d0b668dfbb72828d25a23a3bAndy McFadden} 750bbf9d73a5677de73eaa3b4e1f6de94a24697aad1Dan Bornstein 75132bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein/* documented in header file */ 75232bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornsteinconst char* dvmPathToAbsolutePortion(const char* path) { 75332bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein if (path == NULL) { 75432bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein return NULL; 75532bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein } 75632bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein 75732bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein if (path[0] == '/') { 75832bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein /* It's a regular absolute path. Return it. */ 75932bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein return path; 76032bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein } 76132bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein 76232bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein const char* sentinel = strstr(path, "/./"); 76332bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein 76432bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein if (sentinel != NULL) { 76532bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein /* It's got the sentinel. Return a pointer to the second slash. */ 76632bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein return sentinel + 2; 76732bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein } 76832bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein 76932bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein return NULL; 77032bc0787307ba57e92fa74c52da550e2ca22af7fDan Bornstein} 771708f143f318bb2167c810f9506102f4ad656545cElliott Hughes 772708f143f318bb2167c810f9506102f4ad656545cElliott Hughes// From RE2. 7735719d5c79558ffdbbb863ddcf61836221aba922dElliott Hughesvoid StringAppendV(std::string* dst, const char* format, va_list ap) { 774708f143f318bb2167c810f9506102f4ad656545cElliott Hughes // First try with a small fixed size buffer 775708f143f318bb2167c810f9506102f4ad656545cElliott Hughes char space[1024]; 776708f143f318bb2167c810f9506102f4ad656545cElliott Hughes 777708f143f318bb2167c810f9506102f4ad656545cElliott Hughes // It's possible for methods that use a va_list to invalidate 778708f143f318bb2167c810f9506102f4ad656545cElliott Hughes // the data in it upon use. The fix is to make a copy 779708f143f318bb2167c810f9506102f4ad656545cElliott Hughes // of the structure before using it and use that copy instead. 780708f143f318bb2167c810f9506102f4ad656545cElliott Hughes va_list backup_ap; 781708f143f318bb2167c810f9506102f4ad656545cElliott Hughes va_copy(backup_ap, ap); 782708f143f318bb2167c810f9506102f4ad656545cElliott Hughes int result = vsnprintf(space, sizeof(space), format, backup_ap); 783708f143f318bb2167c810f9506102f4ad656545cElliott Hughes va_end(backup_ap); 784708f143f318bb2167c810f9506102f4ad656545cElliott Hughes 785708f143f318bb2167c810f9506102f4ad656545cElliott Hughes if ((result >= 0) && ((size_t) result < sizeof(space))) { 786708f143f318bb2167c810f9506102f4ad656545cElliott Hughes // It fit 787708f143f318bb2167c810f9506102f4ad656545cElliott Hughes dst->append(space, result); 788708f143f318bb2167c810f9506102f4ad656545cElliott Hughes return; 789708f143f318bb2167c810f9506102f4ad656545cElliott Hughes } 790708f143f318bb2167c810f9506102f4ad656545cElliott Hughes 791708f143f318bb2167c810f9506102f4ad656545cElliott Hughes // Repeatedly increase buffer size until it fits 792708f143f318bb2167c810f9506102f4ad656545cElliott Hughes int length = sizeof(space); 793708f143f318bb2167c810f9506102f4ad656545cElliott Hughes while (true) { 794708f143f318bb2167c810f9506102f4ad656545cElliott Hughes if (result < 0) { 795708f143f318bb2167c810f9506102f4ad656545cElliott Hughes // Older behavior: just try doubling the buffer size 796708f143f318bb2167c810f9506102f4ad656545cElliott Hughes length *= 2; 797708f143f318bb2167c810f9506102f4ad656545cElliott Hughes } else { 798708f143f318bb2167c810f9506102f4ad656545cElliott Hughes // We need exactly "result+1" characters 799708f143f318bb2167c810f9506102f4ad656545cElliott Hughes length = result+1; 800708f143f318bb2167c810f9506102f4ad656545cElliott Hughes } 801708f143f318bb2167c810f9506102f4ad656545cElliott Hughes char* buf = new char[length]; 802708f143f318bb2167c810f9506102f4ad656545cElliott Hughes 803708f143f318bb2167c810f9506102f4ad656545cElliott Hughes // Restore the va_list before we use it again 804708f143f318bb2167c810f9506102f4ad656545cElliott Hughes va_copy(backup_ap, ap); 805708f143f318bb2167c810f9506102f4ad656545cElliott Hughes result = vsnprintf(buf, length, format, backup_ap); 806708f143f318bb2167c810f9506102f4ad656545cElliott Hughes va_end(backup_ap); 807708f143f318bb2167c810f9506102f4ad656545cElliott Hughes 808708f143f318bb2167c810f9506102f4ad656545cElliott Hughes if ((result >= 0) && (result < length)) { 809708f143f318bb2167c810f9506102f4ad656545cElliott Hughes // It fit 810708f143f318bb2167c810f9506102f4ad656545cElliott Hughes dst->append(buf, result); 811708f143f318bb2167c810f9506102f4ad656545cElliott Hughes delete[] buf; 812708f143f318bb2167c810f9506102f4ad656545cElliott Hughes return; 813708f143f318bb2167c810f9506102f4ad656545cElliott Hughes } 814708f143f318bb2167c810f9506102f4ad656545cElliott Hughes delete[] buf; 815708f143f318bb2167c810f9506102f4ad656545cElliott Hughes } 816708f143f318bb2167c810f9506102f4ad656545cElliott Hughes} 817708f143f318bb2167c810f9506102f4ad656545cElliott Hughes 818837eabb829417c1542037423c55536649de404b8Elliott Hughesstd::string StringPrintf(const char* fmt, ...) { 819708f143f318bb2167c810f9506102f4ad656545cElliott Hughes va_list ap; 820708f143f318bb2167c810f9506102f4ad656545cElliott Hughes va_start(ap, fmt); 821708f143f318bb2167c810f9506102f4ad656545cElliott Hughes std::string result; 822708f143f318bb2167c810f9506102f4ad656545cElliott Hughes StringAppendV(&result, fmt, ap); 823708f143f318bb2167c810f9506102f4ad656545cElliott Hughes va_end(ap); 824708f143f318bb2167c810f9506102f4ad656545cElliott Hughes return result; 825708f143f318bb2167c810f9506102f4ad656545cElliott Hughes} 826837eabb829417c1542037423c55536649de404b8Elliott Hughes 827837eabb829417c1542037423c55536649de404b8Elliott Hughesvoid StringAppendF(std::string* dst, const char* format, ...) { 828837eabb829417c1542037423c55536649de404b8Elliott Hughes va_list ap; 829837eabb829417c1542037423c55536649de404b8Elliott Hughes va_start(ap, format); 830837eabb829417c1542037423c55536649de404b8Elliott Hughes StringAppendV(dst, format, ap); 831837eabb829417c1542037423c55536649de404b8Elliott Hughes va_end(ap); 832837eabb829417c1542037423c55536649de404b8Elliott Hughes} 833