Debugger.h revision 6ff3c8fde9623dadad726dbd5e1658585c321751
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16/* 17 * Dalvik-specific side of debugger support. (The JDWP code is intended to 18 * be relatively generic.) 19 */ 20#ifndef _DALVIK_DEBUGGER 21#define _DALVIK_DEBUGGER 22 23#include "Common.h" 24#include "Misc.h" 25#include "jdwp/Jdwp.h" 26#include <pthread.h> 27 28/* fwd decl */ 29struct Object; 30struct ClassObject; 31struct Method; 32struct Thread; 33 34/* 35 * used by StepControl to track a set of addresses associated with 36 * a single line. 37 */ 38typedef struct AddressSet { 39 u4 setSize; 40 u1 set[1]; 41} AddressSet; 42 43INLINE void dvmAddressSetSet(AddressSet *pSet, u4 toSet) 44{ 45 if (toSet < pSet->setSize) { 46 pSet->set[toSet/8] |= 1 << (toSet % 8); 47 } 48} 49 50INLINE bool dvmAddressSetGet(const AddressSet *pSet, u4 toGet) 51{ 52 if (toGet < pSet->setSize) { 53 return (pSet->set[toGet/8] & (1 << (toGet % 8))) != 0; 54 } else { 55 return false; 56 } 57} 58 59/* 60 * Single-step management. 61 */ 62typedef struct StepControl { 63 /* request */ 64 enum JdwpStepSize size; 65 enum JdwpStepDepth depth; 66 struct Thread* thread; /* don't deref; for comparison only */ 67 68 /* current state */ 69 bool active; 70 const struct Method* method; 71 int line; /* line #; could be -1 */ 72 const AddressSet* pAddressSet; /* if non-null, address set for line */ 73 int frameDepth; 74} StepControl; 75 76/* 77 * Invoke-during-breakpoint support. 78 */ 79typedef struct DebugInvokeReq { 80 /* boolean; only set when we're in the tail end of an event handler */ 81 bool ready; 82 83 /* boolean; set if the JDWP thread wants this thread to do work */ 84 bool invokeNeeded; 85 86 /* request */ 87 struct Object* obj; /* not used for ClassType.InvokeMethod */ 88 struct Object* thread; 89 struct ClassObject* clazz; 90 struct Method* method; 91 u4 numArgs; 92 u8* argArray; /* will be NULL if numArgs==0 */ 93 u4 options; 94 95 /* result */ 96 JdwpError err; 97 u1 resultTag; 98 JValue resultValue; 99 ObjectId exceptObj; 100 101 /* condition variable to wait on while the method executes */ 102 pthread_mutex_t lock; 103 pthread_cond_t cv; 104} DebugInvokeReq; 105 106/* system init/shutdown */ 107bool dvmDebuggerStartup(void); 108void dvmDebuggerShutdown(void); 109 110void dvmDbgInitMutex(pthread_mutex_t* pMutex); 111void dvmDbgLockMutex(pthread_mutex_t* pMutex); 112void dvmDbgUnlockMutex(pthread_mutex_t* pMutex); 113void dvmDbgInitCond(pthread_cond_t* pCond); 114void dvmDbgCondWait(pthread_cond_t* pCond, pthread_mutex_t* pMutex); 115void dvmDbgCondSignal(pthread_cond_t* pCond); 116void dvmDbgCondBroadcast(pthread_cond_t* pCond); 117 118/* 119 * Return the DebugInvokeReq for the current thread. 120 */ 121DebugInvokeReq* dvmDbgGetInvokeReq(void); 122 123/* 124 * Enable/disable breakpoints and step modes. Used to provide a heads-up 125 * when the debugger attaches. 126 */ 127void dvmDbgConnected(void); 128void dvmDbgActive(void); 129void dvmDbgDisconnected(void); 130 131/* 132 * Returns "true" if a debugger is connected. Returns "false" if it's 133 * just DDM. 134 */ 135bool dvmDbgIsDebuggerConnected(void); 136 137/* 138 * Time, in milliseconds, since the last debugger activity. Does not 139 * include DDMS activity. Returns -1 if there has been no activity. 140 * Returns 0 if we're in the middle of handling a debugger request. 141 */ 142s8 dvmDbgLastDebuggerActivity(void); 143 144/* 145 * Block/allow GC depending on what we're doing. These return the old 146 * status, which can be fed to dvmDbgThreadGoing() to restore the previous 147 * mode. 148 */ 149int dvmDbgThreadRunning(void); 150int dvmDbgThreadWaiting(void); 151int dvmDbgThreadContinuing(int status); 152 153/* 154 * The debugger wants the VM to exit. 155 */ 156void dvmDbgExit(int status); 157 158/* 159 * Class, Object, Array 160 */ 161const char* dvmDbgGetClassDescriptor(RefTypeId id); 162ObjectId dvmDbgGetClassObject(RefTypeId id); 163RefTypeId dvmDbgGetSuperclass(RefTypeId id); 164ObjectId dvmDbgGetClassLoader(RefTypeId id); 165u4 dvmDbgGetAccessFlags(RefTypeId id); 166bool dvmDbgIsInterface(RefTypeId id); 167void dvmDbgGetClassList(u4* pNumClasses, RefTypeId** pClassRefBuf); 168void dvmDbgGetVisibleClassList(ObjectId classLoaderId, u4* pNumClasses, 169 RefTypeId** pClassRefBuf); 170void dvmDbgGetClassInfo(RefTypeId classId, u1* pTypeTag, u4* pStatus, 171 char** pSignature); 172bool dvmDbgFindLoadedClassBySignature(const char* classDescriptor, 173 RefTypeId* pRefTypeId); 174void dvmDbgGetObjectType(ObjectId objectId, u1* pRefTypeTag, 175 RefTypeId* pRefTypeId); 176u1 dvmDbgGetClassObjectType(RefTypeId refTypeId); 177char* dvmDbgGetSignature(RefTypeId refTypeId); 178const char* dvmDbgGetSourceFile(RefTypeId refTypeId); 179char* dvmDbgGetObjectTypeName(ObjectId objectId); 180int dvmDbgGetSignatureTag(const char* signature); 181int dvmDbgGetObjectTag(ObjectId objectId, const char* type); 182int dvmDbgGetTagWidth(int tag); 183 184int dvmDbgGetArrayLength(ObjectId arrayId); 185int dvmDbgGetArrayElementTag(ObjectId arrayId); 186bool dvmDbgOutputArray(ObjectId arrayId, int firstIndex, int count, 187 ExpandBuf* pReply); 188bool dvmDbgSetArrayElements(ObjectId arrayId, int firstIndex, int count, 189 const u1* buf); 190 191ObjectId dvmDbgCreateString(const char* str); 192ObjectId dvmDbgCreateObject(RefTypeId classId); 193 194bool dvmDbgMatchType(RefTypeId instClassId, RefTypeId classId); 195 196/* 197 * Method and Field 198 */ 199const char* dvmDbgGetMethodName(RefTypeId refTypeId, MethodId id); 200void dvmDbgOutputAllFields(RefTypeId refTypeId, bool withGeneric, 201 ExpandBuf* pReply); 202void dvmDbgOutputAllMethods(RefTypeId refTypeId, bool withGeneric, 203 ExpandBuf* pReply); 204void dvmDbgOutputAllInterfaces(RefTypeId refTypeId, ExpandBuf* pReply); 205void dvmDbgOutputLineTable(RefTypeId refTypeId, MethodId methodId, 206 ExpandBuf* pReply); 207void dvmDbgOutputVariableTable(RefTypeId refTypeId, MethodId id, 208 bool withGeneric, ExpandBuf* pReply); 209 210int dvmDbgGetFieldTag(ObjectId objId, FieldId fieldId); 211int dvmDbgGetStaticFieldTag(RefTypeId refTypeId, FieldId fieldId); 212void dvmDbgGetFieldValue(ObjectId objId, FieldId fieldId, u1* ptr, int width); 213void dvmDbgSetFieldValue(ObjectId objectId, FieldId fieldId, u8 value, 214 int width); 215void dvmDbgGetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId, u1* ptr, 216 int width); 217void dvmDbgSetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId, 218 u8 rawValue, int width); 219 220char* dvmDbgStringToUtf8(ObjectId strId); 221 222/* 223 * Thread, ThreadGroup, Frame 224 */ 225char* dvmDbgGetThreadName(ObjectId threadId); 226ObjectId dvmDbgGetThreadGroup(ObjectId threadId); 227char* dvmDbgGetThreadGroupName(ObjectId threadGroupId); 228ObjectId dvmDbgGetThreadGroupParent(ObjectId threadGroupId); 229ObjectId dvmDbgGetSystemThreadGroupId(void); 230ObjectId dvmDbgGetMainThreadGroupId(void); 231 232bool dvmDbgGetThreadStatus(ObjectId threadId, u4* threadStatus, 233 u4* suspendStatus); 234u4 dvmDbgGetThreadSuspendCount(ObjectId threadId); 235bool dvmDbgThreadExists(ObjectId threadId); 236bool dvmDbgIsSuspended(ObjectId threadId); 237//void dvmDbgWaitForSuspend(ObjectId threadId); 238void dvmDbgGetThreadGroupThreads(ObjectId threadGroupId, 239 ObjectId** ppThreadIds, u4* pThreadCount); 240void dvmDbgGetAllThreads(ObjectId** ppThreadIds, u4* pThreadCount); 241int dvmDbgGetThreadFrameCount(ObjectId threadId); 242bool dvmDbgGetThreadFrame(ObjectId threadId, int num, FrameId* pFrameId, 243 JdwpLocation* pLoc); 244 245ObjectId dvmDbgGetThreadSelfId(void); 246void dvmDbgSuspendVM(bool isEvent); 247void dvmDbgResumeVM(void); 248void dvmDbgSuspendThread(ObjectId threadId); 249void dvmDbgResumeThread(ObjectId threadId); 250void dvmDbgSuspendSelf(void); 251 252bool dvmDbgGetThisObject(ObjectId threadId, FrameId frameId, ObjectId* pThisId); 253void dvmDbgGetLocalValue(ObjectId threadId, FrameId frameId, int slot, 254 u1 tag, u1* buf, int expectedLen); 255void dvmDbgSetLocalValue(ObjectId threadId, FrameId frameId, int slot, 256 u1 tag, u8 value, int width); 257 258 259/* 260 * Debugger notification 261 */ 262void dvmDbgPostLocationEvent(const struct Method* method, int pcOffset, 263 struct Object* thisPtr, int eventFlags); 264void dvmDbgPostException(void* throwFp, int throwRelPc, void* catchFp, 265 int catchRelPc, struct Object* exception); 266void dvmDbgPostThreadStart(struct Thread* thread); 267void dvmDbgPostThreadDeath(struct Thread* thread); 268void dvmDbgPostClassPrepare(struct ClassObject* clazz); 269// FieldAccess, FieldModification 270 271/* for "eventFlags" */ 272enum { 273 DBG_BREAKPOINT = 0x01, 274 DBG_SINGLE_STEP = 0x02, 275 DBG_METHOD_ENTRY = 0x04, 276 DBG_METHOD_EXIT = 0x08, 277}; 278 279bool dvmDbgWatchLocation(const JdwpLocation* pLoc); 280void dvmDbgUnwatchLocation(const JdwpLocation* pLoc); 281bool dvmDbgConfigureStep(ObjectId threadId, enum JdwpStepSize size, 282 enum JdwpStepDepth depth); 283void dvmDbgUnconfigureStep(ObjectId threadId); 284 285JdwpError dvmDbgInvokeMethod(ObjectId threadId, ObjectId objectId, 286 RefTypeId classId, MethodId methodId, u4 numArgs, u8* argArray, 287 u4 options, u1* pResultTag, u8* pResultValue, ObjectId* pExceptObj); 288void dvmDbgExecuteMethod(DebugInvokeReq* pReq); 289 290/* Make an AddressSet for a line, for single stepping */ 291const AddressSet *dvmAddressSetForLine(const struct Method* method, int line); 292 293/* 294 * DDM support. 295 */ 296bool dvmDbgDdmHandlePacket(const u1* buf, int dataLen, u1** pReplyBuf, 297 int* pReplyLen); 298void dvmDbgDdmConnected(void); 299void dvmDbgDdmDisconnected(void); 300void dvmDbgDdmSendChunk(int type, int len, const u1* buf); 301 302#define CHUNK_TYPE(_name) \ 303 ((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3]) 304 305#endif /*_DALVIK_DEBUGGER*/ 306