OSDN Git Service

Merge change 24840 into eclair
[android-x86/dalvik.git] / vm / Debugger.h
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 */
29 struct Object;
30 struct ClassObject;
31 struct Method;
32 struct Thread;
33
34 /*
35  * used by StepControl to track a set of addresses associated with
36  * a single line.
37  */
38 typedef struct AddressSet {
39     u4 setSize;
40     u1 set[1];
41 } AddressSet;
42
43 INLINE void dvmAddressSetSet(AddressSet *pSet, u4 toSet)
44 {
45     if (toSet < pSet->setSize) {
46         pSet->set[toSet/8] |= 1 << (toSet % 8);
47     }
48 }
49
50 INLINE 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  */
62 typedef 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  */
79 typedef 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 */
107 bool dvmDebuggerStartup(void);
108 void dvmDebuggerShutdown(void);
109
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);
117
118 /*
119  * Return the DebugInvokeReq for the current thread.
120  */
121 DebugInvokeReq* dvmDbgGetInvokeReq(void);
122
123 /*
124  * Enable/disable breakpoints and step modes.  Used to provide a heads-up
125  * when the debugger attaches.
126  */
127 void dvmDbgConnected(void);
128 void dvmDbgActive(void);
129 void dvmDbgDisconnected(void);
130
131 /*
132  * Returns "true" if a debugger is connected.  Returns "false" if it's
133  * just DDM.
134  */
135 bool 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  */
142 s8 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  */
149 int dvmDbgThreadRunning(void);
150 int dvmDbgThreadWaiting(void);
151 int dvmDbgThreadContinuing(int status);
152
153 /*
154  * The debugger wants the VM to exit.
155  */
156 void dvmDbgExit(int status);
157
158 /*
159  * Class, Object, Array
160  */
161 const char* dvmDbgGetClassDescriptor(RefTypeId id);
162 RefTypeId dvmDbgGetSuperclass(RefTypeId id);
163 ObjectId dvmDbgGetClassLoader(RefTypeId id);
164 u4 dvmDbgGetAccessFlags(RefTypeId id);
165 bool dvmDbgIsInterface(RefTypeId id);
166 void dvmDbgGetClassList(u4* pNumClasses, RefTypeId** pClassRefBuf);
167 void dvmDbgGetVisibleClassList(ObjectId classLoaderId, u4* pNumClasses,
168         RefTypeId** pClassRefBuf);
169 void dvmDbgGetClassInfo(RefTypeId classId, u1* pTypeTag, u4* pStatus,
170     char** pSignature);
171 bool dvmDbgFindLoadedClassBySignature(const char* classDescriptor,
172         RefTypeId* pRefTypeId);
173 void dvmDbgGetObjectType(ObjectId objectId, u1* pRefTypeTag,
174     RefTypeId* pRefTypeId);
175 u1 dvmDbgGetClassObjectType(RefTypeId refTypeId);
176 char* dvmDbgGetSignature(RefTypeId refTypeId);
177 const char* dvmDbgGetSourceFile(RefTypeId refTypeId);
178 char* dvmDbgGetObjectTypeName(ObjectId objectId);
179 int dvmDbgGetSignatureTag(const char* signature);
180 int dvmDbgGetObjectTag(ObjectId objectId, const char* type);
181 int dvmDbgGetTagWidth(int tag);
182
183 int dvmDbgGetArrayLength(ObjectId arrayId);
184 int dvmDbgGetArrayElementTag(ObjectId arrayId);
185 bool dvmDbgOutputArray(ObjectId arrayId, int firstIndex, int count,
186     ExpandBuf* pReply);
187 bool dvmDbgSetArrayElements(ObjectId arrayId, int firstIndex, int count,
188     const u1* buf);
189
190 ObjectId dvmDbgCreateString(const char* str);
191
192 bool dvmDbgMatchType(RefTypeId instClassId, RefTypeId classId);
193
194 /*
195  * Method and Field
196  */
197 const char* dvmDbgGetMethodName(RefTypeId refTypeId, MethodId id);
198 void dvmDbgOutputAllFields(RefTypeId refTypeId, bool withGeneric,
199     ExpandBuf* pReply);
200 void dvmDbgOutputAllMethods(RefTypeId refTypeId, bool withGeneric,
201     ExpandBuf* pReply);
202 void dvmDbgOutputAllInterfaces(RefTypeId refTypeId, ExpandBuf* pReply);
203 void dvmDbgOutputLineTable(RefTypeId refTypeId, MethodId methodId,
204     ExpandBuf* pReply);
205 void dvmDbgOutputVariableTable(RefTypeId refTypeId, MethodId id,
206     bool withGeneric, ExpandBuf* pReply);
207
208 int dvmDbgGetFieldTag(ObjectId objId, FieldId fieldId);
209 int dvmDbgGetStaticFieldTag(RefTypeId refTypeId, FieldId fieldId);
210 void dvmDbgGetFieldValue(ObjectId objId, FieldId fieldId, u1* ptr, int width);
211 void dvmDbgSetFieldValue(ObjectId objectId, FieldId fieldId, u8 value,
212     int width);
213 void dvmDbgGetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId, u1* ptr,
214     int width);
215 void dvmDbgSetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId,
216     u8 rawValue, int width);
217
218 char* dvmDbgStringToUtf8(ObjectId strId);
219
220 /*
221  * Thread, ThreadGroup, Frame
222  */
223 char* dvmDbgGetThreadName(ObjectId threadId);
224 ObjectId dvmDbgGetThreadGroup(ObjectId threadId);
225 char* dvmDbgGetThreadGroupName(ObjectId threadGroupId);
226 ObjectId dvmDbgGetThreadGroupParent(ObjectId threadGroupId);
227 ObjectId dvmDbgGetSystemThreadGroupId(void);
228 ObjectId dvmDbgGetMainThreadGroupId(void);
229
230 bool dvmDbgGetThreadStatus(ObjectId threadId, u4* threadStatus,
231     u4* suspendStatus);
232 u4 dvmDbgGetThreadSuspendCount(ObjectId threadId);
233 bool dvmDbgThreadExists(ObjectId threadId);
234 bool dvmDbgIsSuspended(ObjectId threadId);
235 //void dvmDbgWaitForSuspend(ObjectId threadId);
236 void dvmDbgGetThreadGroupThreads(ObjectId threadGroupId,
237     ObjectId** ppThreadIds, u4* pThreadCount);
238 void dvmDbgGetAllThreads(ObjectId** ppThreadIds, u4* pThreadCount);
239 int dvmDbgGetThreadFrameCount(ObjectId threadId);
240 bool dvmDbgGetThreadFrame(ObjectId threadId, int num, FrameId* pFrameId,
241     JdwpLocation* pLoc);
242
243 ObjectId dvmDbgGetThreadSelfId(void);
244 void dvmDbgSuspendVM(bool isEvent);
245 void dvmDbgResumeVM(void);
246 void dvmDbgSuspendThread(ObjectId threadId);
247 void dvmDbgResumeThread(ObjectId threadId);
248 void dvmDbgSuspendSelf(void);
249
250 bool dvmDbgGetThisObject(ObjectId threadId, FrameId frameId, ObjectId* pThisId);
251 void dvmDbgGetLocalValue(ObjectId threadId, FrameId frameId, int slot,
252     u1 tag, u1* buf, int expectedLen);
253 void dvmDbgSetLocalValue(ObjectId threadId, FrameId frameId, int slot,
254     u1 tag, u8 value, int width);
255
256
257 /*
258  * Debugger notification
259  */
260 void dvmDbgPostLocationEvent(const struct Method* method, int pcOffset,
261     struct Object* thisPtr, int eventFlags);
262 void dvmDbgPostException(void* throwFp, int throwRelPc, void* catchFp,
263     int catchRelPc, struct Object* exception);
264 void dvmDbgPostThreadStart(struct Thread* thread);
265 void dvmDbgPostThreadDeath(struct Thread* thread);
266 void dvmDbgPostClassPrepare(struct ClassObject* clazz);
267 // FieldAccess, FieldModification
268
269 /* for "eventFlags" */
270 enum {
271     DBG_BREAKPOINT      = 0x01,
272     DBG_SINGLE_STEP     = 0x02,
273     DBG_METHOD_ENTRY    = 0x04,
274     DBG_METHOD_EXIT     = 0x08,
275 };
276
277 bool dvmDbgWatchLocation(const JdwpLocation* pLoc);
278 void dvmDbgUnwatchLocation(const JdwpLocation* pLoc);
279 bool dvmDbgConfigureStep(ObjectId threadId, enum JdwpStepSize size,
280     enum JdwpStepDepth depth);
281 void dvmDbgUnconfigureStep(ObjectId threadId);
282
283 JdwpError dvmDbgInvokeMethod(ObjectId threadId, ObjectId objectId,
284     RefTypeId classId, MethodId methodId, u4 numArgs, u8* argArray,
285     u4 options, u1* pResultTag, u8* pResultValue, ObjectId* pExceptObj);
286 void dvmDbgExecuteMethod(DebugInvokeReq* pReq);
287
288 /* Make an AddressSet for a line, for single stepping */
289 const AddressSet *dvmAddressSetForLine(const struct Method* method, int line);
290
291 /*
292  * DDM support.
293  */
294 bool dvmDbgDdmHandlePacket(const u1* buf, int dataLen, u1** pReplyBuf,
295     int* pReplyLen);
296 void dvmDbgDdmConnected(void);
297 void dvmDbgDdmDisconnected(void);
298 void dvmDbgDdmSendChunk(int type, int len, const u1* buf);
299
300 #define CHUNK_TYPE(_name) \
301     ((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3])
302
303 #endif /*_DALVIK_DEBUGGER*/