blob: 262e1106bba0f2bb5ca8379a3d892e54b73d5470 [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 */
Andy McFadden96516932009-10-28 17:39:02 -070016
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080017/*
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 */
30struct Object;
31struct ClassObject;
32struct Method;
33struct Thread;
34
buzbeecb3081f2011-01-14 13:37:31 -080035#define DEBUGGER_ACTIVE (gDvm.interpBreak & kSubModeDebuggerActive)
36
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080037/*
Andy McFadden96516932009-10-28 17:39:02 -070038 * Used by StepControl to track a set of addresses associated with
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080039 * a single line.
40 */
41typedef struct AddressSet {
42 u4 setSize;
43 u1 set[1];
44} AddressSet;
45
46INLINE void dvmAddressSetSet(AddressSet *pSet, u4 toSet)
47{
48 if (toSet < pSet->setSize) {
49 pSet->set[toSet/8] |= 1 << (toSet % 8);
50 }
51}
52
53INLINE 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 */
65typedef 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 */
82typedef 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 */
110bool dvmDebuggerStartup(void);
111void dvmDebuggerShutdown(void);
112
113void dvmDbgInitMutex(pthread_mutex_t* pMutex);
114void dvmDbgLockMutex(pthread_mutex_t* pMutex);
115void dvmDbgUnlockMutex(pthread_mutex_t* pMutex);
116void dvmDbgInitCond(pthread_cond_t* pCond);
117void dvmDbgCondWait(pthread_cond_t* pCond, pthread_mutex_t* pMutex);
118void dvmDbgCondSignal(pthread_cond_t* pCond);
119void dvmDbgCondBroadcast(pthread_cond_t* pCond);
120
121/*
122 * Return the DebugInvokeReq for the current thread.
123 */
124DebugInvokeReq* dvmDbgGetInvokeReq(void);
125
126/*
127 * Enable/disable breakpoints and step modes. Used to provide a heads-up
128 * when the debugger attaches.
129 */
130void dvmDbgConnected(void);
131void dvmDbgActive(void);
132void dvmDbgDisconnected(void);
133
134/*
135 * Returns "true" if a debugger is connected. Returns "false" if it's
136 * just DDM.
137 */
138bool 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 */
145s8 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 */
152int dvmDbgThreadRunning(void);
153int dvmDbgThreadWaiting(void);
154int dvmDbgThreadContinuing(int status);
155
156/*
157 * The debugger wants the VM to exit.
158 */
159void dvmDbgExit(int status);
160
161/*
162 * Class, Object, Array
163 */
164const char* dvmDbgGetClassDescriptor(RefTypeId id);
Andy McFadden6ff3c8f2009-10-13 13:06:03 -0700165ObjectId dvmDbgGetClassObject(RefTypeId id);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800166RefTypeId dvmDbgGetSuperclass(RefTypeId id);
167ObjectId dvmDbgGetClassLoader(RefTypeId id);
168u4 dvmDbgGetAccessFlags(RefTypeId id);
169bool dvmDbgIsInterface(RefTypeId id);
170void dvmDbgGetClassList(u4* pNumClasses, RefTypeId** pClassRefBuf);
171void dvmDbgGetVisibleClassList(ObjectId classLoaderId, u4* pNumClasses,
172 RefTypeId** pClassRefBuf);
173void dvmDbgGetClassInfo(RefTypeId classId, u1* pTypeTag, u4* pStatus,
Andy McFadden09709762011-03-18 14:27:06 -0700174 const char** pSignature);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800175bool dvmDbgFindLoadedClassBySignature(const char* classDescriptor,
176 RefTypeId* pRefTypeId);
177void dvmDbgGetObjectType(ObjectId objectId, u1* pRefTypeTag,
178 RefTypeId* pRefTypeId);
179u1 dvmDbgGetClassObjectType(RefTypeId refTypeId);
Andy McFadden09709762011-03-18 14:27:06 -0700180const char* dvmDbgGetSignature(RefTypeId refTypeId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800181const char* dvmDbgGetSourceFile(RefTypeId refTypeId);
Andy McFadden09709762011-03-18 14:27:06 -0700182const char* dvmDbgGetObjectTypeName(ObjectId objectId);
183u1 dvmDbgGetObjectTag(ObjectId objectId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800184int dvmDbgGetTagWidth(int tag);
185
186int dvmDbgGetArrayLength(ObjectId arrayId);
Andy McFadden09709762011-03-18 14:27:06 -0700187u1 dvmDbgGetArrayElementTag(ObjectId arrayId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800188bool dvmDbgOutputArray(ObjectId arrayId, int firstIndex, int count,
189 ExpandBuf* pReply);
190bool dvmDbgSetArrayElements(ObjectId arrayId, int firstIndex, int count,
191 const u1* buf);
192
193ObjectId dvmDbgCreateString(const char* str);
Andy McFaddenf50c6d52009-10-02 15:56:26 -0700194ObjectId dvmDbgCreateObject(RefTypeId classId);
Andy McFadden884cd422010-07-19 13:51:36 -0700195ObjectId dvmDbgCreateArrayObject(RefTypeId arrayTypeId, u4 length);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800196
197bool dvmDbgMatchType(RefTypeId instClassId, RefTypeId classId);
198
199/*
200 * Method and Field
201 */
202const char* dvmDbgGetMethodName(RefTypeId refTypeId, MethodId id);
203void dvmDbgOutputAllFields(RefTypeId refTypeId, bool withGeneric,
204 ExpandBuf* pReply);
205void dvmDbgOutputAllMethods(RefTypeId refTypeId, bool withGeneric,
206 ExpandBuf* pReply);
207void dvmDbgOutputAllInterfaces(RefTypeId refTypeId, ExpandBuf* pReply);
208void dvmDbgOutputLineTable(RefTypeId refTypeId, MethodId methodId,
209 ExpandBuf* pReply);
210void dvmDbgOutputVariableTable(RefTypeId refTypeId, MethodId id,
211 bool withGeneric, ExpandBuf* pReply);
212
Andy McFadden09709762011-03-18 14:27:06 -0700213u1 dvmDbgGetFieldBasicTag(ObjectId objId, FieldId fieldId);
214u1 dvmDbgGetStaticFieldBasicTag(RefTypeId refTypeId, FieldId fieldId);
215void dvmDbgGetFieldValue(ObjectId objectId, FieldId fieldId, ExpandBuf* pReply);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800216void dvmDbgSetFieldValue(ObjectId objectId, FieldId fieldId, u8 value,
217 int width);
Andy McFadden09709762011-03-18 14:27:06 -0700218void dvmDbgGetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId,
219 ExpandBuf* pReply);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800220void dvmDbgSetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId,
221 u8 rawValue, int width);
222
223char* dvmDbgStringToUtf8(ObjectId strId);
224
225/*
226 * Thread, ThreadGroup, Frame
227 */
228char* dvmDbgGetThreadName(ObjectId threadId);
229ObjectId dvmDbgGetThreadGroup(ObjectId threadId);
230char* dvmDbgGetThreadGroupName(ObjectId threadGroupId);
231ObjectId dvmDbgGetThreadGroupParent(ObjectId threadGroupId);
232ObjectId dvmDbgGetSystemThreadGroupId(void);
233ObjectId dvmDbgGetMainThreadGroupId(void);
234
235bool dvmDbgGetThreadStatus(ObjectId threadId, u4* threadStatus,
236 u4* suspendStatus);
237u4 dvmDbgGetThreadSuspendCount(ObjectId threadId);
238bool dvmDbgThreadExists(ObjectId threadId);
239bool dvmDbgIsSuspended(ObjectId threadId);
240//void dvmDbgWaitForSuspend(ObjectId threadId);
241void dvmDbgGetThreadGroupThreads(ObjectId threadGroupId,
242 ObjectId** ppThreadIds, u4* pThreadCount);
243void dvmDbgGetAllThreads(ObjectId** ppThreadIds, u4* pThreadCount);
244int dvmDbgGetThreadFrameCount(ObjectId threadId);
245bool dvmDbgGetThreadFrame(ObjectId threadId, int num, FrameId* pFrameId,
246 JdwpLocation* pLoc);
247
248ObjectId dvmDbgGetThreadSelfId(void);
249void dvmDbgSuspendVM(bool isEvent);
250void dvmDbgResumeVM(void);
251void dvmDbgSuspendThread(ObjectId threadId);
252void dvmDbgResumeThread(ObjectId threadId);
253void dvmDbgSuspendSelf(void);
254
255bool dvmDbgGetThisObject(ObjectId threadId, FrameId frameId, ObjectId* pThisId);
256void dvmDbgGetLocalValue(ObjectId threadId, FrameId frameId, int slot,
257 u1 tag, u1* buf, int expectedLen);
258void dvmDbgSetLocalValue(ObjectId threadId, FrameId frameId, int slot,
259 u1 tag, u8 value, int width);
260
261
262/*
263 * Debugger notification
264 */
265void dvmDbgPostLocationEvent(const struct Method* method, int pcOffset,
266 struct Object* thisPtr, int eventFlags);
267void dvmDbgPostException(void* throwFp, int throwRelPc, void* catchFp,
268 int catchRelPc, struct Object* exception);
269void dvmDbgPostThreadStart(struct Thread* thread);
270void dvmDbgPostThreadDeath(struct Thread* thread);
271void dvmDbgPostClassPrepare(struct ClassObject* clazz);
272// FieldAccess, FieldModification
273
274/* for "eventFlags" */
275enum {
276 DBG_BREAKPOINT = 0x01,
277 DBG_SINGLE_STEP = 0x02,
278 DBG_METHOD_ENTRY = 0x04,
279 DBG_METHOD_EXIT = 0x08,
280};
281
282bool dvmDbgWatchLocation(const JdwpLocation* pLoc);
283void dvmDbgUnwatchLocation(const JdwpLocation* pLoc);
284bool dvmDbgConfigureStep(ObjectId threadId, enum JdwpStepSize size,
285 enum JdwpStepDepth depth);
286void dvmDbgUnconfigureStep(ObjectId threadId);
287
288JdwpError dvmDbgInvokeMethod(ObjectId threadId, ObjectId objectId,
289 RefTypeId classId, MethodId methodId, u4 numArgs, u8* argArray,
290 u4 options, u1* pResultTag, u8* pResultValue, ObjectId* pExceptObj);
291void dvmDbgExecuteMethod(DebugInvokeReq* pReq);
292
293/* Make an AddressSet for a line, for single stepping */
294const AddressSet *dvmAddressSetForLine(const struct Method* method, int line);
295
Andy McFaddenc6e64ea2009-12-04 16:36:08 -0800296/* perform "late registration" of an object ID */
297void dvmDbgRegisterObjectId(ObjectId id);
298
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800299/*
300 * DDM support.
301 */
302bool dvmDbgDdmHandlePacket(const u1* buf, int dataLen, u1** pReplyBuf,
303 int* pReplyLen);
304void dvmDbgDdmConnected(void);
305void dvmDbgDdmDisconnected(void);
Andy McFadden01718122010-01-22 16:36:30 -0800306void dvmDbgDdmSendChunk(int type, size_t len, const u1* buf);
307void dvmDbgDdmSendChunkV(int type, const struct iovec* iov, int iovcnt);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800308
309#define CHUNK_TYPE(_name) \
310 ((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3])
311
312#endif /*_DALVIK_DEBUGGER*/