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