OSDN Git Service

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