• 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  * JDWP "public" interface.  The main body of the VM should only use JDWP
18  * structures and functions declared here.
19  *
20  * The JDWP code follows the DalvikVM rules for naming conventions, but
21  * attempts to remain independent of VM innards (e.g. it doesn't access VM
22  * data structures directly).  All calls go through Debugger.c.
23  */
24 #ifndef DALVIK_JDWP_JDWP_H_
25 #define DALVIK_JDWP_JDWP_H_
26 
27 #include "jdwp/JdwpConstants.h"
28 #include "jdwp/ExpandBuf.h"
29 #include "Common.h"
30 #include "Bits.h"
31 #include <pthread.h>
32 
33 struct JdwpState;       /* opaque */
34 
35 /*
36  * Fundamental types.
37  *
38  * ObjectId and RefTypeId must be the same size.
39  */
40 typedef u4 FieldId;     /* static or instance field */
41 typedef u4 MethodId;    /* any kind of method, including constructors */
42 typedef u8 ObjectId;    /* any object (threadID, stringID, arrayID, etc) */
43 typedef u8 RefTypeId;   /* like ObjectID, but unique for Class objects */
44 typedef u8 FrameId;     /* short-lived stack frame ID */
45 
46 /*
47  * Match these with the type sizes.  This way we don't have to pass
48  * a value and a length.
49  */
dvmReadFieldId(const u1 ** pBuf)50 INLINE FieldId dvmReadFieldId(const u1** pBuf)      { return read4BE(pBuf); }
dvmReadMethodId(const u1 ** pBuf)51 INLINE MethodId dvmReadMethodId(const u1** pBuf)    { return read4BE(pBuf); }
dvmReadObjectId(const u1 ** pBuf)52 INLINE ObjectId dvmReadObjectId(const u1** pBuf)    { return read8BE(pBuf); }
dvmReadRefTypeId(const u1 ** pBuf)53 INLINE RefTypeId dvmReadRefTypeId(const u1** pBuf)  { return read8BE(pBuf); }
dvmReadFrameId(const u1 ** pBuf)54 INLINE FrameId dvmReadFrameId(const u1** pBuf)      { return read8BE(pBuf); }
dvmSetFieldId(u1 * buf,FieldId val)55 INLINE void dvmSetFieldId(u1* buf, FieldId val)     { return set4BE(buf, val); }
dvmSetMethodId(u1 * buf,MethodId val)56 INLINE void dvmSetMethodId(u1* buf, MethodId val)   { return set4BE(buf, val); }
dvmSetObjectId(u1 * buf,ObjectId val)57 INLINE void dvmSetObjectId(u1* buf, ObjectId val)   { return set8BE(buf, val); }
dvmSetRefTypeId(u1 * buf,RefTypeId val)58 INLINE void dvmSetRefTypeId(u1* buf, RefTypeId val) { return set8BE(buf, val); }
dvmSetFrameId(u1 * buf,FrameId val)59 INLINE void dvmSetFrameId(u1* buf, FrameId val)     { return set8BE(buf, val); }
expandBufAddFieldId(ExpandBuf * pReply,FieldId id)60 INLINE void expandBufAddFieldId(ExpandBuf* pReply, FieldId id) {
61     expandBufAdd4BE(pReply, id);
62 }
expandBufAddMethodId(ExpandBuf * pReply,MethodId id)63 INLINE void expandBufAddMethodId(ExpandBuf* pReply, MethodId id) {
64     expandBufAdd4BE(pReply, id);
65 }
expandBufAddObjectId(ExpandBuf * pReply,ObjectId id)66 INLINE void expandBufAddObjectId(ExpandBuf* pReply, ObjectId id) {
67     expandBufAdd8BE(pReply, id);
68 }
expandBufAddRefTypeId(ExpandBuf * pReply,RefTypeId id)69 INLINE void expandBufAddRefTypeId(ExpandBuf* pReply, RefTypeId id) {
70     expandBufAdd8BE(pReply, id);
71 }
expandBufAddFrameId(ExpandBuf * pReply,FrameId id)72 INLINE void expandBufAddFrameId(ExpandBuf* pReply, FrameId id) {
73     expandBufAdd8BE(pReply, id);
74 }
75 
76 
77 /*
78  * Holds a JDWP "location".
79  */
80 struct JdwpLocation {
81     u1          typeTag;        /* class or interface? */
82     RefTypeId   classId;        /* method->clazz */
83     MethodId    methodId;       /* method in which "idx" resides */
84     u8          idx;            /* relative index into code block */
85 };
86 
87 /*
88  * How we talk to the debugger.
89  */
90 enum JdwpTransportType {
91     kJdwpTransportUnknown = 0,
92     kJdwpTransportSocket,       /* transport=dt_socket */
93     kJdwpTransportAndroidAdb,   /* transport=dt_android_adb */
94 };
95 
96 /*
97  * Holds collection of JDWP initialization parameters.
98  */
99 struct JdwpStartupParams {
100     JdwpTransportType transport;
101     bool        server;
102     bool        suspend;
103     char        host[64];
104     short       port;
105     /* more will be here someday */
106 };
107 
108 /*
109  * Perform one-time initialization.
110  *
111  * Among other things, this binds to a port to listen for a connection from
112  * the debugger.
113  *
114  * Returns a newly-allocated JdwpState struct on success, or NULL on failure.
115  */
116 JdwpState* dvmJdwpStartup(const JdwpStartupParams* params);
117 
118 /*
119  * Shut everything down.
120  */
121 void dvmJdwpShutdown(JdwpState* state);
122 
123 /*
124  * Returns "true" if a debugger or DDM is connected.
125  */
126 bool dvmJdwpIsActive(JdwpState* state);
127 
128 /*
129  * Return the debugger thread's handle, or 0 if the debugger thread isn't
130  * running.
131  */
132 pthread_t dvmJdwpGetDebugThread(JdwpState* state);
133 
134 /*
135  * Get time, in milliseconds, since the last debugger activity.
136  */
137 s8 dvmJdwpLastDebuggerActivity(JdwpState* state);
138 
139 /*
140  * When we hit a debugger event that requires suspension, it's important
141  * that we wait for the thread to suspend itself before processing any
142  * additional requests.  (Otherwise, if the debugger immediately sends a
143  * "resume thread" command, the resume might arrive before the thread has
144  * suspended itself.)
145  *
146  * The thread should call the "set" function before sending the event to
147  * the debugger.  The main JDWP handler loop calls "get" before processing
148  * an event, and will wait for thread suspension if it's set.  Once the
149  * thread has suspended itself, the JDWP handler calls "clear" and
150  * continues processing the current event.  This works in the suspend-all
151  * case because the event thread doesn't suspend itself until everything
152  * else has suspended.
153  *
154  * It's possible that multiple threads could encounter thread-suspending
155  * events at the same time, so we grab a mutex in the "set" call, and
156  * release it in the "clear" call.
157  */
158 //ObjectId dvmJdwpGetWaitForEventThread(JdwpState* state);
159 void dvmJdwpSetWaitForEventThread(JdwpState* state, ObjectId threadId);
160 void dvmJdwpClearWaitForEventThread(JdwpState* state);
161 
162 /*
163  * Network functions.
164  */
165 bool dvmJdwpCheckConnection(JdwpState* state);
166 bool dvmJdwpAcceptConnection(JdwpState* state);
167 bool dvmJdwpEstablishConnection(JdwpState* state);
168 void dvmJdwpCloseConnection(JdwpState* state);
169 bool dvmJdwpProcessIncoming(JdwpState* state);
170 
171 
172 /*
173  * These notify the debug code that something interesting has happened.  This
174  * could be a thread starting or ending, an exception, or an opportunity
175  * for a breakpoint.  These calls do not mean that an event the debugger
176  * is interested has happened, just that something has happened that the
177  * debugger *might* be interested in.
178  *
179  * The item of interest may trigger multiple events, some or all of which
180  * are grouped together in a single response.
181  *
182  * The event may cause the current thread or all threads (except the
183  * JDWP support thread) to be suspended.
184  */
185 
186 /*
187  * The VM has finished initializing.  Only called when the debugger is
188  * connected at the time initialization completes.
189  */
190 bool dvmJdwpPostVMStart(JdwpState* state, bool suspend);
191 
192 /*
193  * A location of interest has been reached.  This is used for breakpoints,
194  * single-stepping, and method entry/exit.  (JDWP requires that these four
195  * events are grouped together in a single response.)
196  *
197  * In some cases "*pLoc" will just have a method and class name, e.g. when
198  * issuing a MethodEntry on a native method.
199  *
200  * "eventFlags" indicates the types of events that have occurred.
201  */
202 bool dvmJdwpPostLocationEvent(JdwpState* state, const JdwpLocation* pLoc,
203     ObjectId thisPtr, int eventFlags);
204 
205 /*
206  * An exception has been thrown.
207  *
208  * Pass in a zeroed-out "*pCatchLoc" if the exception wasn't caught.
209  */
210 bool dvmJdwpPostException(JdwpState* state, const JdwpLocation* pThrowLoc,
211     ObjectId excepId, RefTypeId excepClassId, const JdwpLocation* pCatchLoc,
212     ObjectId thisPtr);
213 
214 /*
215  * A thread has started or stopped.
216  */
217 bool dvmJdwpPostThreadChange(JdwpState* state, ObjectId threadId, bool start);
218 
219 /*
220  * Class has been prepared.
221  */
222 bool dvmJdwpPostClassPrepare(JdwpState* state, int tag, RefTypeId refTypeId,
223     const char* signature, int status);
224 
225 /*
226  * The VM is about to stop.
227  */
228 bool dvmJdwpPostVMDeath(JdwpState* state);
229 
230 /*
231  * Send up a chunk of DDM data.
232  */
233 void dvmJdwpDdmSendChunkV(JdwpState* state, int type, const struct iovec* iov,
234     int iovcnt);
235 
236 #endif  // DALVIK_JDWP_JDWP_H_
237