blob: dd9679f62b2e7c7c2535850f3147a527c13823c4 [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
29#ifdef __cplusplus
30extern "C" {
31#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080032
33/* fwd decl */
34struct Object;
35struct ClassObject;
36struct Method;
37struct Thread;
38
39/*
Andy McFadden96516932009-10-28 17:39:02 -070040 * Used by StepControl to track a set of addresses associated with
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080041 * a single line.
42 */
43typedef struct AddressSet {
44 u4 setSize;
45 u1 set[1];
46} AddressSet;
47
48INLINE void dvmAddressSetSet(AddressSet *pSet, u4 toSet)
49{
50 if (toSet < pSet->setSize) {
51 pSet->set[toSet/8] |= 1 << (toSet % 8);
52 }
53}
54
55INLINE bool dvmAddressSetGet(const AddressSet *pSet, u4 toGet)
56{
57 if (toGet < pSet->setSize) {
58 return (pSet->set[toGet/8] & (1 << (toGet % 8))) != 0;
59 } else {
60 return false;
61 }
62}
63
64/*
65 * Single-step management.
66 */
67typedef struct StepControl {
68 /* request */
69 enum JdwpStepSize size;
70 enum JdwpStepDepth depth;
71 struct Thread* thread; /* don't deref; for comparison only */
72
73 /* current state */
74 bool active;
75 const struct Method* method;
76 int line; /* line #; could be -1 */
77 const AddressSet* pAddressSet; /* if non-null, address set for line */
78 int frameDepth;
79} StepControl;
80
81/*
82 * Invoke-during-breakpoint support.
83 */
84typedef struct DebugInvokeReq {
85 /* boolean; only set when we're in the tail end of an event handler */
86 bool ready;
87
88 /* boolean; set if the JDWP thread wants this thread to do work */
89 bool invokeNeeded;
90
91 /* request */
92 struct Object* obj; /* not used for ClassType.InvokeMethod */
93 struct Object* thread;
94 struct ClassObject* clazz;
95 struct Method* method;
96 u4 numArgs;
97 u8* argArray; /* will be NULL if numArgs==0 */
98 u4 options;
99
100 /* result */
101 JdwpError err;
102 u1 resultTag;
103 JValue resultValue;
104 ObjectId exceptObj;
105
106 /* condition variable to wait on while the method executes */
107 pthread_mutex_t lock;
108 pthread_cond_t cv;
109} DebugInvokeReq;
110
111/* system init/shutdown */
112bool dvmDebuggerStartup(void);
113void dvmDebuggerShutdown(void);
114
115void dvmDbgInitMutex(pthread_mutex_t* pMutex);
116void dvmDbgLockMutex(pthread_mutex_t* pMutex);
117void dvmDbgUnlockMutex(pthread_mutex_t* pMutex);
118void dvmDbgInitCond(pthread_cond_t* pCond);
119void dvmDbgCondWait(pthread_cond_t* pCond, pthread_mutex_t* pMutex);
120void dvmDbgCondSignal(pthread_cond_t* pCond);
121void dvmDbgCondBroadcast(pthread_cond_t* pCond);
122
123/*
124 * Return the DebugInvokeReq for the current thread.
125 */
126DebugInvokeReq* dvmDbgGetInvokeReq(void);
127
128/*
129 * Enable/disable breakpoints and step modes. Used to provide a heads-up
130 * when the debugger attaches.
131 */
132void dvmDbgConnected(void);
133void dvmDbgActive(void);
134void dvmDbgDisconnected(void);
135
136/*
137 * Returns "true" if a debugger is connected. Returns "false" if it's
138 * just DDM.
139 */
140bool dvmDbgIsDebuggerConnected(void);
141
142/*
143 * Time, in milliseconds, since the last debugger activity. Does not
144 * include DDMS activity. Returns -1 if there has been no activity.
145 * Returns 0 if we're in the middle of handling a debugger request.
146 */
147s8 dvmDbgLastDebuggerActivity(void);
148
149/*
150 * Block/allow GC depending on what we're doing. These return the old
151 * status, which can be fed to dvmDbgThreadGoing() to restore the previous
152 * mode.
153 */
154int dvmDbgThreadRunning(void);
155int dvmDbgThreadWaiting(void);
156int dvmDbgThreadContinuing(int status);
157
158/*
159 * The debugger wants the VM to exit.
160 */
161void dvmDbgExit(int status);
162
163/*
164 * Class, Object, Array
165 */
166const char* dvmDbgGetClassDescriptor(RefTypeId id);
Andy McFadden6ff3c8f2009-10-13 13:06:03 -0700167ObjectId dvmDbgGetClassObject(RefTypeId id);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800168RefTypeId dvmDbgGetSuperclass(RefTypeId id);
169ObjectId dvmDbgGetClassLoader(RefTypeId id);
170u4 dvmDbgGetAccessFlags(RefTypeId id);
171bool dvmDbgIsInterface(RefTypeId id);
172void dvmDbgGetClassList(u4* pNumClasses, RefTypeId** pClassRefBuf);
173void dvmDbgGetVisibleClassList(ObjectId classLoaderId, u4* pNumClasses,
174 RefTypeId** pClassRefBuf);
175void dvmDbgGetClassInfo(RefTypeId classId, u1* pTypeTag, u4* pStatus,
Andy McFadden09709762011-03-18 14:27:06 -0700176 const char** pSignature);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800177bool dvmDbgFindLoadedClassBySignature(const char* classDescriptor,
178 RefTypeId* pRefTypeId);
179void dvmDbgGetObjectType(ObjectId objectId, u1* pRefTypeTag,
180 RefTypeId* pRefTypeId);
181u1 dvmDbgGetClassObjectType(RefTypeId refTypeId);
Andy McFadden09709762011-03-18 14:27:06 -0700182const char* dvmDbgGetSignature(RefTypeId refTypeId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800183const char* dvmDbgGetSourceFile(RefTypeId refTypeId);
Andy McFadden09709762011-03-18 14:27:06 -0700184const char* dvmDbgGetObjectTypeName(ObjectId objectId);
185u1 dvmDbgGetObjectTag(ObjectId objectId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800186int dvmDbgGetTagWidth(int tag);
187
188int dvmDbgGetArrayLength(ObjectId arrayId);
Andy McFadden09709762011-03-18 14:27:06 -0700189u1 dvmDbgGetArrayElementTag(ObjectId arrayId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800190bool dvmDbgOutputArray(ObjectId arrayId, int firstIndex, int count,
191 ExpandBuf* pReply);
192bool dvmDbgSetArrayElements(ObjectId arrayId, int firstIndex, int count,
193 const u1* buf);
194
195ObjectId dvmDbgCreateString(const char* str);
Andy McFaddenf50c6d52009-10-02 15:56:26 -0700196ObjectId dvmDbgCreateObject(RefTypeId classId);
Andy McFadden884cd422010-07-19 13:51:36 -0700197ObjectId dvmDbgCreateArrayObject(RefTypeId arrayTypeId, u4 length);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800198
199bool dvmDbgMatchType(RefTypeId instClassId, RefTypeId classId);
200
201/*
202 * Method and Field
203 */
204const char* dvmDbgGetMethodName(RefTypeId refTypeId, MethodId id);
205void dvmDbgOutputAllFields(RefTypeId refTypeId, bool withGeneric,
206 ExpandBuf* pReply);
207void dvmDbgOutputAllMethods(RefTypeId refTypeId, bool withGeneric,
208 ExpandBuf* pReply);
209void dvmDbgOutputAllInterfaces(RefTypeId refTypeId, ExpandBuf* pReply);
210void dvmDbgOutputLineTable(RefTypeId refTypeId, MethodId methodId,
211 ExpandBuf* pReply);
212void dvmDbgOutputVariableTable(RefTypeId refTypeId, MethodId id,
213 bool withGeneric, ExpandBuf* pReply);
214
Andy McFadden09709762011-03-18 14:27:06 -0700215u1 dvmDbgGetFieldBasicTag(ObjectId objId, FieldId fieldId);
216u1 dvmDbgGetStaticFieldBasicTag(RefTypeId refTypeId, FieldId fieldId);
217void dvmDbgGetFieldValue(ObjectId objectId, FieldId fieldId, ExpandBuf* pReply);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800218void dvmDbgSetFieldValue(ObjectId objectId, FieldId fieldId, u8 value,
219 int width);
Andy McFadden09709762011-03-18 14:27:06 -0700220void dvmDbgGetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId,
221 ExpandBuf* pReply);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800222void dvmDbgSetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId,
223 u8 rawValue, int width);
224
225char* dvmDbgStringToUtf8(ObjectId strId);
226
227/*
228 * Thread, ThreadGroup, Frame
229 */
230char* dvmDbgGetThreadName(ObjectId threadId);
231ObjectId dvmDbgGetThreadGroup(ObjectId threadId);
232char* dvmDbgGetThreadGroupName(ObjectId threadGroupId);
233ObjectId dvmDbgGetThreadGroupParent(ObjectId threadGroupId);
234ObjectId dvmDbgGetSystemThreadGroupId(void);
235ObjectId dvmDbgGetMainThreadGroupId(void);
236
237bool dvmDbgGetThreadStatus(ObjectId threadId, u4* threadStatus,
238 u4* suspendStatus);
239u4 dvmDbgGetThreadSuspendCount(ObjectId threadId);
240bool dvmDbgThreadExists(ObjectId threadId);
241bool dvmDbgIsSuspended(ObjectId threadId);
242//void dvmDbgWaitForSuspend(ObjectId threadId);
243void dvmDbgGetThreadGroupThreads(ObjectId threadGroupId,
244 ObjectId** ppThreadIds, u4* pThreadCount);
245void dvmDbgGetAllThreads(ObjectId** ppThreadIds, u4* pThreadCount);
246int dvmDbgGetThreadFrameCount(ObjectId threadId);
247bool dvmDbgGetThreadFrame(ObjectId threadId, int num, FrameId* pFrameId,
248 JdwpLocation* pLoc);
249
250ObjectId dvmDbgGetThreadSelfId(void);
251void dvmDbgSuspendVM(bool isEvent);
252void dvmDbgResumeVM(void);
253void dvmDbgSuspendThread(ObjectId threadId);
254void dvmDbgResumeThread(ObjectId threadId);
255void dvmDbgSuspendSelf(void);
256
257bool dvmDbgGetThisObject(ObjectId threadId, FrameId frameId, ObjectId* pThisId);
258void dvmDbgGetLocalValue(ObjectId threadId, FrameId frameId, int slot,
259 u1 tag, u1* buf, int expectedLen);
260void dvmDbgSetLocalValue(ObjectId threadId, FrameId frameId, int slot,
261 u1 tag, u8 value, int width);
262
263
264/*
265 * Debugger notification
266 */
267void dvmDbgPostLocationEvent(const struct Method* method, int pcOffset,
268 struct Object* thisPtr, int eventFlags);
269void dvmDbgPostException(void* throwFp, int throwRelPc, void* catchFp,
270 int catchRelPc, struct Object* exception);
271void dvmDbgPostThreadStart(struct Thread* thread);
272void dvmDbgPostThreadDeath(struct Thread* thread);
273void dvmDbgPostClassPrepare(struct ClassObject* clazz);
274// FieldAccess, FieldModification
275
276/* for "eventFlags" */
277enum {
278 DBG_BREAKPOINT = 0x01,
279 DBG_SINGLE_STEP = 0x02,
280 DBG_METHOD_ENTRY = 0x04,
281 DBG_METHOD_EXIT = 0x08,
282};
283
284bool dvmDbgWatchLocation(const JdwpLocation* pLoc);
285void dvmDbgUnwatchLocation(const JdwpLocation* pLoc);
286bool dvmDbgConfigureStep(ObjectId threadId, enum JdwpStepSize size,
287 enum JdwpStepDepth depth);
288void dvmDbgUnconfigureStep(ObjectId threadId);
289
290JdwpError dvmDbgInvokeMethod(ObjectId threadId, ObjectId objectId,
291 RefTypeId classId, MethodId methodId, u4 numArgs, u8* argArray,
292 u4 options, u1* pResultTag, u8* pResultValue, ObjectId* pExceptObj);
293void dvmDbgExecuteMethod(DebugInvokeReq* pReq);
294
295/* Make an AddressSet for a line, for single stepping */
296const AddressSet *dvmAddressSetForLine(const struct Method* method, int line);
297
Andy McFaddenc6e64ea2009-12-04 16:36:08 -0800298/* perform "late registration" of an object ID */
299void dvmDbgRegisterObjectId(ObjectId id);
300
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800301/*
302 * DDM support.
303 */
304bool dvmDbgDdmHandlePacket(const u1* buf, int dataLen, u1** pReplyBuf,
305 int* pReplyLen);
306void dvmDbgDdmConnected(void);
307void dvmDbgDdmDisconnected(void);
Andy McFadden01718122010-01-22 16:36:30 -0800308void dvmDbgDdmSendChunk(int type, size_t len, const u1* buf);
309void dvmDbgDdmSendChunkV(int type, const struct iovec* iov, int iovcnt);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800310
311#define CHUNK_TYPE(_name) \
312 ((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3])
313
Carl Shapiroae188c62011-04-08 13:11:58 -0700314#ifdef __cplusplus
315}
316#endif
317
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800318#endif /*_DALVIK_DEBUGGER*/