From b3b61a83e2ad74d9b37441b508890904e2cc2bc7 Mon Sep 17 00:00:00 2001
From: cperkonig <cperkonig>
Date: Wed, 11 Feb 2004 22:07:16 +0000
Subject: [PATCH] modification to debug on a remote server

---
 .../phpdt/internal/debug/core/PHPDBGInterface.java |   26 ++-
 .../phpdt/internal/debug/core/PHPDBGProxy.java     |  229 ++++++++++++++------
 2 files changed, 184 insertions(+), 71 deletions(-)

diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java
index 80682b8..0f574b7 100644
--- a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java
+++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java
@@ -7,6 +7,7 @@ http://www.eclipse.org/legal/cpl-v10.html
 
 Contributors:
 	Vicente Fernando - www.alfersoft.com.ar - Initial implementation
+	Christian Perkonig - remote debug
 **********************************************************************/
 package net.sourceforge.phpdt.internal.debug.core;
 
@@ -47,6 +48,9 @@ public class PHPDBGInterface {
 	private String className= new String("");
 	private int finalPos=0, refCounter=0, rawCounter=1000;
 	private PHPDBGProxy proxy= null;
+
+	private int lastCmd=-1;
+	private int sid=0;
 	private boolean stopOnError= false;
 	private char[] lastCommand= new char[4];
 	 
@@ -203,6 +207,21 @@ public class PHPDBGInterface {
 		}
 		return BPUnder;
 	}
+	
+	public int getLastCmd()
+	{
+		return lastCmd;
+	}
+	
+	public int getSID()
+	{
+	  return sid;
+  }
+	
+	public void setLastCmd(int cmd)
+	{
+		lastCmd=cmd;
+	}
 
 	public void stepInto() throws IOException {
 		BPUnderHit= 0;
@@ -619,6 +638,7 @@ public class PHPDBGInterface {
 			if(dbg_header_struct[0] != 0x5953) return 0;
 			
 			cmdReceived= dbg_header_struct[1];
+			setLastCmd(cmdReceived);
 			bytesToRead= dbg_header_struct[3];
 
 			//System.out.println("Response Received: " + cmdReceived);
@@ -796,6 +816,7 @@ public class PHPDBGInterface {
 					case PHPDBGBase.FRAME_VER:
 						break;
 					case PHPDBGBase.FRAME_SID:
+					  sid = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);
 						break;
 					case PHPDBGBase.FRAME_SRCLINESINFO:
 						break;
@@ -876,12 +897,13 @@ public class PHPDBGInterface {
 		this.shouldStop= true;
 	}
 
-	public void waitResponse(long milliseconds) throws IOException {
+	public boolean waitResponse(long milliseconds) throws IOException {
 		long timeout= System.currentTimeMillis() + milliseconds;
 		while(System.currentTimeMillis() < timeout) {
 			if(in.ready() || shouldStop) {
 				break;
 			}
 		}
+		return in.ready();
 	}
-}
\ No newline at end of file
+}
diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGProxy.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGProxy.java
index feb5325..5c1f627 100644
--- a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGProxy.java
+++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGProxy.java
@@ -8,6 +8,7 @@ http://www.eclipse.org/legal/cpl-v10.html
 Contributors:
 	IBM Corporation - Initial implementation
 	Vicente Fernando - www.alfersoft.com.ar
+	Christian Perkonig - remote debug
 **********************************************************************/
 package net.sourceforge.phpdt.internal.debug.core;
 
@@ -17,8 +18,11 @@ import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.net.Socket;
 import java.net.ServerSocket;
+import java.net.SocketTimeoutException;
 
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
 import org.eclipse.debug.core.DebugPlugin;
 import org.eclipse.debug.core.DebugException;
 import org.eclipse.debug.core.model.IBreakpoint;
@@ -39,11 +43,19 @@ public class PHPDBGProxy {
 	private PHPThread PHPMainThread;
 	private PHPDBGProxy thisProxy= null;
 	private int port;
+	private boolean remote;
+	private IPath remoteSourcePath;
 
 	public PHPDBGProxy() {
 		thisProxy= this;
 	}
 
+	public PHPDBGProxy(boolean remote,String remoteSourcePath) {
+		thisProxy= this;
+		this.remote=remote;
+		this.remoteSourcePath= new Path(remoteSourcePath);
+	}
+
 	public void start() {
 		createServerSocket();
 		this.startPHPLoop();
@@ -52,10 +64,12 @@ public class PHPDBGProxy {
 	public void stop() {
 		phpLoop.setShouldStop();
 		if(DBGInt != null) DBGInt.setShouldStop();
-		try {
-			getDebugTarget().getProcess().terminate();
-		} catch (DebugException e) {
-			e.printStackTrace();
+		if (!remote) {
+			try {
+				getDebugTarget().getProcess().terminate();
+			} catch (DebugException e) {
+				e.printStackTrace();
+			}
 		}
 		phpLoop.notifyWait();
 	}
@@ -68,7 +82,8 @@ public class PHPDBGProxy {
 	}
 
 	protected void createServerSocket() {
-		port = SocketUtil.findUnusedLocalPort("localhost", 10001, 10101);
+//		port = SocketUtil.findUnusedLocalPort("localhost", 10001, 10101);
+    port = 	10001;
 		if (port == -1) {
 			PHPDebugCorePlugin.log(5, "Cannot find free port!!!!");
 			return;
@@ -99,6 +114,13 @@ public class PHPDBGProxy {
 		}
 		return reader;
 	}
+	
+	public BufferedReader getReader(Socket socket) throws IOException {
+		if (socket != null)
+		  return new BufferedReader(new InputStreamReader(socket.getInputStream(), "ISO8859_1"));
+		else
+		  return null;
+	}
 
 	public OutputStream getOutputStream() throws IOException {
 		return this.getSocket().getOutputStream();
@@ -117,8 +139,14 @@ public class PHPDBGProxy {
 		try {
 			PHPLineBreakpoint phpLBP;
 			if(breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getDefault().getDescriptor().getUniqueIdentifier()) {
+				IPath filename;
 				phpLBP= (PHPLineBreakpoint)breakpoint;
-				bpNo= DBGInt.addBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber());
+				//				bpNo= DBGInt.addBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber());
+				if (remote)
+					filename=remoteSourcePath.append(phpLBP.getMarker().getResource().getProjectRelativePath());
+				else
+					filename=phpLBP.getMarker().getResource().getLocation();
+				bpNo= DBGInt.addBreakpoint(filename.toOSString(), phpLBP.getLineNumber());
 				phpLBP.setDBGBpNo(bpNo);
 			}
 		} catch (IOException e) {
@@ -136,7 +164,13 @@ public class PHPDBGProxy {
 			PHPLineBreakpoint phpLBP;
 			if(breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getDefault().getDescriptor().getUniqueIdentifier()) {
 				phpLBP= (PHPLineBreakpoint)breakpoint;
-				DBGInt.removeBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber(), phpLBP.getDBGBpNo());
+				IPath filename;
+				if (remote)
+					filename=remoteSourcePath.append(phpLBP.getMarker().getResource().getProjectRelativePath());
+				else
+					filename=phpLBP.getMarker().getResource().getLocation();
+//					bpNo= DBGInt.addBreakpoint(filename.toOSString(), phpLBP.getLineNumber());				
+				DBGInt.removeBreakpoint(filename.toOSString(), phpLBP.getLineNumber(), phpLBP.getDBGBpNo());
 			}
 		} catch (IOException e) {
 			PHPDebugCorePlugin.log(e);
@@ -146,6 +180,10 @@ public class PHPDBGProxy {
 			stop();
 		}
 	}
+	
+	public void phpLoopNotify (){
+		phpLoop.notifyWait();
+	}
 
 	public void startPHPLoop() {
 		phpLoop = new PHPLoop();
@@ -278,77 +316,130 @@ public class PHPDBGProxy {
 			try {
 				char[] buf= new char[16];
 				int i, pos, timeout;
-				long interval= 1000*20;
+				long interval= 200; // 200ms
 				String line;
 				PHPStackFrame[] StackList;
+				boolean endFile=false;
+				boolean newconnect=false;
+				Socket newSocket=null;
+				PHPDBGInterface newDBGInt;
+				int sid=-1;
 				
-				//System.out.println("Waiting for breakpoints.");			
-				try{
-					socket = server.accept();
-					//System.out.println("Accepted! : " + socket.toString());
-				} catch (IOException e) {
-					PHPDebugCorePlugin.log(e);
-					return;			
-				}
+//				synchronized (this) {
+//					wait();
+//				}
 				
-				PHPMainThread= new PHPThread(getDebugTarget(), getPort());
+				PHPMainThread = new PHPThread(getDebugTarget(), getPort());
 				PHPMainThread.setName("Thread [main]");
-				timeout= 0;
-				while((getDebugTarget() == null) && (timeout < 100)) {
-					sleep(100);
-					timeout++;
-				}
+				timeout = 0;
+				
+//				while ((getDebugTarget() == null) && (timeout < 100)) {
+//					sleep(100);
+//					timeout++;
+//				}
 				// Be sure debug target is set
-				PHPMainThread.setDebugTarget(getDebugTarget());
+//				PHPMainThread.setDebugTarget(getDebugTarget());
 				getDebugTarget().addThread(PHPMainThread);
-				setDBGInterface(new PHPDBGInterface(getReader(), getOutputStream(), thisProxy));
-
-				DBGInt.waitResponse(1000);
-				DBGInt.flushAllPackets();
-
-				// Check version and session ID
-				setBreakPoints();
-				DBGInt.continueExecution();
-
-				while (!shouldStop) {
-					DBGInt.waitResponse(interval);
-					DBGInt.flushAllPackets();
-
-					if (DBGInt.BPUnderHit != 0) {
-						StackList= DBGInt.getStackList();
-						if(StackList.length > 0) {
-							for(i=0; i < StackList.length; i++) {
-								StackList[i].setThread(PHPMainThread);
-								if(DBGInt.getModByNo(StackList[i].getModNo()).equals("")) {
-									DBGInt.getSourceTree();
-								}
-								StackList[i].setFile(DBGInt.getModByNo(StackList[i].getModNo()));
+				
+				//System.out.println("Waiting for breakpoints.");	
+				while (!shouldStop)	
+				{	
+					newconnect=true;
+	        try {
+ 	          newSocket = server.accept();
+ 	         //System.out.println("Accepted! : " + socket.toString());
+	        } catch (SocketTimeoutException e) {
+						// no one wants to connect
+						newconnect=false;
+ 	  	    } catch (IOException e) {
+  	        PHPDebugCorePlugin.log(e);
+    	      return;
+  	      }
+	
+					if (newconnect)
+					{
+						if (DBGInt==null)
+							server.setSoTimeout(1);
+					 	newDBGInt= new PHPDBGInterface(getReader(newSocket), newSocket.getOutputStream(), thisProxy);
+						newDBGInt.waitResponse(1000);
+        	  newDBGInt.flushAllPackets();
+						// Check version and session ID
+        	  if ((DBGInt==null) || (DBGInt.getSID()==newDBGInt.getSID()))
+        	  {
+        	  	DBGInt=newDBGInt;
+							try	{
+								closeSocket();
+							}	catch (IOException e) {
+								PHPDebugCorePlugin.log(e);
+								shouldStop=true;
 							}
-							PHPMainThread.setStackFrames(StackList);
-						}
-						// Fire debug event
-						PHPMainThread.suspend();
-
-						synchronized(this) {
-							wait();
-						}
-					}					
-					if(PHPMainThread.isTerminated() || getDebugTarget().getProcess().isTerminated()) break;
+        	  	socket=newSocket;
+							setBreakPoints();
+							DBGInt.continueExecution();        	  	
+        	  } else
+        	  {
+							newDBGInt.continueExecution();
+        	  	newSocket.close();
+        	  }
+					}
+
+        	if(DBGInt.waitResponse(interval))
+        	{
+        	
+          	DBGInt.flushAllPackets();
+
+          	if (DBGInt.BPUnderHit != 0) {
+          		StackList = DBGInt.getStackList();
+           		if (StackList.length > 0) {
+             		for (i = 0; i < StackList.length; i++) {
+               		StackList[i].setThread(PHPMainThread);
+               		if (DBGInt.getModByNo(StackList[i].getModNo()).equals("")) {
+                 		DBGInt.getSourceTree();
+               		}
+               		StackList[i].setFile(
+                 		DBGInt.getModByNo(StackList[i].getModNo()));
+             		}
+             		PHPMainThread.setStackFrames(StackList);
+           		}
+           		// Fire debug event
+           		PHPMainThread.suspend();
+
+           		synchronized (this) {
+	             	wait();
+           		}
+          	}
+        	}
+          if (remote) {
+          	if (PHPMainThread.isTerminated())
+          	{
+          		shouldStop=true;
+          		break;
+          	}
+          } else {
+          	if (PHPMainThread.isTerminated() || getDebugTarget().getProcess().isTerminated())
+          	{
+							shouldStop=true;
+							break;             	 
+          	}
+          }
 				}
-			} catch (Exception ex) {
-				PHPDebugCorePlugin.log(ex);
-				System.out.println(ex);
-			} finally {
-				try {
-					getDebugTarget().terminate();
-					closeSocket();
-					closeServerSocket();
-				} catch (IOException e) {
-					PHPDebugCorePlugin.log(e);
-					return;
-				}
-				//System.out.println("Socket loop finished.");
-			}
+    	} 
+    	catch (Exception ex) {
+      	PHPDebugCorePlugin.log(ex);
+      	System.out.println(ex);
+    	} 
+    	finally {
+     		try {
+      		getDebugTarget().terminate();
+      		closeSocket();
+      		closeServerSocket();
+     		}
+     		catch (IOException e) {
+      		PHPDebugCorePlugin.log(e);
+      		return;
+      	}
+        //System.out.println("Socket loop finished.");
+    	}
 		}
 	}
 }
-- 
1.7.1