OSDN Git Service

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