blob: aaef02d880c843ab7da505d59ee576d61171f29f [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
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 */
Andy McFadden96516932009-10-28 17:39:02 -070016
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080017/*
18 * Dalvik-specific side of debugger support. (The JDWP code is intended to
19 * be relatively generic.)
20 */
21#ifndef _DALVIK_DEBUGGER
22#define _DALVIK_DEBUGGER
23
Carl Shapiroae188c62011-04-08 13:11:58 -070024#include <pthread.h>
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080025#include "Common.h"
26#include "Misc.h"
27#include "jdwp/Jdwp.h"
Carl Shapiroae188c62011-04-08 13:11:58 -070028
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080029/* fwd decl */
30struct Object;
31struct ClassObject;
32struct Method;
33struct Thread;
34
35/*
Andy McFadden96516932009-10-28 17:39:02 -070036 * Used by StepControl to track a set of addresses associated with
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080037 * a single line.
38 */
Carl Shapirod862faa2011-04-27 23:00:01 -070039struct AddressSet {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080040 u4 setSize;
41 u1 set[1];
Carl Shapirod862faa2011-04-27 23:00:01 -070042};
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080043
44INLINE void dvmAddressSetSet(AddressSet *pSet, u4 toSet)
45{
46 if (toSet < pSet->setSize) {
47 pSet->set[toSet/8] |= 1 << (toSet % 8);
48 }
49}
50
51INLINE bool dvmAddressSetGet(const AddressSet *pSet, u4 toGet)
52{
53 if (toGet < pSet->setSize) {
54 return (pSet->set[toGet/8] & (1 << (toGet % 8))) != 0;
55 } else {
56 return false;
57 }
58}
59
60/*
61 * Single-step management.
62 */
Carl Shapirod862faa2011-04-27 23:00:01 -070063struct StepControl {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080064 /* request */
Carl Shapirod862faa2011-04-27 23:00:01 -070065 JdwpStepSize size;
66 JdwpStepDepth depth;
67 Thread* thread; /* don't deref; for comparison only */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080068
69 /* current state */
Carl Shapirod862faa2011-04-27 23:00:01 -070070 bool active;
71 const Method* method;
72 int line; /* line #; could be -1 */
73 const AddressSet* pAddressSet; /* if non-null, address set for line */
74 int frameDepth;
75};
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080076
77/*
78 * Invoke-during-breakpoint support.
79 */
Carl Shapirod862faa2011-04-27 23:00:01 -070080struct DebugInvokeReq {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080081 /* boolean; only set when we're in the tail end of an event handler */
82 bool ready;
83
84 /* boolean; set if the JDWP thread wants this thread to do work */
85 bool invokeNeeded;
86
87 /* request */
Carl Shapirod862faa2011-04-27 23:00:01 -070088 Object* obj; /* not used for ClassType.InvokeMethod */
89 Object* thread;
90 ClassObject* clazz;
91 Method* method;
92 u4 numArgs;
93 u8* argArray; /* will be NULL if numArgs==0 */
94 u4 options;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080095
96 /* result */
Carl Shapirod862faa2011-04-27 23:00:01 -070097 JdwpError err;
98 u1 resultTag;
99 JValue resultValue;
100 ObjectId exceptObj;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800101
102 /* condition variable to wait on while the method executes */
Carl Shapirod862faa2011-04-27 23:00:01 -0700103 pthread_mutex_t lock;
104 pthread_cond_t cv;
105};
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800106
107/* system init/shutdown */
108bool dvmDebuggerStartup(void);
109void dvmDebuggerShutdown(void);
110
111void dvmDbgInitMutex(pthread_mutex_t* pMutex);
112void dvmDbgLockMutex(pthread_mutex_t* pMutex);
113void dvmDbgUnlockMutex(pthread_mutex_t* pMutex);
114void dvmDbgInitCond(pthread_cond_t* pCond);
115void dvmDbgCondWait(pthread_cond_t* pCond, pthread_mutex_t* pMutex);
116void dvmDbgCondSignal(pthread_cond_t* pCond);
117void dvmDbgCondBroadcast(pthread_cond_t* pCond);
118
119/*
120 * Return the DebugInvokeReq for the current thread.
121 */
122DebugInvokeReq* dvmDbgGetInvokeReq(void);
123
124/*
125 * Enable/disable breakpoints and step modes. Used to provide a heads-up
126 * when the debugger attaches.
127 */
128void dvmDbgConnected(void);
129void dvmDbgActive(void);
130void dvmDbgDisconnected(void);
131
132/*
133 * Returns "true" if a debugger is connected. Returns "false" if it's
134 * just DDM.
135 */
136bool dvmDbgIsDebuggerConnected(void);
137
138/*
139 * Time, in milliseconds, since the last debugger activity. Does not
140 * include DDMS activity. Returns -1 if there has been no activity.
141 * Returns 0 if we're in the middle of handling a debugger request.
142 */
143s8 dvmDbgLastDebuggerActivity(void);
144
145/*
146 * Block/allow GC depending on what we're doing. These return the old
147 * status, which can be fed to dvmDbgThreadGoing() to restore the previous
148 * mode.
149 */
150int dvmDbgThreadRunning(void);
151int dvmDbgThreadWaiting(void);
152int dvmDbgThreadContinuing(int status);
153
154/*
155 * The debugger wants the VM to exit.
156 */
157void dvmDbgExit(int status);
158
159/*
160 * Class, Object, Array
161 */
162const char* dvmDbgGetClassDescriptor(RefTypeId id);
Andy McFadden6ff3c8f2009-10-13 13:06:03 -0700163ObjectId dvmDbgGetClassObject(RefTypeId id);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800164RefTypeId dvmDbgGetSuperclass(RefTypeId id);
165ObjectId dvmDbgGetClassLoader(RefTypeId id);
166u4 dvmDbgGetAccessFlags(RefTypeId id);
167bool dvmDbgIsInterface(RefTypeId id);
168void dvmDbgGetClassList(u4* pNumClasses, RefTypeId** pClassRefBuf);
169void dvmDbgGetVisibleClassList(ObjectId classLoaderId, u4* pNumClasses,
170 RefTypeId** pClassRefBuf);
171void dvmDbgGetClassInfo(RefTypeId classId, u1* pTypeTag, u4* pStatus,
Andy McFadden09709762011-03-18 14:27:06 -0700172 const char** pSignature);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800173bool dvmDbgFindLoadedClassBySignature(const char* classDescriptor,
174 RefTypeId* pRefTypeId);
175void dvmDbgGetObjectType(ObjectId objectId, u1* pRefTypeTag,
176 RefTypeId* pRefTypeId);
177u1 dvmDbgGetClassObjectType(RefTypeId refTypeId);
Andy McFadden09709762011-03-18 14:27:06 -0700178const char* dvmDbgGetSignature(RefTypeId refTypeId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800179const char* dvmDbgGetSourceFile(RefTypeId refTypeId);
Andy McFadden09709762011-03-18 14:27:06 -0700180const char* dvmDbgGetObjectTypeName(ObjectId objectId);
181u1 dvmDbgGetObjectTag(ObjectId objectId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800182int dvmDbgGetTagWidth(int tag);
183
184int dvmDbgGetArrayLength(ObjectId arrayId);
Andy McFadden09709762011-03-18 14:27:06 -0700185u1 dvmDbgGetArrayElementTag(ObjectId arrayId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800186bool 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);
Andy McFaddenf50c6d52009-10-02 15:56:26 -0700192ObjectId dvmDbgCreateObject(RefTypeId classId);
Andy McFadden884cd422010-07-19 13:51:36 -0700193ObjectId dvmDbgCreateArrayObject(RefTypeId arrayTypeId, u4 length);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800194
195bool dvmDbgMatchType(RefTypeId instClassId, RefTypeId classId);
196
197/*
198 * Method and Field
199 */
200const char* dvmDbgGetMethodName(RefTypeId refTypeId, MethodId id);
201void dvmDbgOutputAllFields(RefTypeId refTypeId, bool withGeneric,
202 ExpandBuf* pReply);
203void dvmDbgOutputAllMethods(RefTypeId refTypeId, bool withGeneric,
204 ExpandBuf* pReply);
205void dvmDbgOutputAllInterfaces(RefTypeId refTypeId, ExpandBuf* pReply);
206void dvmDbgOutputLineTable(RefTypeId refTypeId, MethodId methodId,
207 ExpandBuf* pReply);
208void dvmDbgOutputVariableTable(RefTypeId refTypeId, MethodId id,
209 bool withGeneric, ExpandBuf* pReply);
210
Andy McFadden09709762011-03-18 14:27:06 -0700211u1 dvmDbgGetFieldBasicTag(ObjectId objId, FieldId fieldId);
212u1 dvmDbgGetStaticFieldBasicTag(RefTypeId refTypeId, FieldId fieldId);
213void dvmDbgGetFieldValue(ObjectId objectId, FieldId fieldId, ExpandBuf* pReply);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800214void dvmDbgSetFieldValue(ObjectId objectId, FieldId fieldId, u8 value,
215 int width);
Andy McFadden09709762011-03-18 14:27:06 -0700216void dvmDbgGetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId,
217 ExpandBuf* pReply);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800218void dvmDbgSetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId,
219 u8 rawValue, int width);
220
221char* dvmDbgStringToUtf8(ObjectId strId);
222
223/*
224 * Thread, ThreadGroup, Frame
225 */
226char* dvmDbgGetThreadName(ObjectId threadId);
227ObjectId dvmDbgGetThreadGroup(ObjectId threadId);
228char* dvmDbgGetThreadGroupName(ObjectId threadGroupId);
229ObjectId dvmDbgGetThreadGroupParent(ObjectId threadGroupId);
230ObjectId dvmDbgGetSystemThreadGroupId(void);
231ObjectId dvmDbgGetMainThreadGroupId(void);
232
233bool dvmDbgGetThreadStatus(ObjectId threadId, u4* threadStatus,
234 u4* suspendStatus);
235u4 dvmDbgGetThreadSuspendCount(ObjectId threadId);
236bool dvmDbgThreadExists(ObjectId threadId);
237bool dvmDbgIsSuspended(ObjectId threadId);
238//void dvmDbgWaitForSuspend(ObjectId threadId);
239void dvmDbgGetThreadGroupThreads(ObjectId threadGroupId,
240 ObjectId** ppThreadIds, u4* pThreadCount);
241void dvmDbgGetAllThreads(ObjectId** ppThreadIds, u4* pThreadCount);
242int dvmDbgGetThreadFrameCount(ObjectId threadId);
243bool dvmDbgGetThreadFrame(ObjectId threadId, int num, FrameId* pFrameId,
244 JdwpLocation* pLoc);
245
246ObjectId dvmDbgGetThreadSelfId(void);
247void dvmDbgSuspendVM(bool isEvent);
248void dvmDbgResumeVM(void);
249void dvmDbgSuspendThread(ObjectId threadId);
250void dvmDbgResumeThread(ObjectId threadId);
251void dvmDbgSuspendSelf(void);
252
253bool dvmDbgGetThisObject(ObjectId threadId, FrameId frameId, ObjectId* pThisId);
254void dvmDbgGetLocalValue(ObjectId threadId, FrameId frameId, int slot,
255 u1 tag, u1* buf, int expectedLen);
256void dvmDbgSetLocalValue(ObjectId threadId, FrameId frameId, int slot,
257 u1 tag, u8 value, int width);
258
259
260/*
261 * Debugger notification
262 */
Carl Shapirod862faa2011-04-27 23:00:01 -0700263void dvmDbgPostLocationEvent(const Method* method, int pcOffset,
264 Object* thisPtr, int eventFlags);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800265void dvmDbgPostException(void* throwFp, int throwRelPc, void* catchFp,
Carl Shapirod862faa2011-04-27 23:00:01 -0700266 int catchRelPc, Object* exception);
267void dvmDbgPostThreadStart(Thread* thread);
268void dvmDbgPostThreadDeath(Thread* thread);
269void dvmDbgPostClassPrepare(ClassObject* clazz);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800270
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);
Carl Shapirod862faa2011-04-27 23:00:01 -0700281bool dvmDbgConfigureStep(ObjectId threadId, JdwpStepSize size,
282 JdwpStepDepth depth);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800283void 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 */
Carl Shapirod862faa2011-04-27 23:00:01 -0700291const AddressSet *dvmAddressSetForLine(const Method* method, int line);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800292
Andy McFaddenc6e64ea2009-12-04 16:36:08 -0800293/* perform "late registration" of an object ID */
294void dvmDbgRegisterObjectId(ObjectId id);
295
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800296/*
297 * DDM support.
298 */
299bool dvmDbgDdmHandlePacket(const u1* buf, int dataLen, u1** pReplyBuf,
300 int* pReplyLen);
301void dvmDbgDdmConnected(void);
302void dvmDbgDdmDisconnected(void);
Andy McFadden01718122010-01-22 16:36:30 -0800303void dvmDbgDdmSendChunk(int type, size_t len, const u1* buf);
304void dvmDbgDdmSendChunkV(int type, const struct iovec* iov, int iovcnt);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800305
306#define CHUNK_TYPE(_name) \
307 ((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3])
308
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800309#endif /*_DALVIK_DEBUGGER*/