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