Debugger.cpp revision 1e1433e78f560a01744e870c19c162ab88df9dc1
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 */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Link between JDWP and the VM. The code here only runs as a result of 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * requests from the debugger, so speed is not essential. Maintaining 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * isolation of the JDWP code should make it easier to maintain and reuse. 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Collecting all debugger-related pieces here will also allow us to #ifdef 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the JDWP code out of release builds. 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h" 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNotes on garbage collection and object registration 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectJDWP does not allow the debugger to assume that objects passed to it 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectwill not be garbage collected. It specifies explicit commands (e.g. 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectReference.DisableCollection) to allow the debugger to manage 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectobject lifetime. It does, however, require that the VM not re-use an 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectobject ID unless an explicit "dispose" call has been made, and if the 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectVM asks for a now-collected object we must return INVALID_OBJECT. 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectJDWP also requires that, while the VM is suspended, no garbage collection 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectoccur. The JDWP docs suggest that this is obvious, because no threads 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectcan be running. Unfortunately it's not entirely clear how to deal 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectwith situations where the debugger itself allocates strings or executes 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectcode as part of displaying variables. The easiest way to enforce this, 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectshort of disabling GC whenever the debugger is connected, is to ensure 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectthat the debugger thread can't cause a GC: it has to expand the heap or 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfail to allocate. (Might want to make that "is debugger thread AND all 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectother threads are suspended" to avoid unnecessary heap expansion by a 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpoorly-timed JDWP request.) 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectWe use an "object registry" so that we can separate our internal 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectrepresentation from what we show the debugger. This allows us to 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectreturn a registry table index instead of a pointer or handle. 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectThere are various approaches we can take to achieve correct behavior: 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project(1) Disable garbage collection entirely while the debugger is attached. 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectThis is very easy, but doesn't allow extended debugging sessions on 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectsmall devices. 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project(2) Keep a list of all object references requested by or sent to the 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectdebugger, and include the list in the GC root set. This ensures that 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectobjects the debugger might care about don't go away. This is straightforward, 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbut it can cause us to hold on to large objects and prevent finalizers from 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbeing executed. 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project(3) Keep a list of what amount to weak object references. This way we 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectdon't interfere with the GC, and can support JDWP requests like 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"ObjectReference.IsCollected". 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectThe current implementation is #2. The set should be reasonably small and 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectperformance isn't critical, so a simple expanding array can be used. 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNotes on threads: 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectThe VM has a Thread struct associated with every active thread. The 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectThreadId we pass to the debugger is the ObjectId for the java/lang/Thread 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectobject, so to retrieve the VM's Thread struct we have to scan through the 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectlist looking for a match. 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectWhen a thread goes away, we lock the list and free the struct. To 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectavoid having the thread list updated or Thread structs freed out from 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectunder us, we want to acquire and hold the thread list lock while we're 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectperforming operations on Threads. Exceptions to this rule are noted in 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecta couple of places. 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectWe can speed this up a bit by adding a Thread struct pointer to the 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectjava/lang/Thread object, and ensuring that both are discarded at the 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectsame time. 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/ 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define THREAD_GROUP_ALL ((ObjectId) 0x12345) // magic, internal-only value 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kSlot0Sub 1000 // Eclipse workaround 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * System init. We don't allocate the registry until first use. 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Make sure we do this before initializing JDWP. 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 981e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirobool dvmDebuggerStartup() 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 10096516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden if (!dvmBreakpointStartup()) 10196516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden return false; 10296516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.dbgRegistry = dvmHashTableCreate(1000, NULL); 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (gDvm.dbgRegistry != NULL); 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free registry storage. 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1101e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirovoid dvmDebuggerShutdown() 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableFree(gDvm.dbgRegistry); 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.dbgRegistry = NULL; 11496516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden dvmBreakpointShutdown(); 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Pass these through to the VM functions. Allows extended checking 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (e.g. "errorcheck" mutexes). If nothing else we can assert() success. 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgInitMutex(pthread_mutex_t* pMutex) 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInitMutex(pMutex); 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgLockMutex(pthread_mutex_t* pMutex) 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockMutex(pMutex); 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgUnlockMutex(pthread_mutex_t* pMutex) 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockMutex(pMutex); 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgInitCond(pthread_cond_t* pCond) 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pthread_cond_init(pCond, NULL); 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgCondWait(pthread_cond_t* pCond, pthread_mutex_t* pMutex) 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 140b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro int cc __attribute__ ((__unused__)) = pthread_cond_wait(pCond, pMutex); 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(cc == 0); 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgCondSignal(pthread_cond_t* pCond) 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 145b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro int cc __attribute__ ((__unused__)) = pthread_cond_signal(pCond); 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(cc == 0); 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgCondBroadcast(pthread_cond_t* pCond) 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 150b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro int cc __attribute__ ((__unused__)) = pthread_cond_broadcast(pCond); 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(cc == 0); 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* keep track of type, in case we need to distinguish them someday */ 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef enum RegistryType { 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kObjectId = 0xc1, kRefTypeId 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} RegistryType; 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Hash function for object IDs. Since objects are at least 8 bytes, and 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * could someday be allocated on 16-byte boundaries, we don't want to use 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the low 4 bits in our hash. 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline u4 registryHash(u4 val) 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return val >> 4; 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (This is a dvmHashTableLookup() callback.) 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int registryCompare(const void* obj1, const void* obj2) 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (int) obj1 - (int) obj2; 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine if an id is already in the list. 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the list doesn't yet exist, this creates it. 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Lock the registry before calling here. 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 186b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro#ifndef NDEBUG 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool lookupId(ObjectId id) 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* found; 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project found = dvmHashTableLookup(gDvm.dbgRegistry, registryHash((u4) id), 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (void*)(u4) id, registryCompare, false); 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (found == NULL) 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(found == (void*)(u4) id); 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 198b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro#endif 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Register an object, if it hasn't already been. 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is used for both ObjectId and RefTypeId. In theory we don't have 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to register RefTypeIds unless we're worried about classes unloading. 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Null references must be represented as zero, or the debugger will get 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * very confused. 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ObjectId registerObject(const Object* obj, RegistryType type, bool reg) 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ObjectId id; 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj == NULL) 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert((u4) obj != 0xcccccccc); 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert((u4) obj > 0x100); 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = (ObjectId)(u4)obj | ((u8) type) << 32; 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!reg) 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return id; 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableLock(gDvm.dbgRegistry); 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!gDvm.debuggerConnected) { 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* debugger has detached while we were doing stuff? */ 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("ignoring registerObject request in thread=%d\n", 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThreadSelf()->threadId); 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //dvmAbort(); 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2321e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapiro dvmHashTableLookup(gDvm.dbgRegistry, registryHash((u4) id), 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (void*)(u4) id, registryCompare, true); 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableUnlock(gDvm.dbgRegistry); 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return id; 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that an object has been registered. If it hasn't, the debugger 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is asking for something we didn't send it, which means something 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * somewhere is broken. 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If speed is an issue we can encode the registry index in the high 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * four bytes. We could also just hard-wire this to "true". 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note this actually takes both ObjectId and RefTypeId. 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 250b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro#ifndef NDEBUG 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool objectIsRegistered(ObjectId id, RegistryType type) 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UNUSED_PARAMETER(type); 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (id == 0) // null reference? 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableLock(gDvm.dbgRegistry); 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool result = lookupId(id); 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableUnlock(gDvm.dbgRegistry); 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 263b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro#endif 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert to/from a RefTypeId. 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * These are rarely NULL, but can be (e.g. java/lang/Object's superclass). 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RefTypeId classObjectToRefTypeId(ClassObject* clazz) 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (RefTypeId) registerObject((Object*) clazz, kRefTypeId, true); 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 274e3c01dac83e6eea7f82fe81ed89cfbdd9791dbc9Carl Shapiro#if 0 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RefTypeId classObjectToRefTypeIdNoReg(ClassObject* clazz) 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (RefTypeId) registerObject((Object*) clazz, kRefTypeId, false); 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 279e3c01dac83e6eea7f82fe81ed89cfbdd9791dbc9Carl Shapiro#endif 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* refTypeIdToClassObject(RefTypeId id) 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(objectIsRegistered(id, kRefTypeId) || !gDvm.debuggerConnected); 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (ClassObject*)(u4) id; 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert to/from an ObjectId. 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ObjectId objectToObjectId(const Object* obj) 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return registerObject(obj, kObjectId, true); 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ObjectId objectToObjectIdNoReg(const Object* obj) 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return registerObject(obj, kObjectId, false); 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Object* objectIdToObject(ObjectId id) 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(objectIsRegistered(id, kObjectId) || !gDvm.debuggerConnected); 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (Object*)(u4) id; 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 304c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * Register an object ID that might not have been registered previously. 305c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * 306c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * Normally this wouldn't happen -- the conversion to an ObjectId would 307c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * have added the object to the registry -- but in some cases (e.g. 308c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * throwing exceptions) we really want to do the registration late. 309c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden */ 310c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFaddenvoid dvmDbgRegisterObjectId(ObjectId id) 311c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden{ 312c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden Object* obj = (Object*)(u4) id; 313c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden LOGV("+++ registering %p (%s)\n", obj, obj->clazz->descriptor); 314c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden registerObject(obj, kObjectId, true); 315c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden} 316c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden 317c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden/* 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert to/from a MethodId. 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * These IDs are only guaranteed unique within a class, so they could be 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an enumeration index. For now we just use the Method*. 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic MethodId methodToMethodId(const Method* meth) 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (MethodId)(u4) meth; 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Method* methodIdToMethod(RefTypeId refTypeId, MethodId id) 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // TODO? verify "id" is actually a method in "refTypeId" 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (Method*)(u4) id; 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert to/from a FieldId. 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * These IDs are only guaranteed unique within a class, so they could be 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an enumeration index. For now we just use the Field*. 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic FieldId fieldToFieldId(const Field* field) 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (FieldId)(u4) field; 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Field* fieldIdToField(RefTypeId refTypeId, FieldId id) 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // TODO? verify "id" is actually a field in "refTypeId" 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (Field*)(u4) id; 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert to/from a FrameId. 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We just return a pointer to the stack frame. 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic FrameId frameToFrameId(const void* frame) 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (FrameId)(u4) frame; 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 358fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapirostatic u4* frameIdToFrame(FrameId id) 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 360fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro return (u4*)(u4) id; 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the invocation request state. 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3671e1433e78f560a01744e870c19c162ab88df9dc1Carl ShapiroDebugInvokeReq* dvmDbgGetInvokeReq() 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return &dvmThreadSelf()->invokeReq; 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Enable the object registry, but don't enable debugging features yet. 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only called from the JDWP handler thread. 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3771e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirovoid dvmDbgConnected() 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!gDvm.debuggerConnected); 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("JDWP has attached\n"); 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmHashTableNumEntries(gDvm.dbgRegistry) == 0); 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.debuggerConnected = true; 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Enable all debugging features, including scans for breakpoints. 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is a no-op if we're already active. 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only called from the JDWP handler thread. 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3931e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirovoid dvmDbgActive() 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 3959a3147c7412f4794434b4c2604aa2ba784867774buzbee if (gDvm.debuggerActive) 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("Debugger is active\n"); 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInitBreakpoints(); 4009a3147c7412f4794434b4c2604aa2ba784867774buzbee gDvm.debuggerActive = true; 4019a3147c7412f4794434b4c2604aa2ba784867774buzbee dvmUpdateAllInterpBreak(kInterpDebugBreak, kSubModeDebuggerActive, true); 40299e3e6e72e3471eb85fc2e405866392b01c080febuzbee#if defined(WITH_JIT) 40399e3e6e72e3471eb85fc2e405866392b01c080febuzbee dvmCompilerUpdateGlobalState(); 40499e3e6e72e3471eb85fc2e405866392b01c080febuzbee#endif 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Disable debugging features. 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set "debuggerConnected" to false, which disables use of the object 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * registry. 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only called from the JDWP handler thread. 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4151e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirovoid dvmDbgDisconnected() 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(gDvm.debuggerConnected); 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4199a3147c7412f4794434b4c2604aa2ba784867774buzbee gDvm.debuggerActive = false; 4209a3147c7412f4794434b4c2604aa2ba784867774buzbee dvmUpdateAllInterpBreak(kInterpDebugBreak, kSubModeDebuggerActive, false); 42199e3e6e72e3471eb85fc2e405866392b01c080febuzbee#if defined(WITH_JIT) 42299e3e6e72e3471eb85fc2e405866392b01c080febuzbee dvmCompilerUpdateGlobalState(); 42399e3e6e72e3471eb85fc2e405866392b01c080febuzbee#endif 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableLock(gDvm.dbgRegistry); 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.debuggerConnected = false; 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4282fbe6d15ed8d266ed55fb76e97f866dbd07d5fa6Andy McFadden LOGD("Debugger has detached; object registry had %d entries\n", 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableNumEntries(gDvm.dbgRegistry)); 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //int i; 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //for (i = 0; i < gDvm.dbgRegistryNext; i++) 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // LOGVV("%4d: 0x%llx\n", i, gDvm.dbgRegistryTable[i]); 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableClear(gDvm.dbgRegistry); 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableUnlock(gDvm.dbgRegistry); 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if a debugger is connected. 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Does not return "true" if it's just a DDM server. 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4431e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirobool dvmDbgIsDebuggerConnected() 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 4459a3147c7412f4794434b4c2604aa2ba784867774buzbee return gDvm.debuggerActive; 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get time since last debugger activity. Used when figuring out if the 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * debugger has finished configuring us. 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4521e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapiros8 dvmDbgLastDebuggerActivity() 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dvmJdwpLastDebuggerActivity(gDvm.jdwpState); 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JDWP thread is running, don't allow GC. 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4601e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapiroint dvmDbgThreadRunning() 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 462d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro ThreadStatus oldStatus = dvmChangeStatus(NULL, THREAD_RUNNING); 463d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro return static_cast<int>(oldStatus); 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JDWP thread is idle, allow GC. 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4691e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapiroint dvmDbgThreadWaiting() 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 471d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro ThreadStatus oldStatus = dvmChangeStatus(NULL, THREAD_VMWAIT); 472d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro return static_cast<int>(oldStatus); 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Restore state returned by Running/Waiting calls. 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgThreadContinuing(int status) 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 480d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro ThreadStatus newStatus = static_cast<ThreadStatus>(status); 481d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro ThreadStatus oldStatus = dvmChangeStatus(NULL, newStatus); 482d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro return static_cast<int>(oldStatus); 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The debugger wants us to exit. 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgExit(int status) 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // TODO? invoke System.exit() to perform exit processing; ends up 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // in System.exitInternal(), which can call JNI exit hook 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("GC lifetime allocation: %d bytes\n", gDvm.allocProf.allocCount); 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (CALC_CACHE_STATS) { 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDumpAtomicCacheStats(gDvm.instanceofCache); 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDumpBootClassPath(); 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef PROFILE_FIELD_ACCESS 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDumpFieldAccessCounts(); 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exit(status); 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Class, Object, Array 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the class's type descriptor from a reference type ID. 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char* dvmDbgGetClassDescriptor(RefTypeId id) 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = refTypeIdToClassObject(id); 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return clazz->descriptor; 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 5236ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden * Convert a RefTypeId to an ObjectId. 5246ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden */ 5256ff3c8fde9623dadad726dbd5e1658585c321751Andy McFaddenObjectId dvmDbgGetClassObject(RefTypeId id) 5266ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden{ 5276ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden ClassObject* clazz = refTypeIdToClassObject(id); 5286ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden return objectToObjectId((Object*) clazz); 5296ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden} 5306ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden 5316ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden/* 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the superclass of a class (will be NULL for java/lang/Object). 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectRefTypeId dvmDbgGetSuperclass(RefTypeId id) 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = refTypeIdToClassObject(id); 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return classObjectToRefTypeId(clazz->super); 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a class's defining class loader. 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectRefTypeId dvmDbgGetClassLoader(RefTypeId id) 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = refTypeIdToClassObject(id); 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return objectToObjectId(clazz->classLoader); 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a class's access flags. 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu4 dvmDbgGetAccessFlags(RefTypeId id) 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = refTypeIdToClassObject(id); 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return clazz->accessFlags & JAVA_FLAGS_MASK; 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Is this class an interface? 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgIsInterface(RefTypeId id) 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = refTypeIdToClassObject(id); 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dvmIsInterfaceClass(clazz); 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dvmHashForeach callback 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int copyRefType(void* vclazz, void* varg) 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RefTypeId** pRefType = (RefTypeId**)varg; 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project **pRefType = classObjectToRefTypeId((ClassObject*) vclazz); 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (*pRefType)++; 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the complete list of reference classes (i.e. all classes except 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the primitive types). 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated buffer full of RefTypeId values. 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetClassList(u4* pNumClasses, RefTypeId** pClassRefBuf) 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RefTypeId* pRefType; 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableLock(gDvm.loadedClasses); 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pNumClasses = dvmHashTableNumEntries(gDvm.loadedClasses); 590fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro pRefType = *pClassRefBuf = 591fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro (RefTypeId*)malloc(sizeof(RefTypeId) * *pNumClasses); 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmHashForeach(gDvm.loadedClasses, copyRefType, &pRefType) != 0) { 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Warning: problem getting class list\n"); 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* not really expecting this to happen */ 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pRefType - *pClassRefBuf == (int) *pNumClasses); 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableUnlock(gDvm.loadedClasses); 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the list of reference classes "visible" to the specified class 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * loader. A class is visible to a class loader if the ClassLoader object 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is the defining loader or is listed as an initiating loader. 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated buffer full of RefTypeId values. 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetVisibleClassList(ObjectId classLoaderId, u4* pNumClasses, 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RefTypeId** pClassRefBuf) 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* classLoader; 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numClasses = 0, maxClasses; 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project classLoader = objectIdToObject(classLoaderId); 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // I don't think classLoader can be NULL, but the spec doesn't say 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("GetVisibleList: comparing to %p\n", classLoader); 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableLock(gDvm.loadedClasses); 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* over-allocate the return buffer */ 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project maxClasses = dvmHashTableNumEntries(gDvm.loadedClasses); 625fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro *pClassRefBuf = (RefTypeId*)malloc(sizeof(RefTypeId) * maxClasses); 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Run through the list, looking for matches. 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HashIter iter; 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (dvmHashIterBegin(gDvm.loadedClasses, &iter); !dvmHashIterDone(&iter); 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashIterNext(&iter)) 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = (ClassObject*) dvmHashIterData(&iter); 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz->classLoader == classLoader || 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLoaderInInitiatingList(clazz, classLoader)) 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV(" match '%s'\n", clazz->descriptor); 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (*pClassRefBuf)[numClasses++] = classObjectToRefTypeId(clazz); 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pNumClasses = numClasses; 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHashTableUnlock(gDvm.loadedClasses); 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 6490970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Get the "JNI signature" for a class, e.g. "Ljava/lang/String;". 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 6510970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Our class descriptors are in the correct format, so we just return that. 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 6530970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenstatic const char* jniSignature(ClassObject* clazz) 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 6550970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return clazz->descriptor; 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get information about a class. 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "pSignature" is not NULL, *pSignature gets the "JNI signature" of 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the class. 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetClassInfo(RefTypeId classId, u1* pTypeTag, u4* pStatus, 6650970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden const char** pSignature) 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = refTypeIdToClassObject(classId); 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz->descriptor[0] == '[') { 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* generated array class */ 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pStatus = CS_VERIFIED | CS_PREPARED; 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pTypeTag = TT_ARRAY; 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz->status == CLASS_ERROR) 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pStatus = CS_ERROR; 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pStatus = CS_VERIFIED | CS_PREPARED | CS_INITIALIZED; 678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsInterfaceClass(clazz)) 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pTypeTag = TT_INTERFACE; 680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pTypeTag = TT_CLASS; 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pSignature != NULL) 6840970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden *pSignature = jniSignature(clazz); 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Search the list of loaded classes for a match. 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgFindLoadedClassBySignature(const char* classDescriptor, 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RefTypeId* pRefTypeId) 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = dvmFindLoadedClass(classDescriptor); 696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz != NULL) { 697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pRefTypeId = classObjectToRefTypeId(clazz); 698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else 700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get an object's class and "type tag". 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetObjectType(ObjectId objectId, u1* pRefTypeTag, 708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RefTypeId* pRefTypeId) 709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* obj = objectIdToObject(objectId); 711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsArrayClass(obj->clazz)) 713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pRefTypeTag = TT_ARRAY; 714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else if (dvmIsInterfaceClass(obj->clazz)) 715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pRefTypeTag = TT_INTERFACE; 716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pRefTypeTag = TT_CLASS; 718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pRefTypeId = classObjectToRefTypeId(obj->clazz); 719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get a class object's "type tag". 723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu1 dvmDbgGetClassObjectType(RefTypeId refTypeId) 725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = refTypeIdToClassObject(refTypeId); 727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsArrayClass(clazz)) 729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return TT_ARRAY; 730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else if (dvmIsInterfaceClass(clazz)) 731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return TT_INTERFACE; 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return TT_CLASS; 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get a class' signature. 738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 7390970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenconst char* dvmDbgGetSignature(RefTypeId refTypeId) 740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = refTypeIdToClassObject(refTypeId); 744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(clazz != NULL); 745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7460970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return jniSignature(clazz); 747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get class' source file. 751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string. 753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char* dvmDbgGetSourceFile(RefTypeId refTypeId) 755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = refTypeIdToClassObject(refTypeId); 759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(clazz != NULL); 760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return clazz->sourceFile; 762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 7650970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Get an object's type name. (For log message display only.) 766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 7670970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenconst char* dvmDbgGetObjectTypeName(ObjectId objectId) 768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 7690970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden if (objectId == 0) 7700970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return "(null)"; 771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7720970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden Object* obj = objectIdToObject(objectId); 7730970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return jniSignature(obj->clazz); 774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 7770970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Determine whether or not a tag represents a primitive type. 778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 7790970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenstatic bool isTagPrimitive(u1 tag) 780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 7810970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden switch (tag) { 7820970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_BYTE: 7830970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_CHAR: 7840970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_FLOAT: 7850970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_DOUBLE: 7860970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_INT: 7870970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_LONG: 7880970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_SHORT: 7890970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_VOID: 7900970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_BOOLEAN: 7910970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return true; 7920970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_ARRAY: 7930970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_OBJECT: 7940970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_STRING: 7950970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_CLASS_OBJECT: 7960970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_THREAD: 7970970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_THREAD_GROUP: 7980970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_CLASS_LOADER: 7990970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return false; 800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 8010970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden LOGE("ERROR: unhandled tag '%c'\n", tag); 802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 8030970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return false; 804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 8080970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Determine the best tag type given an object's class. 809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 8100970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenstatic u1 tagFromClass(ClassObject* clazz) 811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 8120970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden if (dvmIsArrayClass(clazz)) 8130970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return JT_ARRAY; 814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 8150970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden if (clazz == gDvm.classJavaLangString) { 816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return JT_STRING; 817c6d2470eec726ae0ad95e4fd2d9d7da7cb2cdcbaDan Bornstein } else if (dvmIsTheClassClass(clazz)) { 818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return JT_CLASS_OBJECT; 8190970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden } else if (dvmInstanceof(clazz, gDvm.classJavaLangThread)) { 820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return JT_THREAD; 8210970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden } else if (dvmInstanceof(clazz, gDvm.classJavaLangThreadGroup)) { 822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return JT_THREAD_GROUP; 8230970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden } else if (dvmInstanceof(clazz, gDvm.classJavaLangClassLoader)) { 824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return JT_CLASS_LOADER; 8250970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden } else { 826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return JT_OBJECT; 8270970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden } 828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 8310970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Return a basic tag value based solely on a type descriptor. 8320970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * 8330970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * The ASCII value maps directly to the JDWP tag constants, so we don't 8340970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * need to do much here. This does not return the fancier tags like 8350970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * JT_THREAD. 836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 8370970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenstatic u1 basicTagFromDescriptor(const char* descriptor) 838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 8390970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return descriptor[0]; 8400970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden} 841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 8420970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden/* 8430970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Objects declared to hold Object might actually hold a more specific 8440970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * type. The debugger may take a special interest in these (e.g. it 8450970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * wants to display the contents of Strings), so we want to return an 8460970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * appropriate tag. 8470970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * 8480970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Null objects are tagged JT_OBJECT. 8490970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden */ 8500970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenstatic u1 tagFromObject(const Object* obj) 8510970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden{ 8520970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden if (obj == NULL) 8530970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return JT_OBJECT; 8540970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return tagFromClass(obj->clazz); 8550970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden} 856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 8570970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden/* 8580970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Determine the tag for an object. 8590970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * 8600970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * "objectId" may be 0 (i.e. NULL reference). 8610970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden */ 8620970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenu1 dvmDbgGetObjectTag(ObjectId objectId) 8630970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden{ 8640970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return tagFromObject(objectIdToObject(objectId)); 865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the widths of the specified JDWP.Tag value. 869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgGetTagWidth(int tag) 871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (tag) { 873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_VOID: 874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_BYTE: 876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_BOOLEAN: 877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_CHAR: 879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_SHORT: 880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 2; 881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_FLOAT: 882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_INT: 883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 4; 884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_ARRAY: 885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_OBJECT: 886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_STRING: 887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_THREAD: 888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_THREAD_GROUP: 889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_CLASS_LOADER: 890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_CLASS_OBJECT: 891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sizeof(ObjectId); 892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_DOUBLE: 893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_LONG: 894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 8; 895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("ERROR: unhandled tag '%c'\n", tag); 897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the length of the specified array. 905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgGetArrayLength(ObjectId arrayId) 907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* arrayObj = (ArrayObject*) objectIdToObject(arrayId); 909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmIsArray(arrayObj)); 910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return arrayObj->length; 911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a tag indicating the general type of elements in the array. 915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 9160970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenu1 dvmDbgGetArrayElementTag(ObjectId arrayId) 917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* arrayObj = (ArrayObject*) objectIdToObject(arrayId); 919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 9200970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden ClassObject* arrayClass = arrayObj->obj.clazz; 9210970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden u1 tag = basicTagFromDescriptor(arrayClass->descriptor + 1); 9220970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden if (!isTagPrimitive(tag)) { 9230970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden /* try to refine it */ 9240970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden tag = tagFromClass(arrayClass->elementClass); 9250970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden } 926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 9270970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return tag; 928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy a series of values with the specified width, changing the byte 932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ordering to big-endian. 933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void copyValuesToBE(u1* out, const u1* in, int count, int width) 935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (width) { 939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 1: 940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(out, in, count); 941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 2: 943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < count; i++) 944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *(((u2*) out)+i) = get2BE(in + i*2); 945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 4: 947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < count; i++) 948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *(((u4*) out)+i) = get4BE(in + i*4); 949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 8: 951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < count; i++) 952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *(((u8*) out)+i) = get8BE(in + i*8); 953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 9600970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Copy a series of values with the specified width, changing the 961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * byte order from big-endian. 962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void copyValuesFromBE(u1* out, const u1* in, int count, int width) 964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (width) { 968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 1: 969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(out, in, count); 970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 2: 972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < count; i++) 973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set2BE(out + i*2, *((u2*)in + i)); 974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 4: 976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < count; i++) 977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(out + i*4, *((u4*)in + i)); 978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 8: 980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < count; i++) 981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set8BE(out + i*8, *((u8*)in + i)); 982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Output a piece of an array to the reply buffer. 990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "false" if something looks fishy. 992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgOutputArray(ObjectId arrayId, int firstIndex, int count, 994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExpandBuf* pReply) 995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* arrayObj = (ArrayObject*) objectIdToObject(arrayId); 997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1* data = (const u1*)arrayObj->contents; 998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 tag; 999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmIsArray(arrayObj)); 1001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (firstIndex + count > (int)arrayObj->length) { 1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Request for index=%d + count=%d excceds length=%d\n", 1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project firstIndex, count, arrayObj->length); 1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 10080970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden tag = basicTagFromDescriptor(arrayObj->obj.clazz->descriptor + 1); 1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isTagPrimitive(tag)) { 1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int width = dvmDbgGetTagWidth(tag); 1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1* outBuf; 1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outBuf = expandBufAddSpace(pReply, count * width); 1015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyValuesToBE(outBuf, data + firstIndex*width, count, width); 1017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object** pObjects; 1019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 1020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pObjects = (Object**) data; 1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pObjects += firstIndex; 1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV(" --> copying %d object IDs\n", count); 1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //assert(tag == JT_OBJECT); // could be object or "refined" type 1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < count; i++, pObjects++) { 1028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 thisTag; 1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*pObjects != NULL) 10300970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden thisTag = tagFromObject(*pObjects); 1031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 1032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisTag = tag; 1033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd1(pReply, thisTag); 1034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddObjectId(pReply, objectToObjectId(*pObjects)); 1035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 1039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set a range of elements in an array from the data in "buf". 1043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgSetArrayElements(ObjectId arrayId, int firstIndex, int count, 1045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1* buf) 1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* arrayObj = (ArrayObject*) objectIdToObject(arrayId); 1048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1* data = (u1*)arrayObj->contents; 1049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 tag; 1050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmIsArray(arrayObj)); 1052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (firstIndex + count > (int)arrayObj->length) { 1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Attempt to set index=%d + count=%d excceds length=%d\n", 1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project firstIndex, count, arrayObj->length); 1056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 10590970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden tag = basicTagFromDescriptor(arrayObj->obj.clazz->descriptor + 1); 1060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isTagPrimitive(tag)) { 1062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int width = dvmDbgGetTagWidth(tag); 1063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV(" --> setting %d '%c' width=%d\n", count, tag, width); 1065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copyValuesFromBE(data + firstIndex*width, buf, count, width); 1067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object** pObjects; 1069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 1070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pObjects = (Object**) data; 1072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pObjects += firstIndex; 1073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV(" --> setting %d objects", count); 1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* should do array type check here */ 1077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < count; i++) { 1078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ObjectId id = dvmReadObjectId(&buf); 1079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pObjects++ = objectIdToObject(id); 1080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 1084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a new string. 1088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The only place the reference will be held in the VM is in our registry. 1090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectId dvmDbgCreateString(const char* str) 1092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringObject* strObj; 1094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 109581f3ebe03cd33c9003641084bece0604ee68bf88Barry Hayes strObj = dvmCreateStringFromCstr(str); 1096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc((Object*) strObj, NULL); 1097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return objectToObjectId((Object*) strObj); 1098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1101f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden * Allocate a new object of the specified type. 1102f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden * 1103f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden * Add it to the registry to prevent it from being GCed. 1104f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden */ 1105f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFaddenObjectId dvmDbgCreateObject(RefTypeId classId) 1106f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden{ 1107f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden ClassObject* clazz = refTypeIdToClassObject(classId); 1108f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden Object* newObj = dvmAllocObject(clazz, ALLOC_DEFAULT); 1109f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden dvmReleaseTrackedAlloc(newObj, NULL); 1110f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden return objectToObjectId(newObj); 1111f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden} 1112f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden 1113f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden/* 1114884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden * Allocate a new array object of the specified type and length. The 1115884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden * type is the array type, not the element type. 1116884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden * 1117884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden * Add it to the registry to prevent it from being GCed. 1118884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden */ 1119884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFaddenObjectId dvmDbgCreateArrayObject(RefTypeId arrayTypeId, u4 length) 1120884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden{ 1121884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden ClassObject* clazz = refTypeIdToClassObject(arrayTypeId); 1122884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden Object* newObj = (Object*) dvmAllocArrayByClass(clazz, length, ALLOC_DEFAULT); 1123884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden dvmReleaseTrackedAlloc(newObj, NULL); 1124884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden return objectToObjectId(newObj); 1125884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden} 1126884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden 1127884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden/* 1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine if "instClassId" is an instance of "classId". 1129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgMatchType(RefTypeId instClassId, RefTypeId classId) 1131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* instClazz = refTypeIdToClassObject(instClassId); 1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = refTypeIdToClassObject(classId); 1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dvmInstanceof(instClazz, clazz); 1136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Method and Field 1142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the method name from a MethodId. 1147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char* dvmDbgGetMethodName(RefTypeId refTypeId, MethodId id) 1149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* meth; 1151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth = methodIdToMethod(refTypeId, id); 1153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return meth->name; 1154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 11570970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Augment the access flags for synthetic methods and fields by setting 115886c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden * the (as described by the spec) "0xf0000000 bit". Also, strip out any 115986c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden * flags not specified by the Java programming language. 11600970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden */ 11610970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenstatic u4 augmentedAccessFlags(u4 accessFlags) 11620970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden{ 116386c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden accessFlags &= JAVA_FLAGS_MASK; 116486c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden 11650970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden if ((accessFlags & ACC_SYNTHETIC) != 0) { 11660970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return accessFlags | 0xf0000000; 11670970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden } else { 11680970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return accessFlags; 11690970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden } 11700970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden} 11710970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden 11720970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden/* 1173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For ReferenceType.Fields and ReferenceType.FieldsWithGeneric: 11740970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * output all fields declared by the class. Inherited fields are 1175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not included. 1176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgOutputAllFields(RefTypeId refTypeId, bool withGeneric, 1178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExpandBuf* pReply) 1179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1180d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro ClassObject* clazz = refTypeIdToClassObject(refTypeId); 1181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(clazz != NULL); 1182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1183d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro u4 declared = clazz->sfieldCount + clazz->ifieldCount; 1184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReply, declared); 1185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1186d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro for (int i = 0; i < clazz->sfieldCount; i++) { 1187d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro Field* field = &clazz->sfields[i].field; 1188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddFieldId(pReply, fieldToFieldId(field)); 1189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pReply, (const u1*) field->name); 1190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pReply, (const u1*) field->signature); 1191d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro if (withGeneric) { 1192d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro static const u1 genericSignature[1] = ""; 1193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pReply, genericSignature); 1194d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro } 11950970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd4BE(pReply, augmentedAccessFlags(field->accessFlags)); 1196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1197d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro for (int i = 0; i < clazz->ifieldCount; i++) { 1198d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro Field* field = (Field*)&clazz->ifields[i].field; 1199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddFieldId(pReply, fieldToFieldId(field)); 1200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pReply, (const u1*) field->name); 1201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pReply, (const u1*) field->signature); 1202d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro if (withGeneric) { 1203d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro static const u1 genericSignature[1] = ""; 1204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pReply, genericSignature); 1205d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro } 12060970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd4BE(pReply, augmentedAccessFlags(field->accessFlags)); 1207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For ReferenceType.Methods and ReferenceType.MethodsWithGeneric: 1212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * output all methods declared by the class. Inherited methods are 1213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not included. 1214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgOutputAllMethods(RefTypeId refTypeId, bool withGeneric, 1216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExpandBuf* pReply) 1217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexStringCache stringCache; 1219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static const u1 genericSignature[1] = ""; 1220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 1221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* meth; 1222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 declared; 1223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 1224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringCacheInit(&stringCache); 1226de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = refTypeIdToClassObject(refTypeId); 1228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(clazz != NULL); 1229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project declared = clazz->directMethodCount + clazz->virtualMethodCount; 1231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReply, declared); 1232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < clazz->directMethodCount; i++) { 1234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth = &clazz->directMethods[i]; 1235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddMethodId(pReply, methodToMethodId(meth)); 1237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pReply, (const u1*) meth->name); 1238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pReply, 1240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (const u1*) dexProtoGetMethodDescriptor(&meth->prototype, 1241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &stringCache)); 1242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (withGeneric) 1244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pReply, genericSignature); 12450970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd4BE(pReply, augmentedAccessFlags(meth->accessFlags)); 1246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < clazz->virtualMethodCount; i++) { 1248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth = &clazz->virtualMethods[i]; 1249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddMethodId(pReply, methodToMethodId(meth)); 1251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pReply, (const u1*) meth->name); 1252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pReply, 1254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (const u1*) dexProtoGetMethodDescriptor(&meth->prototype, 1255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &stringCache)); 1256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (withGeneric) 1258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pReply, genericSignature); 12590970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd4BE(pReply, augmentedAccessFlags(meth->accessFlags)); 1260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringCacheRelease(&stringCache); 1263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Output all interfaces directly implemented by the class. 1267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgOutputAllInterfaces(RefTypeId refTypeId, ExpandBuf* pReply) 1269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 1271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, start, count; 1272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = refTypeIdToClassObject(refTypeId); 1274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(clazz != NULL); 1275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz->super == NULL) 1277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project start = 0; 1278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 1279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project start = clazz->super->iftableCount; 1280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count = clazz->iftableCount - start; 1282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReply, count); 1283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = start; i < clazz->iftableCount; i++) { 1284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* iface = clazz->iftable[i].clazz; 1285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddRefTypeId(pReply, classObjectToRefTypeId(iface)); 1286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct DebugCallbackContext { 1290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numItems; 1291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExpandBuf* pReply; 1292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // used by locals table 1293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool withGeneric; 1294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} DebugCallbackContext; 1295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1296de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapirostatic int lineTablePositionsCb(void *cnxt, u4 address, u4 lineNum) 1297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DebugCallbackContext *pContext = (DebugCallbackContext *)cnxt; 1299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd8BE(pContext->pReply, address); 1301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pContext->pReply, lineNum); 1302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pContext->numItems++; 1303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 1305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For Method.LineTable: output the line table. 1309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note we operate in Dalvik's 16-bit units rather than bytes. 1311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgOutputLineTable(RefTypeId refTypeId, MethodId methodId, 1313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExpandBuf* pReply) 1314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* method; 1316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u8 start, end; 1317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DebugCallbackContext context; 1318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset (&context, 0, sizeof(DebugCallbackContext)); 1320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = methodIdToMethod(refTypeId, methodId); 1322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsNativeMethod(method)) { 1323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project start = (u8) -1; 1324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project end = (u8) -1; 1325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project start = 0; 1327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project end = dvmGetMethodInsnsSize(method); 1328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd8BE(pReply, start); 1331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd8BE(pReply, end); 1332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Add numLines later 1334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t numLinesOffset = expandBufGetLength(pReply); 1335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReply, 0); 1336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project context.pReply = pReply; 1338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexDecodeDebugInfo(method->clazz->pDvmDex->pDexFile, 1340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmGetMethodCode(method), 1341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->clazz->descriptor, 1342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->prototype.protoIdx, 1343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->accessFlags, 1344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lineTablePositionsCb, NULL, &context); 1345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(expandBufGetBuffer(pReply) + numLinesOffset, context.numItems); 1347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Eclipse appears to expect that the "this" reference is in slot zero. 1351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If it's not, the "variables" display will show two copies of "this", 1352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * possibly because it gets "this" from SF.ThisObject and then displays 1353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * all locals with nonzero slot numbers. 1354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * So, we remap the item in slot 0 to 1000, and remap "this" to zero. On 1356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * SF.GetValues / SF.SetValues we map them back. 1357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int tweakSlot(int slot, const char* name) 1359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int newSlot = slot; 1361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(name, "this") == 0) // only remap "this" ptr 1363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newSlot = 0; 1364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else if (slot == 0) // always remap slot 0 1365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newSlot = kSlot0Sub; 1366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("untweak: %d to %d\n", slot, newSlot); 1368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return newSlot; 1369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Reverse Eclipse hack. 1373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int untweakSlot(int slot, const void* framePtr) 1375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int newSlot = slot; 1377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (slot == kSlot0Sub) { 1379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newSlot = 0; 1380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (slot == 0) { 1381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const StackSaveArea* saveArea = SAVEAREA_FROM_FP(framePtr); 1382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const Method* method = saveArea->method; 1383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newSlot = method->registersSize - method->insSize; 1384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("untweak: %d to %d\n", slot, newSlot); 1387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return newSlot; 1388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void variableTableCb (void *cnxt, u2 reg, u4 startAddress, 1391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 endAddress, const char *name, const char *descriptor, 1392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *signature) 1393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DebugCallbackContext *pContext = (DebugCallbackContext *)cnxt; 1395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project reg = (u2) tweakSlot(reg, name); 1397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV(" %2d: %d(%d) '%s' '%s' slot=%d\n", 1399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pContext->numItems, startAddress, endAddress - startAddress, 1400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project name, descriptor, reg); 1401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd8BE(pContext->pReply, startAddress); 1403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pContext->pReply, (const u1*)name); 1404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pContext->pReply, (const u1*)descriptor); 1405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pContext->withGeneric) { 1406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pContext->pReply, (const u1*) signature); 1407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pContext->pReply, endAddress - startAddress); 1409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pContext->pReply, reg); 1410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pContext->numItems++; 1412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For Method.VariableTable[WithGeneric]: output information about local 1416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * variables for the specified method. 1417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgOutputVariableTable(RefTypeId refTypeId, MethodId methodId, 1419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool withGeneric, ExpandBuf* pReply) 1420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* method; 1422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DebugCallbackContext context; 1423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset (&context, 0, sizeof(DebugCallbackContext)); 1425de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = methodIdToMethod(refTypeId, methodId); 1427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReply, method->insSize); 1429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Add numLocals later 1431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t numLocalsOffset = expandBufGetLength(pReply); 1432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReply, 0); 1433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project context.pReply = pReply; 1435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project context.withGeneric = withGeneric; 1436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexDecodeDebugInfo(method->clazz->pDvmDex->pDexFile, 1437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmGetMethodCode(method), 1438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->clazz->descriptor, 1439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->prototype.protoIdx, 1440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->accessFlags, 1441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project NULL, variableTableCb, &context); 1442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(expandBufGetBuffer(pReply) + numLocalsOffset, context.numItems); 1444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 14470970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Get the basic tag for an instance field. 1448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 14490970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenu1 dvmDbgGetFieldBasicTag(ObjectId objId, FieldId fieldId) 1450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* obj = objectIdToObject(objId); 1452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RefTypeId classId = classObjectToRefTypeId(obj->clazz); 14530970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden const Field* field = fieldIdToField(classId, fieldId); 14540970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return basicTagFromDescriptor(field->signature); 1455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 14580970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Get the basic tag for a static field. 1459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 14600970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenu1 dvmDbgGetStaticFieldBasicTag(RefTypeId refTypeId, FieldId fieldId) 1461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 14620970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden const Field* field = fieldIdToField(refTypeId, fieldId); 14630970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return basicTagFromDescriptor(field->signature); 1464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 14660970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden 1467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 14680970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Copy the value of a static field into the output buffer, preceded 14690970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * by an appropriate tag. The tag is based on the value held by the 14700970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * field, not the field's type. 1471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 14720970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenvoid dvmDbgGetFieldValue(ObjectId objectId, FieldId fieldId, ExpandBuf* pReply) 1473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* obj = objectIdToObject(objectId); 1475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RefTypeId classId = classObjectToRefTypeId(obj->clazz); 14760970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden InstField* ifield = (InstField*) fieldIdToField(classId, fieldId); 14770970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden u1 tag = basicTagFromDescriptor(ifield->field.signature); 14780970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden 14790970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden if (tag == JT_ARRAY || tag == JT_OBJECT) { 14800970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden Object* objVal = dvmGetFieldObject(obj, ifield->byteOffset); 14810970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden tag = tagFromObject(objVal); 14820970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd1(pReply, tag); 14830970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAddObjectId(pReply, objectToObjectId(objVal)); 14840970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden LOGV(" --> ifieldId %x --> tag '%c' %p\n", fieldId, tag, objVal); 14850970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden } else { 14860970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden JValue value; 1487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 14880970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden LOGV(" --> ifieldId %x --> tag '%c'\n", fieldId, tag); 14890970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd1(pReply, tag); 14900970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden 14910970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden switch (tag) { 14920970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_BOOLEAN: 14930970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd1(pReply, dvmGetFieldBoolean(obj, ifield->byteOffset)); 14940970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 14950970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_BYTE: 14960970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd1(pReply, dvmGetFieldByte(obj, ifield->byteOffset)); 14970970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 14980970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_SHORT: 14990970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd2BE(pReply, dvmGetFieldShort(obj, ifield->byteOffset)); 15000970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 15010970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_CHAR: 15020970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd2BE(pReply, dvmGetFieldChar(obj, ifield->byteOffset)); 15030970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 15040970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_INT: 15050970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd4BE(pReply, dvmGetFieldInt(obj, ifield->byteOffset)); 15060970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 15070970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_FLOAT: 15080970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden value.f = dvmGetFieldInt(obj, ifield->byteOffset); 15090970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd4BE(pReply, value.i); 15100970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 15110970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_LONG: 15120970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd8BE(pReply, dvmGetFieldLong(obj, ifield->byteOffset)); 15130970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 15140970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_DOUBLE: 15150970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden value.d = dvmGetFieldInt(obj, ifield->byteOffset); 15160970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd8BE(pReply, value.j); 15170970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 15180970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden default: 15190970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden LOGE("ERROR: unhandled field type '%s'\n", ifield->field.signature); 15200970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden assert(false); 15210970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 15220970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden } 1523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the value of the specified field. 1528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSetFieldValue(ObjectId objectId, FieldId fieldId, u8 value, 1530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int width) 1531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* obj = objectIdToObject(objectId); 1533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RefTypeId classId = classObjectToRefTypeId(obj->clazz); 1534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InstField* field = (InstField*) fieldIdToField(classId, fieldId); 1535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (field->field.signature[0]) { 1537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_BOOLEAN: 1538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 1); 1539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetFieldBoolean(obj, field->byteOffset, value != 0); 1540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_BYTE: 1542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 1); 1543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetFieldInt(obj, field->byteOffset, value); 1544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_SHORT: 1546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_CHAR: 1547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 2); 1548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetFieldInt(obj, field->byteOffset, value); 1549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_INT: 1551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_FLOAT: 1552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 4); 1553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetFieldInt(obj, field->byteOffset, value); 1554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_ARRAY: 1556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_OBJECT: 1557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == sizeof(ObjectId)); 1558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetFieldObject(obj, field->byteOffset, objectIdToObject(value)); 1559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_DOUBLE: 1561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_LONG: 1562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 8); 1563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetFieldLong(obj, field->byteOffset, value); 1564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 1566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("ERROR: unhandled class type '%s'\n", field->field.signature); 1567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 1568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 15730970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Copy the value of a static field into the output buffer, preceded 15740970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * by an appropriate tag. The tag is based on the value held by the 15750970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * field, not the field's type. 1576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 15770970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenvoid dvmDbgGetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId, 15780970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden ExpandBuf* pReply) 1579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* sfield = (StaticField*) fieldIdToField(refTypeId, fieldId); 15810970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden u1 tag = basicTagFromDescriptor(sfield->field.signature); 15820970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden 15830970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden if (tag == JT_ARRAY || tag == JT_OBJECT) { 15840970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden Object* objVal = dvmGetStaticFieldObject(sfield); 15850970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden tag = tagFromObject(objVal); 15860970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd1(pReply, tag); 15870970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAddObjectId(pReply, objectToObjectId(objVal)); 15880970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden LOGV(" --> sfieldId %x --> tag '%c' %p\n", fieldId, tag, objVal); 15890970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden } else { 15900970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden JValue value; 1591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 15920970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden LOGV(" --> sfieldId %x --> tag '%c'\n", fieldId, tag); 15930970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd1(pReply, tag); 15940970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden 15950970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden switch (tag) { 15960970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_BOOLEAN: 15970970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd1(pReply, dvmGetStaticFieldBoolean(sfield)); 15980970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 15990970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_BYTE: 16000970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd1(pReply, dvmGetStaticFieldByte(sfield)); 16010970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 16020970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_SHORT: 16030970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd2BE(pReply, dvmGetStaticFieldShort(sfield)); 16040970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 16050970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_CHAR: 16060970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd2BE(pReply, dvmGetStaticFieldChar(sfield)); 16070970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 16080970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_INT: 16090970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd4BE(pReply, dvmGetStaticFieldInt(sfield)); 16100970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 16110970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_FLOAT: 16120970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden value.f = dvmGetStaticFieldFloat(sfield); 16130970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd4BE(pReply, value.i); 16140970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 16150970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_LONG: 16160970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd8BE(pReply, dvmGetStaticFieldLong(sfield)); 16170970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 16180970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden case JT_DOUBLE: 16190970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden value.d = dvmGetStaticFieldDouble(sfield); 16200970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden expandBufAdd8BE(pReply, value.j); 16210970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 16220970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden default: 16230970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden LOGE("ERROR: unhandled field type '%s'\n", sfield->field.signature); 16240970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden assert(false); 16250970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden break; 16260970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden } 1627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the value of a static field. 1632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId, 1634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u8 rawValue, int width) 1635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* sfield = (StaticField*) fieldIdToField(refTypeId, fieldId); 1637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* objVal; 1638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JValue value; 1639de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project value.j = rawValue; 1641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (sfield->field.signature[0]) { 1643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_BOOLEAN: 1644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 1); 1645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetStaticFieldBoolean(sfield, value.z); 1646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_BYTE: 1648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 1); 1649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetStaticFieldByte(sfield, value.b); 1650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_SHORT: 1652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 2); 1653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetStaticFieldShort(sfield, value.s); 1654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_CHAR: 1656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 2); 1657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetStaticFieldChar(sfield, value.c); 1658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_INT: 1660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 4); 1661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetStaticFieldInt(sfield, value.i); 1662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_FLOAT: 1664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 4); 1665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetStaticFieldFloat(sfield, value.f); 1666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_ARRAY: 1668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_OBJECT: 1669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == sizeof(ObjectId)); 1670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objVal = objectIdToObject(rawValue); 1671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetStaticFieldObject(sfield, objVal); 1672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_LONG: 1674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 8); 1675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetStaticFieldLong(sfield, value.j); 1676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_DOUBLE: 1678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 8); 1679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetStaticFieldDouble(sfield, value.d); 1680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 1682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("ERROR: unhandled class type '%s'\n", sfield->field.signature); 1683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 1684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert a string object to a UTF-8 string. 1690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string. 1692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDbgStringToUtf8(ObjectId strId) 1694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringObject* strObj = (StringObject*) objectIdToObject(strId); 1696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dvmCreateCstrFromString(strObj); 1698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Thread and ThreadGroup 1704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert a thread object to a Thread ptr. 1709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This currently requires running through the list of threads and finding 1711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a match. 1712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * IMPORTANT: grab gDvm.threadListLock before calling here. 1714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Thread* threadObjToThread(Object* threadObj) 1716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* thread; 1718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (thread = gDvm.threadList; thread != NULL; thread = thread->next) { 1720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thread->threadObj == threadObj) 1721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return thread; 1725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the status and suspend state of a thread. 1729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgGetThreadStatus(ObjectId threadId, u4* pThreadStatus, 1731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4* pSuspendStatus) 1732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* threadObj; 1734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* thread; 1735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool result = false; 1736de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project threadObj = objectIdToObject(threadId); 1738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(threadObj != NULL); 1739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* lock the thread list, so the thread doesn't vanish while we work */ 1741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockThreadList(NULL); 1742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thread = threadObjToThread(threadObj); 1744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thread == NULL) 1745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (thread->status) { 1748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case THREAD_ZOMBIE: *pThreadStatus = TS_ZOMBIE; break; 1749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case THREAD_RUNNING: *pThreadStatus = TS_RUNNING; break; 1750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case THREAD_TIMED_WAIT: *pThreadStatus = TS_SLEEPING; break; 1751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case THREAD_MONITOR: *pThreadStatus = TS_MONITOR; break; 1752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case THREAD_WAIT: *pThreadStatus = TS_WAIT; break; 1753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case THREAD_INITIALIZING: *pThreadStatus = TS_ZOMBIE; break; 1754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case THREAD_STARTING: *pThreadStatus = TS_ZOMBIE; break; 1755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case THREAD_NATIVE: *pThreadStatus = TS_RUNNING; break; 1756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case THREAD_VMWAIT: *pThreadStatus = TS_WAIT; break; 1757b5f3c0b8222efea953adb94b97a2c70ba58e26e3Andy McFadden case THREAD_SUSPENDED: *pThreadStatus = TS_RUNNING; break; 1758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 1759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 1760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pThreadStatus = THREAD_ZOMBIE; 1761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsSuspended(thread)) 1765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pSuspendStatus = SUSPEND_STATUS_SUSPENDED; 1766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 1767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pSuspendStatus = 0; 1768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = true; 1770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 1772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockThreadList(); 1773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 1774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the thread's suspend count. 1778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu4 dvmDbgGetThreadSuspendCount(ObjectId threadId) 1780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* threadObj; 1782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* thread; 1783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 result = 0; 1784de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project threadObj = objectIdToObject(threadId); 1786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(threadObj != NULL); 1787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* lock the thread list, so the thread doesn't vanish while we work */ 1789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockThreadList(NULL); 1790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thread = threadObjToThread(threadObj); 1792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thread == NULL) 1793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17959a3147c7412f4794434b4c2604aa2ba784867774buzbee result = thread->interpBreak.ctl.suspendCount; 1796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 1798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockThreadList(); 1799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 1800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether or not a thread exists in the VM's thread list. 1804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if the thread exists. 1806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgThreadExists(ObjectId threadId) 1808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* threadObj; 1810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* thread; 1811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool result; 1812de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project threadObj = objectIdToObject(threadId); 1814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(threadObj != NULL); 1815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* lock the thread list, so the thread doesn't vanish while we work */ 1817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockThreadList(NULL); 1818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thread = threadObjToThread(threadObj); 1820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thread == NULL) 1821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = false; 1822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 1823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = true; 1824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockThreadList(); 1826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 1827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether or not a thread is suspended. 1831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "false" if the thread is running or doesn't exist. 1833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgIsSuspended(ObjectId threadId) 1835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* threadObj; 1837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* thread; 1838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool result = false; 1839de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project threadObj = objectIdToObject(threadId); 1841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(threadObj != NULL); 1842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* lock the thread list, so the thread doesn't vanish while we work */ 1844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockThreadList(NULL); 1845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thread = threadObjToThread(threadObj); 1847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thread == NULL) 1848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = dvmIsSuspended(thread); 1851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 1853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockThreadList(); 1854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 1855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the ObjectId for the "system" thread group. 1859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 18601e1433e78f560a01744e870c19c162ab88df9dc1Carl ShapiroObjectId dvmDbgGetSystemThreadGroupId() 1861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* groupObj = dvmGetSystemThreadGroup(); 1863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return objectToObjectId(groupObj); 1864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 186786c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden * Return the ObjectId for the "main" thread group. 1868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 18691e1433e78f560a01744e870c19c162ab88df9dc1Carl ShapiroObjectId dvmDbgGetMainThreadGroupId() 1870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* groupObj = dvmGetMainThreadGroup(); 1872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return objectToObjectId(groupObj); 1873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the name of a thread. 1877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string. 1879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDbgGetThreadName(ObjectId threadId) 1881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* threadObj; 1883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringObject* nameStr; 1884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* str; 1885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* result; 1886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project threadObj = objectIdToObject(threadId); 1888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(threadObj != NULL); 1889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nameStr = (StringObject*) dvmGetFieldObject(threadObj, 1891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.offJavaLangThread_name); 1892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project str = dvmCreateCstrFromString(nameStr); 1893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = (char*) malloc(strlen(str) + 20); 1894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* lock the thread list, so the thread doesn't vanish while we work */ 1896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockThreadList(NULL); 1897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* thread = threadObjToThread(threadObj); 1898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thread != NULL) 1899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(result, "<%d> %s", thread->threadId, str); 1900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 1901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(result, "%s", str); 1902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockThreadList(); 1903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(str); 1905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 1906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get a thread's group. 1910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectId dvmDbgGetThreadGroup(ObjectId threadId) 1912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* threadObj; 1914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* group; 1915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project threadObj = objectIdToObject(threadId); 1917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(threadObj != NULL); 1918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project group = dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_group); 1920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return objectToObjectId(group); 1921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the name of a thread group. 1926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string. 1928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDbgGetThreadGroupName(ObjectId threadGroupId) 1930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* threadGroup; 1932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringObject* nameStr; 1933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project threadGroup = objectIdToObject(threadGroupId); 1935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(threadGroup != NULL); 1936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 193786c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden nameStr = (StringObject*) 193886c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden dvmGetFieldObject(threadGroup, gDvm.offJavaLangThreadGroup_name); 1939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dvmCreateCstrFromString(nameStr); 1940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the parent of a thread group. 1944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string. 1946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectId dvmDbgGetThreadGroupParent(ObjectId threadGroupId) 1948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* threadGroup; 1950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* parent; 1951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project threadGroup = objectIdToObject(threadGroupId); 1953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(threadGroup != NULL); 1954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 195586c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden parent = dvmGetFieldObject(threadGroup, gDvm.offJavaLangThreadGroup_parent); 1956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return objectToObjectId(parent); 1957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the list of threads in the thread group. 1961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We do this by running through the full list of threads and returning 1963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the ones that have the ThreadGroup object as their owner. 1964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If threadGroupId is set to "kAllThreads", we ignore the group field and 1966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return all threads. 1967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The caller must free "*ppThreadIds". 1969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetThreadGroupThreads(ObjectId threadGroupId, 1971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ObjectId** ppThreadIds, u4* pThreadCount) 1972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* targetThreadGroup = NULL; 1974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* thread; 1975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count; 1976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (threadGroupId != THREAD_GROUP_ALL) { 1978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targetThreadGroup = objectIdToObject(threadGroupId); 1979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(targetThreadGroup != NULL); 1980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockThreadList(NULL); 1983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thread = gDvm.threadList; 1985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count = 0; 1986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (thread = gDvm.threadList; thread != NULL; thread = thread->next) { 1987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* group; 1988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Skip over the JDWP support thread. Some debuggers 1990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * get bent out of shape when they can't suspend and 1991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * query all threads, so it's easier if we just don't 1992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * tell them about us. 1993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) 1995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 1996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* This thread is currently being created, and isn't ready 1998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to be seen by the debugger yet. 1999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thread->threadObj == NULL) 2001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 2002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 200386c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden group = dvmGetFieldObject(thread->threadObj, 200486c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden gDvm.offJavaLangThread_group); 2005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (threadGroupId == THREAD_GROUP_ALL || group == targetThreadGroup) 2006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count++; 2007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pThreadCount = count; 2010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count == 0) { 2012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *ppThreadIds = NULL; 2013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ObjectId* ptr; 2015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr = *ppThreadIds = (ObjectId*) malloc(sizeof(ObjectId) * count); 2016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (thread = gDvm.threadList; thread != NULL; thread = thread->next) { 2018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* group; 2019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Skip over the JDWP support thread. Some debuggers 2021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * get bent out of shape when they can't suspend and 2022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * query all threads, so it's easier if we just don't 2023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * tell them about us. 2024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) 2026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 2027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* This thread is currently being created, and isn't ready 2029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to be seen by the debugger yet. 2030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thread->threadObj == NULL) 2032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 2033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 203486c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden group = dvmGetFieldObject(thread->threadObj, 203586c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden gDvm.offJavaLangThread_group); 2036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (threadGroupId == THREAD_GROUP_ALL || group == targetThreadGroup) 2037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 2038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *ptr++ = objectToObjectId(thread->threadObj); 2039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count--; 2040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(count == 0); 2044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockThreadList(); 2047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get all threads. 2051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The caller must free "*ppThreadIds". 2053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetAllThreads(ObjectId** ppThreadIds, u4* pThreadCount) 2055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgGetThreadGroupThreads(THREAD_GROUP_ALL, ppThreadIds, pThreadCount); 2057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count up the #of frames on the thread's stack. 2062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 206386c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden * Returns -1 on failure. 2064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgGetThreadFrameCount(ObjectId threadId) 2066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* threadObj; 2068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* thread; 206986c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden int count = -1; 2070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project threadObj = objectIdToObject(threadId); 2072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockThreadList(NULL); 2074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thread = threadObjToThread(threadObj); 207586c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden if (thread != NULL) { 207686c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden count = dvmComputeExactFrameDepth(thread->curFrame); 2077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockThreadList(); 207986c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden 2080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return count; 2081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get info for frame N from the specified thread's stack. 2085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgGetThreadFrame(ObjectId threadId, int num, FrameId* pFrameId, 2087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpLocation* pLoc) 2088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* threadObj; 2090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* thread; 2091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* framePtr; 2092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count; 2093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project threadObj = objectIdToObject(threadId); 2095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockThreadList(NULL); 2097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thread = threadObjToThread(threadObj); 2099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thread == NULL) 2100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project framePtr = thread->curFrame; 2103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count = 0; 2104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (framePtr != NULL) { 2105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const StackSaveArea* saveArea = SAVEAREA_FROM_FP(framePtr); 2106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const Method* method = saveArea->method; 2107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2108fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro if (!dvmIsBreakFrame((u4*)framePtr)) { 2109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count == num) { 2110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pFrameId = frameToFrameId(framePtr); 2111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsInterfaceClass(method->clazz)) 2112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pLoc->typeTag = TT_INTERFACE; 2113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pLoc->typeTag = TT_CLASS; 2115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pLoc->classId = classObjectToRefTypeId(method->clazz); 2116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pLoc->methodId = methodToMethodId(method); 2117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsNativeMethod(method)) 2118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pLoc->idx = (u8)-1; 2119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pLoc->idx = saveArea->xtra.currentPc - method->insns; 2121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockThreadList(); 2122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 2123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count++; 2126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project framePtr = saveArea->prevFrame; 2129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 2132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockThreadList(); 2133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 2134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the ThreadId for the current thread. 2138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 21391e1433e78f560a01744e870c19c162ab88df9dc1Carl ShapiroObjectId dvmDbgGetThreadSelfId() 2140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* self = dvmThreadSelf(); 2142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return objectToObjectId(self->threadObj); 2143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Suspend the VM. 2147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSuspendVM(bool isEvent) 2149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSuspendAllThreads(isEvent ? SUSPEND_FOR_DEBUG_EVENT : SUSPEND_FOR_DEBUG); 2151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Resume the VM. 2155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgResumeVM() 2157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmResumeAllThreads(SUSPEND_FOR_DEBUG); 2159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Suspend one thread (not ourselves). 2163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSuspendThread(ObjectId threadId) 2165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* threadObj = objectIdToObject(threadId); 2167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* thread; 2168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockThreadList(NULL); 2170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thread = threadObjToThread(threadObj); 2172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thread == NULL) { 2173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* can happen if our ThreadDeath notify crosses in the mail */ 2174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("WARNING: threadid=%llx obj=%p no match\n", threadId, threadObj); 2175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSuspendThread(thread); 2177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockThreadList(); 2180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Resume one thread (not ourselves). 2184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgResumeThread(ObjectId threadId) 2186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* threadObj = objectIdToObject(threadId); 2188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* thread; 2189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockThreadList(NULL); 2191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thread = threadObjToThread(threadObj); 2193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thread == NULL) { 2194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("WARNING: threadid=%llx obj=%p no match\n", threadId, threadObj); 2195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmResumeThread(thread); 2197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockThreadList(); 2200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Suspend ourselves after sending an event to the debugger. 2204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 22051e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirovoid dvmDbgSuspendSelf() 2206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSuspendSelf(true); 2208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the "this" object for the specified frame. 2212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Object* getThisObject(const u4* framePtr) 2214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const StackSaveArea* saveArea = SAVEAREA_FROM_FP(framePtr); 2216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const Method* method = saveArea->method; 2217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int argOffset = method->registersSize - method->insSize; 2218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* thisObj; 2219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method == NULL) { 2221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* this is a "break" frame? */ 2222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 2223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 2224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV(" Pulling this object for frame at %p\n", framePtr); 2227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV(" Method='%s' native=%d static=%d this=%p\n", 2228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->name, dvmIsNativeMethod(method), 2229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmIsStaticMethod(method), (Object*) framePtr[argOffset]); 2230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * No "this" pointer for statics. No args on the interp stack for 2233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * native methods invoked directly from the VM. 2234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsNativeMethod(method) || dvmIsStaticMethod(method)) 2236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisObj = NULL; 2237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisObj = (Object*) framePtr[argOffset]; 2239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thisObj != NULL && !dvmIsValidObject(thisObj)) { 2241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Debugger: invalid 'this' pointer %p in %s.%s; returning NULL\n", 2242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project framePtr, method->clazz->descriptor, method->name); 2243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisObj = NULL; 2244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return thisObj; 2247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the "this" object for the specified frame. The thread must be 2251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * suspended. 2252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgGetThisObject(ObjectId threadId, FrameId frameId, ObjectId* pThisId) 2254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u4* framePtr = frameIdToFrame(frameId); 2256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* thisObj; 2257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UNUSED_PARAMETER(threadId); 2259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisObj = getThisObject(framePtr); 2261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pThisId = objectToObjectId(thisObj); 2263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 2264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy the value of a method argument or local variable into the 2268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * specified buffer. The value will be preceeded with the tag. 226986c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden * 227086c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden * The debugger includes the tags in the request. Object tags may 227186c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden * be updated with a more refined type. 2272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetLocalValue(ObjectId threadId, FrameId frameId, int slot, 2274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 tag, u1* buf, int expectedLen) 2275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u4* framePtr = frameIdToFrame(frameId); 2277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* objVal; 2278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 intVal; 2279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u8 longVal; 2280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UNUSED_PARAMETER(threadId); 2282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project slot = untweakSlot(slot, framePtr); // Eclipse workaround 2284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (tag) { 2286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_BOOLEAN: 2287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(expectedLen == 1); 2288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project intVal = framePtr[slot]; 2289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set1(buf+1, intVal != 0); 2290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_BYTE: 2292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(expectedLen == 1); 2293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project intVal = framePtr[slot]; 2294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set1(buf+1, intVal); 2295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_SHORT: 2297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_CHAR: 2298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(expectedLen == 2); 2299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project intVal = framePtr[slot]; 2300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set2BE(buf+1, intVal); 2301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_INT: 2303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_FLOAT: 2304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(expectedLen == 4); 2305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project intVal = framePtr[slot]; 2306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(buf+1, intVal); 2307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_ARRAY: 230986c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden assert(expectedLen == sizeof(ObjectId)); 2310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 2311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* convert to "ObjectId" */ 2312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objVal = (Object*)framePtr[slot]; 2313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (objVal != NULL && !dvmIsValidObject(objVal)) { 2314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("JDWP: slot %d expected to hold array, %p invalid\n", 2315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project slot, objVal); 2316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); // DEBUG: make it obvious 2317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objVal = NULL; 2318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tag = JT_OBJECT; // JT_ARRAY not expected for NULL ref 2319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetObjectId(buf+1, objectToObjectId(objVal)); 2321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_OBJECT: 232486c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden assert(expectedLen == sizeof(ObjectId)); 2325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 2326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* convert to "ObjectId" */ 2327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objVal = (Object*)framePtr[slot]; 23280970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden 23290970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden if (objVal != NULL && !dvmIsValidObject(objVal)) { 23300970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden LOGW("JDWP: slot %d expected to hold object, %p invalid\n", 23310970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden slot, objVal); 23320970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden dvmAbort(); // DEBUG: make it obvious 23330970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden objVal = NULL; 2334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 23350970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden tag = tagFromObject(objVal); 2336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetObjectId(buf+1, objectToObjectId(objVal)); 2337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_DOUBLE: 2340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_LONG: 2341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(expectedLen == 8); 234286c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden memcpy(&longVal, &framePtr[slot], 8); 2343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set8BE(buf+1, longVal); 2344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 2346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("ERROR: unhandled tag '%c'\n", tag); 2347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 2348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 235186c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden /* prepend tag, which may have been updated */ 2352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set1(buf, tag); 2353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy a new value into an argument or local variable. 2357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSetLocalValue(ObjectId threadId, FrameId frameId, int slot, u1 tag, 2359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u8 value, int width) 2360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4* framePtr = frameIdToFrame(frameId); 2362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UNUSED_PARAMETER(threadId); 2364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project slot = untweakSlot(slot, framePtr); // Eclipse workaround 2366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (tag) { 2368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_BOOLEAN: 2369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 1); 2370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project framePtr[slot] = (u4)value; 2371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_BYTE: 2373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 1); 2374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project framePtr[slot] = (u4)value; 2375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_SHORT: 2377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_CHAR: 2378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 2); 2379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project framePtr[slot] = (u4)value; 2380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_INT: 2382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_FLOAT: 2383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 4); 2384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project framePtr[slot] = (u4)value; 2385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_STRING: 2387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* The debugger calls VirtualMachine.CreateString to create a new 2388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * string, then uses this to set the object reference, when you 2389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * edit a String object */ 2390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_ARRAY: 2391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_OBJECT: 2392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == sizeof(ObjectId)); 2393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project framePtr[slot] = (u4) objectIdToObject(value); 2394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_DOUBLE: 2396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_LONG: 2397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(width == 8); 239886c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden memcpy(&framePtr[slot], &value, 8); 2399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_VOID: 2401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_CLASS_OBJECT: 2402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_THREAD: 2403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_THREAD_GROUP: 2404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case JT_CLASS_LOADER: 240586c95935211bcb07cc2cb9dc1a6d1069f80f727cAndy McFadden /* not expecting these from debugger; fall through to failure */ 2406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 2407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("ERROR: unhandled tag '%c'\n", tag); 2408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 2409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Debugger notification 2417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell JDWP that a breakpoint address has been reached. 2422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "pcOffset" will be -1 for native methods. 2424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "thisPtr" will be NULL for static methods. 2425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgPostLocationEvent(const Method* method, int pcOffset, 2427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* thisPtr, int eventFlags) 2428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpLocation loc; 2430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsInterfaceClass(method->clazz)) 2432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project loc.typeTag = TT_INTERFACE; 2433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project loc.typeTag = TT_CLASS; 2435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project loc.classId = classObjectToRefTypeId(method->clazz); 2436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project loc.methodId = methodToMethodId(method); 2437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project loc.idx = pcOffset; 2438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note we use "NoReg" so we don't keep track of references that are 2441c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * never actually sent to the debugger. The "thisPtr" is only used to 2442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * compare against registered events. 2443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmJdwpPostLocationEvent(gDvm.jdwpState, &loc, 2446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objectToObjectIdNoReg(thisPtr), eventFlags)) 2447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 2448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project classObjectToRefTypeId(method->clazz); 2449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objectToObjectId(thisPtr); 2450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell JDWP that an exception has occurred. 2455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgPostException(void* throwFp, int throwRelPc, void* catchFp, 2457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int catchRelPc, Object* exception) 2458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpLocation throwLoc, catchLoc; 2460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const Method* throwMeth; 2461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const Method* catchMeth; 2462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwMeth = SAVEAREA_FROM_FP(throwFp)->method; 2464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsInterfaceClass(throwMeth->clazz)) 2465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwLoc.typeTag = TT_INTERFACE; 2466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwLoc.typeTag = TT_CLASS; 2468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwLoc.classId = classObjectToRefTypeId(throwMeth->clazz); 2469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwLoc.methodId = methodToMethodId(throwMeth); 2470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwLoc.idx = throwRelPc; 2471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (catchRelPc < 0) { 2473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(&catchLoc, 0, sizeof(catchLoc)); 2474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catchMeth = SAVEAREA_FROM_FP(catchFp)->method; 2476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsInterfaceClass(catchMeth->clazz)) 2477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catchLoc.typeTag = TT_INTERFACE; 2478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catchLoc.typeTag = TT_CLASS; 2480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catchLoc.classId = classObjectToRefTypeId(catchMeth->clazz); 2481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catchLoc.methodId = methodToMethodId(catchMeth); 2482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catchLoc.idx = catchRelPc; 2483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* need this for InstanceOnly filters */ 2486fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro Object* thisObj = getThisObject((u4*)throwFp); 2487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2488c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden /* 2489c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * Hand the event to the JDWP exception handler. Note we're using the 2490c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * "NoReg" objectID on the exception, which is not strictly correct -- 2491c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * the exception object WILL be passed up to the debugger if the 2492c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * debugger is interested in the event. We do this because the current 2493c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * implementation of the debugger object registry never throws anything 2494c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * away, and some people were experiencing a fatal build up of exception 2495c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * objects when dealing with certain libraries. 2496c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden */ 2497c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden dvmJdwpPostException(gDvm.jdwpState, &throwLoc, 2498c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden objectToObjectIdNoReg(exception), 2499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project classObjectToRefTypeId(exception->clazz), &catchLoc, 2500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objectToObjectId(thisObj)); 2501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell JDWP and/or DDMS that a thread has started. 2505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgPostThreadStart(Thread* thread) 2507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 25089a3147c7412f4794434b4c2604aa2ba784867774buzbee if (gDvm.debuggerActive) { 2509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpPostThreadChange(gDvm.jdwpState, 2510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objectToObjectId(thread->threadObj), true); 2511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.ddmThreadNotification) 2513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDdmSendThreadNotification(thread, true); 2514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell JDWP and/or DDMS that a thread has gone away. 2518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgPostThreadDeath(Thread* thread) 2520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 25219a3147c7412f4794434b4c2604aa2ba784867774buzbee if (gDvm.debuggerActive) { 2522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpPostThreadChange(gDvm.jdwpState, 2523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project objectToObjectId(thread->threadObj), false); 2524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.ddmThreadNotification) 2526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDdmSendThreadNotification(thread, false); 2527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell JDWP that a new class has been prepared. 2531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgPostClassPrepare(ClassObject* clazz) 2533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 25340970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden const char* signature; 2535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int tag; 2536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsInterfaceClass(clazz)) 2538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tag = TT_INTERFACE; 2539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tag = TT_CLASS; 2541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // TODO - we currently always send both "verified" and "prepared" since 2543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // debuggers seem to like that. There might be some advantage to honesty, 2544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // since the class may not yet be verified. 25450970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden signature = jniSignature(clazz); 2546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpPostClassPrepare(gDvm.jdwpState, tag, classObjectToRefTypeId(clazz), 2547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature, CS_VERIFIED | CS_PREPARED); 2548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The JDWP event mechanism has registered an event with a LocationOnly 2552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * mod. Tell the interpreter to call us if we hit the specified 2553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * address. 2554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgWatchLocation(const JdwpLocation* pLoc) 2556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* method = methodIdToMethod(pLoc->classId, pLoc->methodId); 2558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!dvmIsNativeMethod(method)); 2559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAddBreakAddr(method, pLoc->idx); 2560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; /* assume success */ 2561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * An event with a LocationOnly mod has been removed. 2565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgUnwatchLocation(const JdwpLocation* pLoc) 2567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* method = methodIdToMethod(pLoc->classId, pLoc->methodId); 2569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!dvmIsNativeMethod(method)); 2570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmClearBreakAddr(method, pLoc->idx); 2571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The JDWP event mechanism has registered a single-step event. Tell 2575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the interpreter about it. 2576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgConfigureStep(ObjectId threadId, enum JdwpStepSize size, 2578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project enum JdwpStepDepth depth) 2579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* threadObj; 2581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* thread; 2582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool result = false; 2583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project threadObj = objectIdToObject(threadId); 2585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(threadObj != NULL); 2586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get a pointer to the Thread struct for this ID. The pointer will 2589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * be used strictly for comparisons against the current thread pointer 2590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * after the setup is complete, so we can safely release the lock. 2591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockThreadList(NULL); 2593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thread = threadObjToThread(threadObj); 2594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thread == NULL) { 2596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Thread for single-step not found\n"); 2597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsSuspended(thread)) { 2600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Thread for single-step not suspended\n"); 2601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!"non-susp step"); // I want to know if this can happen 2602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmIsSuspended(thread)); 2606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmAddSingleStep(thread, size, depth)) 2607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = true; 2610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 2612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockThreadList(); 2613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 2614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A single-step event has been removed. 2618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgUnconfigureStep(ObjectId threadId) 2620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UNUSED_PARAMETER(threadId); 2622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* right now it's global, so don't need to find Thread */ 2624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmClearSingleStep(NULL); 2625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Invoke a method in a thread that has been stopped on a breakpoint or 2629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * other debugger event. (This function is called from the JDWP thread.) 2630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note that access control is not enforced, per spec. 2632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectJdwpError dvmDbgInvokeMethod(ObjectId threadId, ObjectId objectId, 2634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RefTypeId classId, MethodId methodId, u4 numArgs, ObjectId* argArray, 2635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 options, u1* pResultTag, u8* pResultValue, ObjectId* pExceptObj) 2636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* threadObj = objectIdToObject(threadId); 2638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockThreadList(NULL); 2640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2641d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro Thread* targetThread = threadObjToThread(threadObj); 2642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (targetThread == NULL) { 2643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockThreadList(); 2644d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro return ERR_INVALID_THREAD; /* thread does not exist */ 2645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!targetThread->invokeReq.ready) { 2647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockThreadList(); 2648d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro return ERR_INVALID_THREAD; /* thread not stopped by event */ 2649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 26520d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden * We currently have a bug where we don't successfully resume the 26530d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden * target thread if the suspend count is too deep. We're expected to 26540d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden * require one "resume" for each "suspend", but when asked to execute 26550d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden * a method we have to resume fully and then re-suspend it back to the 26560d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden * same level. (The easiest way to cause this is to type "suspend" 26570d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden * multiple times in jdb.) 26580d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden * 26590d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden * It's unclear what this means when the event specifies "resume all" 26600d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden * and some threads are suspended more deeply than others. This is 26610d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden * a rare problem, so for now we just prevent it from hanging forever 26620d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden * by rejecting the method invocation request. Without this, we will 26630d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden * be stuck waiting on a suspended thread. 26640d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden */ 26659a3147c7412f4794434b4c2604aa2ba784867774buzbee if (targetThread->interpBreak.ctl.suspendCount > 1) { 26660d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden LOGW("threadid=%d: suspend count on threadid=%d is %d, too deep " 26670d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden "for method exec\n", 26680d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden dvmThreadSelf()->threadId, targetThread->threadId, 26699a3147c7412f4794434b4c2604aa2ba784867774buzbee targetThread->interpBreak.ctl.suspendCount); 26700d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden dvmUnlockThreadList(); 2671d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro return ERR_THREAD_SUSPENDED; /* probably not expected here */ 26720d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden } 26730d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden 26740d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden /* 2675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: ought to screen the various IDs, and verify that the argument 2676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * list is valid. 2677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targetThread->invokeReq.obj = objectIdToObject(objectId); 2680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targetThread->invokeReq.thread = threadObj; 2681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targetThread->invokeReq.clazz = refTypeIdToClassObject(classId); 2682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targetThread->invokeReq.method = methodIdToMethod(classId, methodId); 2683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targetThread->invokeReq.numArgs = numArgs; 2684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targetThread->invokeReq.argArray = argArray; 2685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targetThread->invokeReq.options = options; 2686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targetThread->invokeReq.invokeNeeded = true; 2687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is a bit risky -- if the thread goes away we're sitting high 2690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and dry -- but we must release this before the dvmResumeAllThreads 2691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * call, and it's unwise to hold it during dvmWaitForSuspend. 2692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockThreadList(); 2694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 269699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * We change our (JDWP thread) status, which should be THREAD_RUNNING, 269799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * so the VM can suspend for a GC if the invoke request causes us to 269899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * run out of memory. It's also a good idea to change it before locking 269999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * the invokeReq mutex, although that should never be held for long. 2700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* self = dvmThreadSelf(); 2702d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro ThreadStatus oldStatus = dvmChangeStatus(self, THREAD_VMWAIT); 2703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV(" Transferring control to event thread\n"); 2705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockMutex(&targetThread->invokeReq.lock); 2706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((options & INVOKE_SINGLE_THREADED) == 0) { 2708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV(" Resuming all threads\n"); 2709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmResumeAllThreads(SUSPEND_FOR_DEBUG_EVENT); 2710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV(" Resuming event thread only\n"); 2712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmResumeThread(targetThread); 2713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Wait for the request to finish executing. 2717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (targetThread->invokeReq.invokeNeeded) { 2719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pthread_cond_wait(&targetThread->invokeReq.cv, 2720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &targetThread->invokeReq.lock); 2721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockMutex(&targetThread->invokeReq.lock); 2723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV(" Control has returned from event thread\n"); 2724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* wait for thread to re-suspend itself */ 2726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmWaitForSuspend(targetThread); 2727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Done waiting, switch back to RUNNING. 2730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmChangeStatus(self, oldStatus); 2732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Suspend the threads. We waited for the target thread to suspend 2735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * itself, so all we need to do is suspend the others. 2736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The suspendAllThreads() call will double-suspend the event thread, 2738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * so we want to resume the target thread once to keep the books straight. 2739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((options & INVOKE_SINGLE_THREADED) == 0) { 2741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV(" Suspending all threads\n"); 2742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSuspendAllThreads(SUSPEND_FOR_DEBUG_EVENT); 2743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV(" Resuming event thread to balance the count\n"); 2744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmResumeThread(targetThread); 2745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set up the result. 2749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pResultTag = targetThread->invokeReq.resultTag; 2751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isTagPrimitive(targetThread->invokeReq.resultTag)) 2752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pResultValue = targetThread->invokeReq.resultValue.j; 2753fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro else { 2754fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro Object* tmpObj = (Object*)targetThread->invokeReq.resultValue.l; 2755fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro *pResultValue = objectToObjectId(tmpObj); 2756fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro } 2757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pExceptObj = targetThread->invokeReq.exceptObj; 2758d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro return targetThread->invokeReq.err; 2759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 27620970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Return a basic tag value for the return type. 2763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 27640970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenstatic u1 getReturnTypeBasicTag(const Method* method) 2765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* descriptor = dexProtoGetReturnType(&method->prototype); 27670970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return basicTagFromDescriptor(descriptor); 2768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Execute the method described by "*pReq". 277299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 277399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * We're currently in VMWAIT, because we're stopped on a breakpoint. We 277499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * want to switch to RUNNING while we execute. 2775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgExecuteMethod(DebugInvokeReq* pReq) 2777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* self = dvmThreadSelf(); 2779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const Method* meth; 2780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* oldExcept; 2781d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro ThreadStatus oldStatus; 2782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can be called while an exception is pending in the VM. We need 2785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to preserve that across the method invocation. 2786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project oldExcept = dvmGetException(self); 27887dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden if (oldExcept != NULL) { 27897dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden dvmAddTrackedAlloc(oldExcept, self); 27907dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden dvmClearException(self); 27917dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden } 279299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 279399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project oldStatus = dvmChangeStatus(self, THREAD_RUNNING); 2794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Translate the method through the vtable, unless we're calling a 2797f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden * direct method or the debugger wants to suppress it. 2798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2799f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden if ((pReq->options & INVOKE_NONVIRTUAL) != 0 || pReq->obj == NULL || 2800f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden dvmIsDirectMethod(pReq->method)) 2801f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden { 2802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth = pReq->method; 2803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth = dvmGetVirtualizedMethod(pReq->clazz, pReq->method); 2805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(meth != NULL); 2807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(sizeof(jvalue) == sizeof(u8)); 2809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IF_LOGV() { 2811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&meth->prototype); 2812f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden LOGV("JDWP invoking method %p/%p %s.%s:%s\n", 2813f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden pReq->method, meth, meth->clazz->descriptor, meth->name, desc); 2814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 2815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2817d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden dvmCallMethodA(self, meth, pReq->obj, false, &pReq->resultValue, 2818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (jvalue*)pReq->argArray); 2819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pReq->exceptObj = objectToObjectId(dvmGetException(self)); 28200970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden pReq->resultTag = getReturnTypeBasicTag(meth); 2821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pReq->exceptObj != 0) { 2822f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden Object* exc = dvmGetException(self); 2823f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden LOGD(" JDWP invocation returning with exceptObj=%p (%s)\n", 2824f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden exc, exc->clazz->descriptor); 2825f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden //dvmLogExceptionStackTrace(); 2826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmClearException(self); 2827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Nothing should try to use this, but it looks like something is. 2829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Make it null to be safe. 2830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pReq->resultValue.j = 0; /*0xadadadad;*/ 2832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (pReq->resultTag == JT_OBJECT) { 2833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* if no exception thrown, examine object result more closely */ 28340970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden u1 newTag = tagFromObject((Object*)pReq->resultValue.l); 2835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newTag != pReq->resultTag) { 2836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV(" JDWP promoted result from %d to %d\n", 2837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pReq->resultTag, newTag); 2838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pReq->resultTag = newTag; 2839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 28407dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden 28417dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden /* 28427dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden * Register the object. We don't actually need an ObjectId yet, 28437dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden * but we do need to be sure that the GC won't move or discard the 28447dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden * object when we switch out of RUNNING. The ObjectId conversion 28457dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden * will add the object to the "do not touch" list. 28467dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden * 28477dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden * We can't use the "tracked allocation" mechanism here because 28487dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden * the object is going to be handed off to a different thread. 28497dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden */ 28501e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapiro objectToObjectId((Object*)pReq->resultValue.l); 2851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 28537dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden if (oldExcept != NULL) { 2854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetException(self, oldExcept); 28557dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden dvmReleaseTrackedAlloc(oldExcept, self); 28567dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden } 285799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project dvmChangeStatus(self, oldStatus); 2858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// for dvmAddressSetForLine 2861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct AddressSetContext { 2862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool lastAddressValid; 2863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 lastAddress; 2864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 lineNum; 2865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AddressSet *pSet; 2866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} AddressSetContext; 2867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// for dvmAddressSetForLine 2869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int addressSetCb (void *cnxt, u4 address, u4 lineNum) 2870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AddressSetContext *pContext = (AddressSetContext *)cnxt; 2872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (lineNum == pContext->lineNum) { 2874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!pContext->lastAddressValid) { 2875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Everything from this address until the next line change is ours 2876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pContext->lastAddress = address; 2877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pContext->lastAddressValid = true; 2878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // else, If we're already in a valid range for this lineNum, 2880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // just keep going (shouldn't really happen) 2881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (pContext->lastAddressValid) { // and the line number is new 2882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 i; 2883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Add everything from the last entry up until here to the set 2884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = pContext->lastAddress; i < address; i++) { 2885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAddressSetSet(pContext->pSet, i); 2886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pContext->lastAddressValid = false; 2889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // there may be multiple entries for a line 2892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 2893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Build up a set of bytecode addresses associated with a line number 2896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst AddressSet *dvmAddressSetForLine(const Method* method, int line) 2898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AddressSet *result; 2900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexFile *pDexFile = method->clazz->pDvmDex->pDexFile; 2901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 insnsSize = dvmGetMethodInsnsSize(method); 2902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AddressSetContext context; 2903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2904fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro result = (AddressSet*)calloc(1, sizeof(AddressSet) + (insnsSize/8) + 1); 2905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result->setSize = insnsSize; 2906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(&context, 0, sizeof(context)); 2908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project context.pSet = result; 2909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project context.lineNum = line; 2910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project context.lastAddressValid = false; 2911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexDecodeDebugInfo(pDexFile, dvmGetMethodCode(method), 2913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->clazz->descriptor, 2914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->prototype.protoIdx, 2915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->accessFlags, 2916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addressSetCb, NULL, &context); 2917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // If the line number was the last in the position table... 2919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (context.lastAddressValid) { 2920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 i; 2921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = context.lastAddress; i < insnsSize; i++) { 2922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAddressSetSet(result, i); 2923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 2927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Dalvik Debug Monitor support 2933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We have received a DDM packet over JDWP. Hand it off to the VM. 2938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgDdmHandlePacket(const u1* buf, int dataLen, u1** pReplyBuf, 2940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int* pReplyLen) 2941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dvmDdmHandlePacket(buf, dataLen, pReplyBuf, pReplyLen); 2943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * First DDM packet has arrived over JDWP. Notify the press. 2947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 29481e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirovoid dvmDbgDdmConnected() 2949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDdmConnected(); 2951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JDWP connection has dropped. 2955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 29561e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirovoid dvmDbgDdmDisconnected() 2957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDdmDisconnected(); 2959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Send up a JDWP event packet with a DDM chunk in it. 2963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 29640171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFaddenvoid dvmDbgDdmSendChunk(int type, size_t len, const u1* buf) 29650171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden{ 29660171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden assert(buf != NULL); 29670171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden struct iovec vec[1] = { {(void*)buf, len} }; 29680171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden dvmDbgDdmSendChunkV(type, vec, 1); 29690171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden} 29700171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden 29710171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden/* 29720171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden * Send up a JDWP event packet with a DDM chunk in it. The chunk is 29730171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden * concatenated from multiple source buffers. 29740171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden */ 29750171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFaddenvoid dvmDbgDdmSendChunkV(int type, const struct iovec* iov, int iovcnt) 2976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.jdwpState == NULL) { 2978a6ef944d938832ea2768e0b165d9cf325c0f65aeRobert CH Chou LOGV("Debugger thread not active, ignoring DDM send (t=0x%08x)\n", 2979a6ef944d938832ea2768e0b165d9cf325c0f65aeRobert CH Chou type); 2980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 29830171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden dvmJdwpDdmSendChunkV(gDvm.jdwpState, type, iov, iovcnt); 2984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2985