blob: b41318cd73b26cde064bb4160febdc7ea54b70c9 [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 */
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);
162RefTypeId dvmDbgGetSuperclass(RefTypeId id);
163ObjectId dvmDbgGetClassLoader(RefTypeId id);
164u4 dvmDbgGetAccessFlags(RefTypeId id);
165bool dvmDbgIsInterface(RefTypeId id);
166void dvmDbgGetClassList(u4* pNumClasses, RefTypeId** pClassRefBuf);
167void dvmDbgGetVisibleClassList(ObjectId classLoaderId, u4* pNumClasses,
168 RefTypeId** pClassRefBuf);
169void dvmDbgGetClassInfo(RefTypeId classId, u1* pTypeTag, u4* pStatus,
170 char** pSignature);
171bool dvmDbgFindLoadedClassBySignature(const char* classDescriptor,
172 RefTypeId* pRefTypeId);
173void dvmDbgGetObjectType(ObjectId objectId, u1* pRefTypeTag,
174 RefTypeId* pRefTypeId);
175u1 dvmDbgGetClassObjectType(RefTypeId refTypeId);
176char* dvmDbgGetSignature(RefTypeId refTypeId);
177const char* dvmDbgGetSourceFile(RefTypeId refTypeId);
178char* dvmDbgGetObjectTypeName(ObjectId objectId);
179int dvmDbgGetSignatureTag(const char* signature);
180int dvmDbgGetObjectTag(ObjectId objectId, const char* type);
181int dvmDbgGetTagWidth(int tag);
182
183int dvmDbgGetArrayLength(ObjectId arrayId);
184int dvmDbgGetArrayElementTag(ObjectId arrayId);
185bool dvmDbgOutputArray(ObjectId arrayId, int firstIndex, int count,
186 ExpandBuf* pReply);
187bool dvmDbgSetArrayElements(ObjectId arrayId, int firstIndex, int count,
188 const u1* buf);
189
190ObjectId dvmDbgCreateString(const char* str);
Andy McFaddenf50c6d52009-10-02 15:56:26 -0700191ObjectId dvmDbgCreateObject(RefTypeId classId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800192
193bool dvmDbgMatchType(RefTypeId instClassId, RefTypeId classId);
194
195/*
196 * Method and Field
197 */
198const char* dvmDbgGetMethodName(RefTypeId refTypeId, MethodId id);
199void dvmDbgOutputAllFields(RefTypeId refTypeId, bool withGeneric,
200 ExpandBuf* pReply);
201void dvmDbgOutputAllMethods(RefTypeId refTypeId, bool withGeneric,
202 ExpandBuf* pReply);
203void dvmDbgOutputAllInterfaces(RefTypeId refTypeId, ExpandBuf* pReply);
204void dvmDbgOutputLineTable(RefTypeId refTypeId, MethodId methodId,
205 ExpandBuf* pReply);
206void dvmDbgOutputVariableTable(RefTypeId refTypeId, MethodId id,
207 bool withGeneric, ExpandBuf* pReply);
208
209int dvmDbgGetFieldTag(ObjectId objId, FieldId fieldId);
210int dvmDbgGetStaticFieldTag(RefTypeId refTypeId, FieldId fieldId);
211void dvmDbgGetFieldValue(ObjectId objId, FieldId fieldId, u1* ptr, int width);
212void dvmDbgSetFieldValue(ObjectId objectId, FieldId fieldId, u8 value,
213 int width);
214void dvmDbgGetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId, u1* ptr,
215 int width);
216void dvmDbgSetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId,
217 u8 rawValue, int width);
218
219char* dvmDbgStringToUtf8(ObjectId strId);
220
221/*
222 * Thread, ThreadGroup, Frame
223 */
224char* dvmDbgGetThreadName(ObjectId threadId);
225ObjectId dvmDbgGetThreadGroup(ObjectId threadId);
226char* dvmDbgGetThreadGroupName(ObjectId threadGroupId);
227ObjectId dvmDbgGetThreadGroupParent(ObjectId threadGroupId);
228ObjectId dvmDbgGetSystemThreadGroupId(void);
229ObjectId dvmDbgGetMainThreadGroupId(void);
230
231bool dvmDbgGetThreadStatus(ObjectId threadId, u4* threadStatus,
232 u4* suspendStatus);
233u4 dvmDbgGetThreadSuspendCount(ObjectId threadId);
234bool dvmDbgThreadExists(ObjectId threadId);
235bool dvmDbgIsSuspended(ObjectId threadId);
236//void dvmDbgWaitForSuspend(ObjectId threadId);
237void dvmDbgGetThreadGroupThreads(ObjectId threadGroupId,
238 ObjectId** ppThreadIds, u4* pThreadCount);
239void dvmDbgGetAllThreads(ObjectId** ppThreadIds, u4* pThreadCount);
240int dvmDbgGetThreadFrameCount(ObjectId threadId);
241bool dvmDbgGetThreadFrame(ObjectId threadId, int num, FrameId* pFrameId,
242 JdwpLocation* pLoc);
243
244ObjectId dvmDbgGetThreadSelfId(void);
245void dvmDbgSuspendVM(bool isEvent);
246void dvmDbgResumeVM(void);
247void dvmDbgSuspendThread(ObjectId threadId);
248void dvmDbgResumeThread(ObjectId threadId);
249void dvmDbgSuspendSelf(void);
250
251bool dvmDbgGetThisObject(ObjectId threadId, FrameId frameId, ObjectId* pThisId);
252void dvmDbgGetLocalValue(ObjectId threadId, FrameId frameId, int slot,
253 u1 tag, u1* buf, int expectedLen);
254void dvmDbgSetLocalValue(ObjectId threadId, FrameId frameId, int slot,
255 u1 tag, u8 value, int width);
256
257
258/*
259 * Debugger notification
260 */
261void dvmDbgPostLocationEvent(const struct Method* method, int pcOffset,
262 struct Object* thisPtr, int eventFlags);
263void dvmDbgPostException(void* throwFp, int throwRelPc, void* catchFp,
264 int catchRelPc, struct Object* exception);
265void dvmDbgPostThreadStart(struct Thread* thread);
266void dvmDbgPostThreadDeath(struct Thread* thread);
267void dvmDbgPostClassPrepare(struct ClassObject* clazz);
268// FieldAccess, FieldModification
269
270/* for "eventFlags" */
271enum {
272 DBG_BREAKPOINT = 0x01,
273 DBG_SINGLE_STEP = 0x02,
274 DBG_METHOD_ENTRY = 0x04,
275 DBG_METHOD_EXIT = 0x08,
276};
277
278bool dvmDbgWatchLocation(const JdwpLocation* pLoc);
279void dvmDbgUnwatchLocation(const JdwpLocation* pLoc);
280bool dvmDbgConfigureStep(ObjectId threadId, enum JdwpStepSize size,
281 enum JdwpStepDepth depth);
282void dvmDbgUnconfigureStep(ObjectId threadId);
283
284JdwpError dvmDbgInvokeMethod(ObjectId threadId, ObjectId objectId,
285 RefTypeId classId, MethodId methodId, u4 numArgs, u8* argArray,
286 u4 options, u1* pResultTag, u8* pResultValue, ObjectId* pExceptObj);
287void dvmDbgExecuteMethod(DebugInvokeReq* pReq);
288
289/* Make an AddressSet for a line, for single stepping */
290const AddressSet *dvmAddressSetForLine(const struct Method* method, int line);
291
292/*
293 * DDM support.
294 */
295bool dvmDbgDdmHandlePacket(const u1* buf, int dataLen, u1** pReplyBuf,
296 int* pReplyLen);
297void dvmDbgDdmConnected(void);
298void dvmDbgDdmDisconnected(void);
299void dvmDbgDdmSendChunk(int type, int len, const u1* buf);
300
301#define CHUNK_TYPE(_name) \
302 ((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3])
303
304#endif /*_DALVIK_DEBUGGER*/