예제 #1
0
        /// <summary>
        /// Chunk handler entry point.
        /// </summary>
        internal override void handleChunk(Client client, int type, ByteBuffer data, bool isReply, int msgId)
		{

			Log.d("ddm-prof", "handling " + ChunkHandler.name(type));

			if (type == CHUNK_MPRE)
			{
				handleMPRE(client, data);
			}
			else if (type == CHUNK_MPSE)
			{
				handleMPSE(client, data);
			}
			else if (type == CHUNK_MPRQ)
			{
				handleMPRQ(client, data);
			}
			else if (type == CHUNK_FAIL)
			{
				handleFAIL(client, data);
			}
			else
			{
				handleUnknownChunk(client, type, data, isReply, msgId);
			}
		}
예제 #2
0
        /// <summary>
        /// Chunk handler entry point.
        /// </summary>
        internal override void handleChunk(Client client, int type, ByteBuffer data, bool isReply, int msgId)
		{

			Log.d("ddm-nativeheap", "handling " + ChunkHandler.name(type));

			if (type == CHUNK_NHGT)
			{
				handleNHGT(client, data);
			}
			else if (type == CHUNK_NHST)
			{
				// start chunk before any NHSG chunk(s)
				client.clientData.nativeHeapData.clearHeapData();
			}
			else if (type == CHUNK_NHEN)
			{
				// end chunk after NHSG chunk(s)
				client.clientData.nativeHeapData.sealHeapData();
			}
			else if (type == CHUNK_NHSG)
			{
				handleNHSG(client, data);
			}
			else
			{
				handleUnknownChunk(client, type, data, isReply, msgId);
			}

			client.update(Client.CHANGE_NATIVE_HEAP_DATA);
		}
예제 #3
0
        /// <summary>
        /// Chunk handler entry point.
        /// </summary>
        internal override void handleChunk(Client client, int type, ByteBuffer data, bool isReply, int msgId)
		{

			Log.d("ddm-thread", "handling " + ChunkHandler.name(type));

			if (type == CHUNK_THCR)
			{
				handleTHCR(client, data);
			}
			else if (type == CHUNK_THDE)
			{
				handleTHDE(client, data);
			}
			else if (type == CHUNK_THST)
			{
				handleTHST(client, data);
			}
			else if (type == CHUNK_THNM)
			{
				handleTHNM(client, data);
			}
			else if (type == CHUNK_STKL)
			{
				handleSTKL(client, data);
			}
			else
			{
				handleUnknownChunk(client, type, data, isReply, msgId);
			}
		}
예제 #4
0
		/// <summary>
		/// Client is ready.
		/// </summary>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void clientReady(Client client) throws java.io.IOException
		internal override void clientReady(Client client)
		{
			if (client.heapUpdateEnabled)
			{
				//sendHPSG(client, WHEN_GC, WHAT_MERGE);
				sendHPIF(client, HPIF_WHEN_EVERY_GC);
			}
		}
예제 #5
0
		/// <summary>
		/// Client is ready.
		/// </summary>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void clientReady(Client client) throws java.io.IOException
		internal override void clientReady(Client client)
		{
			Log.d("ddm-thread", "Now ready: " + client);
			if (client.threadUpdateEnabled)
			{
				sendTHEN(client, true);
			}
		}
예제 #6
0
		/*
		 * Handle a thread creation message.
		 */
		private void handleTEST(Client client, ByteBuffer data)
		{
			/*
			 * Can't call data.array() on a read-only ByteBuffer, so we make
			 * a copy.
			 */
			var copy = new byte[data.limit];
			data.get(copy);

			Log.d("ddm-test", "Received:");
			Log.hexDump("ddm-test", Log.LogLevel.DEBUG, copy, 0, copy.Length);
		}
예제 #7
0
		/// <summary>
		/// Send an EXIT request to the client.
		/// </summary>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public static void sendEXIT(Client client, int status) throws java.io.IOException
		public static void sendEXIT(Client client, int status)
		{
			ByteBuffer rawBuf = allocBuffer(4);
			JdwpPacket packet = new JdwpPacket(rawBuf);
			ByteBuffer buf = getChunkDataBuf(rawBuf);

			buf.putInt(status);

			finishChunkPacket(packet, CHUNK_EXIT, buf.position);
			Log.d("ddm-exit", "Sending " + name(CHUNK_EXIT) + ": " + status);
			client.sendAndConsume(packet, mInst);
		}
예제 #8
0
        /// <summary>
        /// Chunk handler entry point.
        /// </summary>
        internal override void handleChunk(Client client, int type, ByteBuffer data, bool isReply, int msgId)
		{

			Log.d("ddm-test", "handling " + ChunkHandler.name(type));

			if (type == CHUNK_TEST)
			{
				handleTEST(client, data);
			}
			else
			{
				handleUnknownChunk(client, type, data, isReply, msgId);
			}
		}
예제 #9
0
        /// <summary>
        /// Chunk handler entry point.
        /// </summary>
        internal override void handleChunk(Client client, int type, ByteBuffer data, bool isReply, int msgId)
		{

			Log.d("ddm-appname", "handling " + ChunkHandler.name(type));

			if (type == CHUNK_APNM)
			{
				Debug.Assert(!isReply);
				handleAPNM(client, data);
			}
			else
			{
				handleUnknownChunk(client, type, data, isReply, msgId);
			}
		}
예제 #10
0
		/*
		 * Handle a reply to our WAIT message.
		 */
		private static void handleWAIT(Client client, ByteBuffer data)
		{
		    var reason = data.get();

			Log.d("ddm-wait", "WAIT: reason=" + reason);


			ClientData cd = client.clientData;
			lock (cd)
			{
				cd.debuggerConnectionStatus = ClientData.DebuggerStatus.WAITING;
			}

			client.update(Client.CHANGE_DEBUGGER_STATUS);
		}
예제 #11
0
		/// <summary>
		/// Handle chunks not recognized by handlers.  The handleChunk() method
		/// in sub-classes should call this if the chunk type isn't recognized.
		/// </summary>
		protected internal virtual void handleUnknownChunk(Client client, int type, ByteBuffer data, bool isReply, int msgId)
		{
			if (type == CHUNK_FAIL)
			{
				int errorCode, msgLen;
				string msg;

                errorCode = data.getInt();
                msgLen = data.getInt();
				msg = getString(data, msgLen);
				Log.w("ddms", "WARNING: failure code=" + errorCode + " msg=" + msg);
			}
			else
			{
				Log.w("ddms", "WARNING: received unknown chunk " + name(type) + ": len=" + data.limit + ", reply=" + isReply + ", msgId=0x" + msgId.toHexString());
			}
			Log.w("ddms", "         client " + client + ", handler " + this);
		}
예제 #12
0
		/// <summary>
		/// Create a new Debugger object, configured to listen for connections
		/// on a specific port.
		/// </summary>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: Debugger(Client client, int listenPort) throws java.io.IOException
		internal Debugger(Client client, int listenPort)
		{

			mClient = client;
			mListenPort = listenPort;

			mListenChannel = ServerSocketChannel.open();
			mListenChannel.configureBlocking(false); // required for Selector

			var addr = new DnsEndPoint("localhost", listenPort); //$NON-NLS-1$
			mListenChannel.socket().ExclusiveAddressUse = false; // .reuseAddress = true; // enable SO_REUSEADDR
			mListenChannel.socket().Bind(addr);

			mReadBuffer = ByteBuffer.allocate(INITIAL_BUF_SIZE);
			mPreDataBuffer = ByteBuffer.allocate(PRE_DATA_BUF_SIZE);
			mConnState = ST_NOT_CONNECTED;

			Log.d("ddms", "Created: " + this.ToString());
		}
예제 #13
0
		/// <summary>
		/// Chunk handler entry point.
		/// </summary>
		internal override void handleChunk(Client client, int type, ByteBuffer data, bool isReply, int msgId)
		{

			Log.d("ddm-hello", "handling " + ChunkHandler.name(type));

			if (type == CHUNK_HELO)
			{
				Debug.Assert(isReply);
				handleHELO(client, data);
			}
			else if (type == CHUNK_FEAT)
			{
				handleFEAT(client, data);
			}
			else
			{
				handleUnknownChunk(client, type, data, isReply, msgId);
			}
		}
예제 #14
0
		/*
		 * Handle a reply to our APNM message.
		 */
		private static void handleAPNM(Client client, ByteBuffer data)
		{
			int appNameLen;
			string appName;

            appNameLen = data.getInt();
			appName = getString(data, appNameLen);

			Log.d("ddm-appname", "APNM: app='" + appName + "'");

			ClientData cd = client.clientData;
			lock (cd)
			{
				cd.clientDescription = appName;
			}

			client = checkDebuggerPortForAppName(client, appName);

			if (client != null)
			{
				client.update(Client.CHANGE_NAME);
			}
		}
예제 #15
0
		/// <summary>
		/// Sends HELLO-type commands to the VM after a good handshake. </summary>
		/// <param name="client"> </param>
		/// <param name="serverProtocolVersion"> </param>
		/// <exception cref="IOException"> </exception>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public static void sendHelloCommands(Client client, int serverProtocolVersion) throws java.io.IOException
		public static void sendHelloCommands(Client client, int serverProtocolVersion)
		{
			sendHELO(client, serverProtocolVersion);
			sendFEAT(client);
			HandleProfiling.sendMPRQ(client);
		}
예제 #16
0
		/// <summary>
		/// Client went away.
		/// </summary>
		internal override void clientDisconnected(Client client)
		{
			Log.d("ddm-hello", "Now disconnected: " + client);
		}
예제 #17
0
		/// <summary>
		/// Client is ready.
		/// </summary>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void clientReady(Client client) throws java.io.IOException
		internal override void clientReady(Client client)
		{
			Log.d("ddm-hello", "Now ready: " + client);
		}
예제 #18
0
		/// <summary>
		/// Send a FEAT request to the client.
		/// </summary>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public static void sendFEAT(Client client) throws java.io.IOException
		public static void sendFEAT(Client client)
		{
			ByteBuffer rawBuf = allocBuffer(0);
			JdwpPacket packet = new JdwpPacket(rawBuf);
			ByteBuffer buf = getChunkDataBuf(rawBuf);

			// no data

			finishChunkPacket(packet, CHUNK_FEAT, buf.position);
			Log.d("ddm-heap", "Sending " + name(CHUNK_FEAT));
			client.sendAndConsume(packet, mInst);
		}
예제 #19
0
		/// <summary>
		/// Handle a reply to our FEAT request.
		/// </summary>
		private static void handleFEAT(Client client, ByteBuffer data)
		{
			int featureCount;
			int i;

            featureCount = data.getInt();
			for (i = 0; i < featureCount; i++)
			{
                int len = data.getInt();
				string feature = getString(data, len);
				client.clientData.addFeature(feature);

				Log.d("ddm-hello", "Feature: " + feature);
			}
		}
예제 #20
0
		/// <summary>
		/// Send a HELO request to the client.
		/// </summary>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public static void sendHELO(Client client, int serverProtocolVersion) throws java.io.IOException
		public static void sendHELO(Client client, int serverProtocolVersion)
		{
			ByteBuffer rawBuf = allocBuffer(4);
			JdwpPacket packet = new JdwpPacket(rawBuf);
			ByteBuffer buf = getChunkDataBuf(rawBuf);

			buf.putInt(serverProtocolVersion);

			finishChunkPacket(packet, CHUNK_HELO, buf.position);
			Log.d("ddm-hello", "Sending " + name(CHUNK_HELO) + " ID=0x" + packet.id.toHexString());
			client.sendAndConsume(packet, mInst);
		}
예제 #21
0
		/// <summary>
		/// Client is ready.  The monitor thread calls this method on all
		/// handlers when the client is determined to be DDM-aware (usually
		/// after receiving a HELO response.)
		/// 
		/// The handler can use this opportunity to initialize client-side
		/// activity.  Because there's a fair chance we'll want to send a
		/// message to the client, this method can throw an IOException.
		/// </summary>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: abstract void clientReady(Client client) throws java.io.IOException;
		internal abstract void clientReady(Client client);
예제 #22
0
		/*
		 * Handle the response from our REcent Allocation Query message.
		 */
		private void handleREAQ(Client client, ByteBuffer data)
		{
			bool enabled;

			enabled = (data.get() != 0);
			Log.d("ddm-heap", "REAQ says: enabled=" + enabled);

			client.clientData.allocationStatus = enabled ? ClientData.AllocationTrackingStatus.ON : ClientData.AllocationTrackingStatus.OFF;
			client.update(Client.CHANGE_HEAP_ALLOCATION_STATUS);
		}
예제 #23
0
        /// <summary>
        /// Client went away.
        /// </summary>
        internal override void clientDisconnected(Client client)
		{
		}
예제 #24
0
		/// <summary>
		/// Client is ready.
		/// </summary>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void clientReady(Client client) throws java.io.IOException
		internal override void clientReady(Client client)
		{
		}
예제 #25
0
		/*
		 * Handle a REcent ALlocation response.
		 *
		 * Message header (all values big-endian):
		 *   (1b) message header len (to allow future expansion); includes itself
		 *   (1b) entry header len
		 *   (1b) stack frame len
		 *   (2b) number of entries
		 *   (4b) offset to string table from start of message
		 *   (2b) number of class name strings
		 *   (2b) number of method name strings
		 *   (2b) number of source file name strings
		 *   For each entry:
		 *     (4b) total allocation size
		 *     (2b) threadId
		 *     (2b) allocated object's class name index
		 *     (1b) stack depth
		 *     For each stack frame:
		 *       (2b) method's class name
		 *       (2b) method name
		 *       (2b) method source file
		 *       (2b) line number, clipped to 32767; -2 if native; -1 if no source
		 *   (xb) class name strings
		 *   (xb) method name strings
		 *   (xb) source file strings
		 *
		 *   As with other DDM traffic, strings are sent as a 4-byte length
		 *   followed by UTF-16 data.
		 */
		private void handleREAL(Client client, ByteBuffer data)
		{
			Log.e("ddm-heap", "*** Received " + name(CHUNK_REAL));
			int messageHdrLen, entryHdrLen, stackFrameLen;
			int numEntries, offsetToStrings;
			int numClassNames, numMethodNames, numFileNames;

			/*
			 * Read the header.
			 */
			messageHdrLen = (data.get() & 0xff);
			entryHdrLen = (data.get() & 0xff);
			stackFrameLen = (data.get() & 0xff);
			numEntries = (data.getShort() & 0xffff);
            offsetToStrings = data.getInt();
			numClassNames = (data.getShort() & 0xffff);
			numMethodNames = (data.getShort()& 0xffff);
			numFileNames = (data.getShort()& 0xffff);


			/*
			 * Skip forward to the strings and read them.
			 */
			data.position = offsetToStrings;

			string[] classNames = new string[numClassNames];
			string[] methodNames = new string[numMethodNames];
			string[] fileNames = new string[numFileNames];

			readStringTable(data, classNames);
			readStringTable(data, methodNames);
			//System.out.println("METHODS: "
			//    + java.util.Arrays.deepToString(methodNames));
			readStringTable(data, fileNames);

			/*
			 * Skip back to a point just past the header and start reading
			 * entries.
			 */
			data.position = messageHdrLen;

			List<AllocationInfo> list = new List<AllocationInfo>(numEntries);
			int allocNumber = numEntries; // order value for the entry. This is sent in reverse order.
			for (int i = 0; i < numEntries; i++)
			{
				int totalSize;
				int threadId, classNameIndex, stackDepth;

                totalSize = data.getInt();
				threadId = (data.getShort() & 0xffff);
				classNameIndex = (data.getShort() & 0xffff);
				stackDepth = (data.get() & 0xff);
				/* we've consumed 9 bytes; gobble up any extra */
				for (int skip = 9; skip < entryHdrLen; skip++)
				{
					data.get();
				}

				StackTraceElement[] steArray = new StackTraceElement[stackDepth];

				/*
				 * Pull out the stack trace.
				 */
				for (int sti = 0; sti < stackDepth; sti++)
				{
					int methodClassNameIndex, methodNameIndex;
					int methodSourceFileIndex;
					short lineNumber;
					string methodClassName, methodName, methodSourceFile;

					methodClassNameIndex = (data.getShort() & 0xffff);
					methodNameIndex = (data.getShort()& 0xffff);
					methodSourceFileIndex = (data.getShort()& 0xffff);
					lineNumber = data.getShort();

					methodClassName = classNames[methodClassNameIndex];
					methodName = methodNames[methodNameIndex];
					methodSourceFile = fileNames[methodSourceFileIndex];

					steArray[sti] = new StackTraceElement(methodClassName, methodName, methodSourceFile, lineNumber);

					/* we've consumed 8 bytes; gobble up any extra */
					for (int skip = 9; skip < stackFrameLen; skip++)
					{
						data.get();
					}
				}

				list.Add(new AllocationInfo(allocNumber--, classNames[classNameIndex], totalSize, (short) threadId, steArray));
			}

			client.clientData.allocations = list.ToArray();
			client.update(Client.CHANGE_HEAP_ALLOCATIONS);
		}
예제 #26
0
        /// <summary>
        /// Chunk handler entry point.
        /// </summary>
        internal override void handleChunk(Client client, int type, ByteBuffer data, bool isReply, int msgId)
		{
			Log.d("ddm-heap", "handling " + ChunkHandler.name(type));

			if (type == CHUNK_HPIF)
			{
				handleHPIF(client, data);
			}
			else if (type == CHUNK_HPST)
			{
				handleHPST(client, data);
			}
			else if (type == CHUNK_HPEN)
			{
				handleHPEN(client, data);
			}
			else if (type == CHUNK_HPSG)
			{
				handleHPSG(client, data);
			}
			else if (type == CHUNK_HPDU)
			{
				handleHPDU(client, data);
			}
			else if (type == CHUNK_HPDS)
			{
				handleHPDS(client, data);
			}
			else if (type == CHUNK_REAQ)
			{
				handleREAQ(client, data);
			}
			else if (type == CHUNK_REAL)
			{
				handleREAL(client, data);
			}
			else
			{
				handleUnknownChunk(client, type, data, isReply, msgId);
			}
		}
예제 #27
0
		/// <summary>
		/// Client has gone away.  Can be used to clean up any resources
		/// associated with this client connection.
		/// </summary>
		internal abstract void clientDisconnected(Client client);
예제 #28
0
		/*
		 * Handle a reply to our HELO message.
		 */
		private static void handleHELO(Client client, ByteBuffer data)
		{
			int version, pid, vmIdentLen, appNameLen;
			string vmIdent, appName;

            version = data.getInt();
            pid = data.getInt();
            vmIdentLen = data.getInt();
            appNameLen = data.getInt();

			vmIdent = getString(data, vmIdentLen);
			appName = getString(data, appNameLen);

			Log.d("ddm-hello", "HELO: v=" + version + ", pid=" + pid + ", vm='" + vmIdent + "', app='" + appName + "'");

			ClientData cd = client.clientData;

			lock (cd)
			{
				if (cd.pid == pid)
				{
					cd.vmIdentifier = vmIdent;
					cd.clientDescription = appName;
					cd.isDdmAware(true);
				}
				else
				{
					Log.e("ddm-hello", "Received pid (" + pid + ") does not match client pid (" + cd.pid + ")");
				}
			}

			client = checkDebuggerPortForAppName(client, appName);

			if (client != null)
			{
				client.update(Client.CHANGE_NAME);
			}
		}
예제 #29
0
		/// <summary>
		/// Handle an incoming chunk.  The data, of chunk type "type", begins
		/// at the start of "data" and continues to data.limit().
		/// 
		/// If "isReply" is set, then "msgId" will be the ID of the request
		/// we sent to the client.  Otherwise, it's the ID generated by the
		/// client for this event.  Note that it's possible to receive chunks
		/// in reply packets for which we are not registered.
		/// 
		/// The handler may not modify the contents of "data".
		/// </summary>
		internal abstract void handleChunk(Client client, int type, ByteBuffer data, bool isReply, int msgId);
예제 #30
0
		/// <summary>
		/// Check that the client is opened with the proper debugger port for the
		/// specified application name, and if not, reopen it. </summary>
		/// <param name="client"> </param>
		/// <param name="uiThread"> </param>
		/// <param name="appName">
		/// @return </param>
		protected internal static Client checkDebuggerPortForAppName(Client client, string appName)
		{
			DebugPortManager.IDebugPortProvider provider = DebugPortManager.provider;
			if (provider != null)
			{
				Device device = client.deviceImpl;
				int newPort = provider.getPort(device, appName);

				if (newPort != DebugPortManager.DebugPortProvider.NO_STATIC_PORT && newPort != client.debuggerListenPort)
				{

					AndroidDebugBridge bridge = AndroidDebugBridge.bridge;
					if (bridge != null)
					{
						DeviceMonitor deviceMonitor = bridge.deviceMonitor;
						if (deviceMonitor != null)
						{
							deviceMonitor.addClientToDropAndReopen(client, newPort);
							client = null;
						}
					}
				}
			}

			return client;
		}