2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * Dalvik-specific side of debugger support. (The JDWP code is intended to
18 * be relatively generic.)
20 #ifndef _DALVIK_DEBUGGER
21 #define _DALVIK_DEBUGGER
25 #include "jdwp/Jdwp.h"
35 * used by StepControl to track a set of addresses associated with
38 typedef struct AddressSet {
43 INLINE void dvmAddressSetSet(AddressSet *pSet, u4 toSet)
45 if (toSet < pSet->setSize) {
46 pSet->set[toSet/8] |= 1 << (toSet % 8);
50 INLINE bool dvmAddressSetGet(const AddressSet *pSet, u4 toGet)
52 if (toGet < pSet->setSize) {
53 return (pSet->set[toGet/8] & (1 << (toGet % 8))) != 0;
60 * Single-step management.
62 typedef struct StepControl {
64 enum JdwpStepSize size;
65 enum JdwpStepDepth depth;
66 struct Thread* thread; /* don't deref; for comparison only */
70 const struct Method* method;
71 int line; /* line #; could be -1 */
72 const AddressSet* pAddressSet; /* if non-null, address set for line */
77 * Invoke-during-breakpoint support.
79 typedef struct DebugInvokeReq {
80 /* boolean; only set when we're in the tail end of an event handler */
83 /* boolean; set if the JDWP thread wants this thread to do work */
87 struct Object* obj; /* not used for ClassType.InvokeMethod */
88 struct Object* thread;
89 struct ClassObject* clazz;
90 struct Method* method;
92 u8* argArray; /* will be NULL if numArgs==0 */
101 /* condition variable to wait on while the method executes */
102 pthread_mutex_t lock;
106 /* system init/shutdown */
107 bool dvmDebuggerStartup(void);
108 void dvmDebuggerShutdown(void);
110 void dvmDbgInitMutex(pthread_mutex_t* pMutex);
111 void dvmDbgLockMutex(pthread_mutex_t* pMutex);
112 void dvmDbgUnlockMutex(pthread_mutex_t* pMutex);
113 void dvmDbgInitCond(pthread_cond_t* pCond);
114 void dvmDbgCondWait(pthread_cond_t* pCond, pthread_mutex_t* pMutex);
115 void dvmDbgCondSignal(pthread_cond_t* pCond);
116 void dvmDbgCondBroadcast(pthread_cond_t* pCond);
119 * Return the DebugInvokeReq for the current thread.
121 DebugInvokeReq* dvmDbgGetInvokeReq(void);
124 * Enable/disable breakpoints and step modes. Used to provide a heads-up
125 * when the debugger attaches.
127 void dvmDbgConnected(void);
128 void dvmDbgActive(void);
129 void dvmDbgDisconnected(void);
132 * Returns "true" if a debugger is connected. Returns "false" if it's
135 bool dvmDbgIsDebuggerConnected(void);
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.
142 s8 dvmDbgLastDebuggerActivity(void);
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
149 int dvmDbgThreadRunning(void);
150 int dvmDbgThreadWaiting(void);
151 int dvmDbgThreadContinuing(int status);
154 * The debugger wants the VM to exit.
156 void dvmDbgExit(int status);
159 * Class, Object, Array
161 const char* dvmDbgGetClassDescriptor(RefTypeId id);
162 ObjectId dvmDbgGetClassObject(RefTypeId id);
163 RefTypeId dvmDbgGetSuperclass(RefTypeId id);
164 ObjectId dvmDbgGetClassLoader(RefTypeId id);
165 u4 dvmDbgGetAccessFlags(RefTypeId id);
166 bool dvmDbgIsInterface(RefTypeId id);
167 void dvmDbgGetClassList(u4* pNumClasses, RefTypeId** pClassRefBuf);
168 void dvmDbgGetVisibleClassList(ObjectId classLoaderId, u4* pNumClasses,
169 RefTypeId** pClassRefBuf);
170 void dvmDbgGetClassInfo(RefTypeId classId, u1* pTypeTag, u4* pStatus,
172 bool dvmDbgFindLoadedClassBySignature(const char* classDescriptor,
173 RefTypeId* pRefTypeId);
174 void dvmDbgGetObjectType(ObjectId objectId, u1* pRefTypeTag,
175 RefTypeId* pRefTypeId);
176 u1 dvmDbgGetClassObjectType(RefTypeId refTypeId);
177 char* dvmDbgGetSignature(RefTypeId refTypeId);
178 const char* dvmDbgGetSourceFile(RefTypeId refTypeId);
179 char* dvmDbgGetObjectTypeName(ObjectId objectId);
180 int dvmDbgGetSignatureTag(const char* signature);
181 int dvmDbgGetObjectTag(ObjectId objectId, const char* type);
182 int dvmDbgGetTagWidth(int tag);
184 int dvmDbgGetArrayLength(ObjectId arrayId);
185 int dvmDbgGetArrayElementTag(ObjectId arrayId);
186 bool dvmDbgOutputArray(ObjectId arrayId, int firstIndex, int count,
188 bool dvmDbgSetArrayElements(ObjectId arrayId, int firstIndex, int count,
191 ObjectId dvmDbgCreateString(const char* str);
192 ObjectId dvmDbgCreateObject(RefTypeId classId);
194 bool dvmDbgMatchType(RefTypeId instClassId, RefTypeId classId);
199 const char* dvmDbgGetMethodName(RefTypeId refTypeId, MethodId id);
200 void dvmDbgOutputAllFields(RefTypeId refTypeId, bool withGeneric,
202 void dvmDbgOutputAllMethods(RefTypeId refTypeId, bool withGeneric,
204 void dvmDbgOutputAllInterfaces(RefTypeId refTypeId, ExpandBuf* pReply);
205 void dvmDbgOutputLineTable(RefTypeId refTypeId, MethodId methodId,
207 void dvmDbgOutputVariableTable(RefTypeId refTypeId, MethodId id,
208 bool withGeneric, ExpandBuf* pReply);
210 int dvmDbgGetFieldTag(ObjectId objId, FieldId fieldId);
211 int dvmDbgGetStaticFieldTag(RefTypeId refTypeId, FieldId fieldId);
212 void dvmDbgGetFieldValue(ObjectId objId, FieldId fieldId, u1* ptr, int width);
213 void dvmDbgSetFieldValue(ObjectId objectId, FieldId fieldId, u8 value,
215 void dvmDbgGetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId, u1* ptr,
217 void dvmDbgSetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId,
218 u8 rawValue, int width);
220 char* dvmDbgStringToUtf8(ObjectId strId);
223 * Thread, ThreadGroup, Frame
225 char* dvmDbgGetThreadName(ObjectId threadId);
226 ObjectId dvmDbgGetThreadGroup(ObjectId threadId);
227 char* dvmDbgGetThreadGroupName(ObjectId threadGroupId);
228 ObjectId dvmDbgGetThreadGroupParent(ObjectId threadGroupId);
229 ObjectId dvmDbgGetSystemThreadGroupId(void);
230 ObjectId dvmDbgGetMainThreadGroupId(void);
232 bool dvmDbgGetThreadStatus(ObjectId threadId, u4* threadStatus,
234 u4 dvmDbgGetThreadSuspendCount(ObjectId threadId);
235 bool dvmDbgThreadExists(ObjectId threadId);
236 bool dvmDbgIsSuspended(ObjectId threadId);
237 //void dvmDbgWaitForSuspend(ObjectId threadId);
238 void dvmDbgGetThreadGroupThreads(ObjectId threadGroupId,
239 ObjectId** ppThreadIds, u4* pThreadCount);
240 void dvmDbgGetAllThreads(ObjectId** ppThreadIds, u4* pThreadCount);
241 int dvmDbgGetThreadFrameCount(ObjectId threadId);
242 bool dvmDbgGetThreadFrame(ObjectId threadId, int num, FrameId* pFrameId,
245 ObjectId dvmDbgGetThreadSelfId(void);
246 void dvmDbgSuspendVM(bool isEvent);
247 void dvmDbgResumeVM(void);
248 void dvmDbgSuspendThread(ObjectId threadId);
249 void dvmDbgResumeThread(ObjectId threadId);
250 void dvmDbgSuspendSelf(void);
252 bool dvmDbgGetThisObject(ObjectId threadId, FrameId frameId, ObjectId* pThisId);
253 void dvmDbgGetLocalValue(ObjectId threadId, FrameId frameId, int slot,
254 u1 tag, u1* buf, int expectedLen);
255 void dvmDbgSetLocalValue(ObjectId threadId, FrameId frameId, int slot,
256 u1 tag, u8 value, int width);
260 * Debugger notification
262 void dvmDbgPostLocationEvent(const struct Method* method, int pcOffset,
263 struct Object* thisPtr, int eventFlags);
264 void dvmDbgPostException(void* throwFp, int throwRelPc, void* catchFp,
265 int catchRelPc, struct Object* exception);
266 void dvmDbgPostThreadStart(struct Thread* thread);
267 void dvmDbgPostThreadDeath(struct Thread* thread);
268 void dvmDbgPostClassPrepare(struct ClassObject* clazz);
269 // FieldAccess, FieldModification
271 /* for "eventFlags" */
273 DBG_BREAKPOINT = 0x01,
274 DBG_SINGLE_STEP = 0x02,
275 DBG_METHOD_ENTRY = 0x04,
276 DBG_METHOD_EXIT = 0x08,
279 bool dvmDbgWatchLocation(const JdwpLocation* pLoc);
280 void dvmDbgUnwatchLocation(const JdwpLocation* pLoc);
281 bool dvmDbgConfigureStep(ObjectId threadId, enum JdwpStepSize size,
282 enum JdwpStepDepth depth);
283 void dvmDbgUnconfigureStep(ObjectId threadId);
285 JdwpError dvmDbgInvokeMethod(ObjectId threadId, ObjectId objectId,
286 RefTypeId classId, MethodId methodId, u4 numArgs, u8* argArray,
287 u4 options, u1* pResultTag, u8* pResultValue, ObjectId* pExceptObj);
288 void dvmDbgExecuteMethod(DebugInvokeReq* pReq);
290 /* Make an AddressSet for a line, for single stepping */
291 const AddressSet *dvmAddressSetForLine(const struct Method* method, int line);
296 bool dvmDbgDdmHandlePacket(const u1* buf, int dataLen, u1** pReplyBuf,
298 void dvmDbgDdmConnected(void);
299 void dvmDbgDdmDisconnected(void);
300 void dvmDbgDdmSendChunk(int type, int len, const u1* buf);
302 #define CHUNK_TYPE(_name) \
303 ((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3])
305 #endif /*_DALVIK_DEBUGGER*/