* Copyright (c) 2000, 2002 IBM Corp. and others. All rights reserved. This program and the accompanying materials are made
* available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at
* 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;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
+import java.util.Map;
+import java.util.Vector;
import net.sourceforge.phpdt.internal.debug.core.breakpoints.PHPLineBreakpoint;
-import net.sourceforge.phpdt.internal.debug.core.logview.LogView;
-import net.sourceforge.phpdt.internal.debug.core.model.IPHPDebugTarget;
+import net.sourceforge.phpdt.internal.debug.core.model.PHPDebugTarget;
import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
import net.sourceforge.phpdt.internal.debug.core.model.PHPThread;
import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
-import org.eclipse.ui.IViewPart;
-import org.eclipse.ui.IWorkbenchPage;
public class PHPDBGProxy {
- private ServerSocket server = null;
-
- private Socket socket;
-
- private BufferedReader reader = null;
-
- private PHPDBGInterface DBGInt = null;
-
- private IPHPDebugTarget debugTarget = null;
-
- private PHPLoop phpLoop;
-
- 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();
- }
-
- public void stop() {
- phpLoop.setShouldStop();
- if (DBGInt != null)
- DBGInt.setShouldStop();
- if (!remote) {
- try {
- getDebugTarget().getProcess().terminate();
- } catch (DebugException e) {
- e.printStackTrace();
- }
- }
- phpLoop.notifyWait();
- }
-
- protected ServerSocket getServerSocket() throws IOException {
- if (server == null) {
- createServerSocket();
- }
- return server;
- }
-
- protected void createServerSocket() {
- port = SocketUtil.findUnusedLocalPort("localhost", 10001, 10101);
-// port = 10001;
- if (port == -1) {
- PHPDebugCorePlugin.log(5, "Cannot find free port!!!!");
- return;
- }
- try {
- if (server == null) {
- server = new ServerSocket(port);
- //System.out.println("ServerSocket on port: " + port);
- }
- } catch (IOException e) {
- // IO Error
- PHPDebugCorePlugin.log(e);
- stop();
- }
- }
-
- public Socket getSocket() throws IOException {
- return socket;
- }
-
- protected void setDBGInterface(PHPDBGInterface DBGInt) {
- this.DBGInt = DBGInt;
- }
-
- public BufferedReader getReader() throws IOException {
- if (reader == null) {
- reader = new BufferedReader(new InputStreamReader(this.getSocket().getInputStream(), "ISO8859_1"));
- }
- 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();
- }
-
- protected void setBreakPoints() throws IOException, CoreException {
- IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints();
- for (int i = 0; i < breakpoints.length; i++) {
- addBreakpoint(breakpoints[i]);
- }
- }
-
- public void addBreakpoint(IBreakpoint breakpoint) {
- if (DBGInt == null)
- return;
- int bpNo = 0;
- try {
- PHPLineBreakpoint phpLBP;
- if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier()) {
- IPath filename;
- phpLBP = (PHPLineBreakpoint) breakpoint;
- // 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) {
- PHPDebugCorePlugin.log(e);
- stop();
- } catch (CoreException e) {
- PHPDebugCorePlugin.log(e);
- stop();
- }
- }
-
- public void removeBreakpoint(IBreakpoint breakpoint) {
- if (DBGInt == null)
- return;
- try {
- PHPLineBreakpoint phpLBP;
- if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier()) {
- phpLBP = (PHPLineBreakpoint) breakpoint;
- 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);
- stop();
- } catch (CoreException e) {
- PHPDebugCorePlugin.log(e);
- stop();
- }
- }
-
- public void phpLoopNotify() {
- phpLoop.notifyWait();
- }
-
- public void startPHPLoop() {
- phpLoop = new PHPLoop();
- phpLoop.start();
- }
-
- public void resume() {
- try {
- DBGInt.continueExecution();
- phpLoop.notifyWait();
- } catch (IOException e) {
- PHPDebugCorePlugin.log(e);
- stop();
- }
- }
-
- public void pause() {
- try {
- DBGInt.pauseExecution();
- } catch (IOException e) {
- PHPDebugCorePlugin.log(e);
- stop();
- }
- }
-
- protected IPHPDebugTarget getDebugTarget() {
- return debugTarget;
- }
-
- public void setDebugTarget(IPHPDebugTarget debugTarget) {
- this.debugTarget = debugTarget;
- debugTarget.setPHPDBGProxy(this);
- }
-
- public PHPVariable[] readVariables(PHPStackFrame frame) {
- try {
- return DBGInt.getVariables(frame);
- } catch (IOException ioex) {
- ioex.printStackTrace();
- throw new RuntimeException(ioex.getMessage());
- } catch (DebugException ex) {
- ex.printStackTrace();
- throw new RuntimeException(ex.getMessage());
- }
- }
-
- public PHPVariable[] eval(PHPStackFrame frame, String evalString) {
- try {
- return DBGInt.evalBlock(frame, evalString);
- // return DBGInt.getVariables(frame);
- } catch (IOException ioex) {
- ioex.printStackTrace();
- throw new RuntimeException(ioex.getMessage());
- } catch (DebugException ex) {
- ex.printStackTrace();
- throw new RuntimeException(ex.getMessage());
- }
- }
-
- public void readStepOverEnd(PHPStackFrame stackFrame) {
- try {
- DBGInt.stepOver();
- phpLoop.notifyWait();
- } catch (Exception e) {
- PHPDebugCorePlugin.log(e);
- }
- }
-
- public void readStepReturnEnd(PHPStackFrame stackFrame) {
- try {
- DBGInt.stepOut();
- phpLoop.notifyWait();
- } catch (Exception e) {
- PHPDebugCorePlugin.log(e);
- }
- }
-
- public void readStepIntoEnd(PHPStackFrame stackFrame) {
- try {
- DBGInt.stepInto();
- phpLoop.notifyWait();
- } catch (Exception e) {
- PHPDebugCorePlugin.log(e);
- }
- }
-
- /*
- * public PHPStackFrame[] readFrames(PHPThread thread) { //try { //this.println("th " + thread.getId() + " ; f "); //return new
- * FramesReader(getMultiReaderStrategy()).readFrames(thread); return null; //} catch (IOException e) { //
- * PHPDebugCorePlugin.log(e); // return null; //}
- * }
- */
-
- public void closeSocket() throws IOException {
- if (socket != null) {
- socket.close();
- }
- }
-
- public void closeServerSocket() throws IOException {
- if (server != null) {
- server.close();
- }
- }
-
- public int getPort() {
- return port;
- }
-
- class PHPLoop extends Thread {
- private boolean shouldStop;
-
- public PHPLoop() {
- shouldStop = false;
- this.setName("PHPDebuggerLoop");
- }
-
- public synchronized void setShouldStop() {
- shouldStop = true;
- }
-
- public synchronized void notifyWait() {
- notify();
- }
-
- public void run() {
- try {
- char[] buf = new char[16];
- int i, pos, timeout;
- long interval = 200; // 200ms
- String line;
- PHPStackFrame[] StackList;
- boolean endFile = false;
- boolean newconnect = false;
- Socket newSocket = null;
- PHPDBGInterface newDBGInt;
- int sid = -1;
-
- // synchronized (this) {
- // wait();
- // }
-
- PHPMainThread = new PHPThread(getDebugTarget(), getPort());
- PHPMainThread.setName("Thread [main]");
- timeout = 0;
-
- // while ((getDebugTarget() == null) && (timeout < 100)) {
- // sleep(100);
- // timeout++;
- // }
- // Be sure debug target is set
- // PHPMainThread.setDebugTarget(getDebugTarget());
- getDebugTarget().addThread(PHPMainThread);
-
- //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;
- }
- 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.");
- }
- }
- }
-}
\ No newline at end of file
+ private ServerSocket server = null;
+ private BufferedReader reader = null;
+ private PHPDBGInterface DBGInt = null; // The DBG interface which is linked with the proxy
+ private PHPDebugTarget debugTarget = null;
+ private PHPDBGProxy thisProxy = null;
+ private PHPLoop phpLoop;
+ private PHPThread PHPMainThread;
+ private Socket socket;
+ private int port;
+ private boolean remote;
+ private boolean pathtranslation;
+ private Map pathmap;
+ private IPath remoteSourcePath;
+
+ /**
+ */
+ public PHPDBGProxy () {
+ thisProxy = this;
+ }
+
+ /**
+ * @param remote
+ * @param remoteSourcePath
+ * @param pathTranslate
+ * @param paths
+ */
+ public PHPDBGProxy (boolean remote, String remoteSourcePath, boolean pathTranslate, Map paths) {
+ thisProxy = this;
+ this.remote = remote;
+ this.remoteSourcePath = new Path (remoteSourcePath);
+ this.pathmap = paths;
+ this.pathtranslation = pathTranslate;
+ }
+
+ /**
+ *
+ */
+ public void start () {
+ createServerSocket (); // Create a server socket for communicatio with DBG
+
+ this.startPHPLoop (); //
+ }
+
+ /**
+ *
+ */
+ public void stop () {
+ phpLoop.setShouldStop (); // Notify the thread's 'run loop' to stop
+
+ if (DBGInt != null) { // If we have a DBG interface linked with this proxy
+ DBGInt.setShouldStop (); // Notify the DBG interface to stop the waiting for response
+ }
+
+// if (!remote) { // If it's not a remote proxy session
+// try {
+// getDebugTarget ().getProcess ().terminate (); //
+// } catch (DebugException e) {
+// e.printStackTrace ();
+// }
+// }
+
+ phpLoop.notifyWait ();
+ }
+
+ public void setTerminated () {
+ try {
+ PHPMainThread.terminate ();
+ }
+ catch (DebugException e) {
+ }
+ }
+
+ /**
+ * TODO Is this method called from anywhere?
+ *
+ * Returns a already created server socket, or
+ * creates a server socket if none exists, and
+ * returns the newly created one.
+ *
+ * @return A server socket
+ */
+ protected ServerSocket getServerSocket () throws IOException {
+ if (server == null) { // Do we have already a server socket
+ createServerSocket (); // No, then create one
+ }
+
+ return server; // Return the server socket
+ }
+
+ /**
+ * Find a free unused port between 10001 and 10101 if the current debug session
+ * is for remote debugging, and a unused port 7869 if it is used as non remote debugging.
+ *
+ * For remote debugging the used port is submitted with the URL.
+ * E.g. http://localhost/index.php?DBGSESSID=1@localhost:10001
+ * For non remote debugging (if PHPeclipse used e.g. php cli directly) no port
+ * can be submitted by parameter, and only the default port (7869) can be used.
+ *
+ * @note: The free dbg version doesn't allow to set the appropriate port within php.ini!
+ *
+ *
+ */
+ protected void createServerSocket () {
+ if (this.remote) {
+ port = SocketUtil.findUnusedLocalPort ("localhost", 10001, 10101); // Get the first free port in the range from 10001 to 10101
+ }
+ else {
+ port = SocketUtil.findUnusedLocalPort ("localhost", 7869, 7869); // Get the first free port in the range from 7869 to 7869
+ }
+
+ if (port == -1) { // Did we get a free port?
+ PHPDebugCorePlugin.log (5, "Cannot find free port!!!!"); // No, output a error message
+
+ return; // And return
+ }
+ try {
+ if (server == null) { // If there is no server socket yet
+ server = new ServerSocket (port); // create a server socket for the free port
+ //System.out.println("ServerSocket on port: " + port);
+ }
+ } catch (IOException e) {
+ PHPDebugCorePlugin.log (e);
+ stop ();
+ }
+ }
+
+ /**
+ *
+ */
+ public Socket getSocket () throws IOException {
+ return socket; // Return the socket
+ }
+
+ /**
+ * Set the DBG interface which is linked to this proxy
+ *
+ * @paran DBGInt The DGB interface which is linked with this proxy
+ */
+ protected void setDBGInterface (PHPDBGInterface DBGInt) {
+ this.DBGInt = DBGInt;
+ }
+
+ /**
+ * Get the DBG interface which is linked to this proxy
+ *
+ * @paran DBGInt The DGB interface which is linked with this proxy
+ */
+ public PHPDBGInterface getDBGInterface () {
+ return DBGInt;
+ }
+
+ /**
+ * Give back a buffered input stream for the socket which is
+ * linked with this proxy
+ */
+ public BufferedReader getReader () throws IOException {
+ if (reader == null) { // Do we already have a buffered input stream
+ reader = new BufferedReader (new InputStreamReader (this.getSocket ().getInputStream (),
+ "ISO8859_1"));
+ }
+
+ return reader; // Return the buffered input stream
+ }
+
+ /**
+ *
+ */
+ public BufferedReader getReader (Socket socket) throws IOException {
+ if (socket != null) { // Is a socket provided
+ return new BufferedReader (new InputStreamReader (socket.getInputStream (),
+ "ISO8859_1")); // Then create a buffered input stream
+ }
+ else {
+ return null; // Without a socket we can't create a input stream
+ }
+ }
+
+ /**
+ *
+ * @return The output stream for this proxy's socket
+ */
+ public OutputStream getOutputStream () throws IOException {
+ return this.getSocket ().getOutputStream ();
+ }
+
+ /**
+ *
+ */
+ protected void setBreakPoints () throws IOException, CoreException {
+ IBreakpoint[] breakpoints = DebugPlugin.getDefault ().getBreakpointManager ().getBreakpoints ();
+
+ for (int i = 0; i < breakpoints.length; i++) {
+ if (breakpoints[i].isEnabled ()) {
+ addBreakpoint (breakpoints[i]);
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ private String MapPath (PHPLineBreakpoint phpLBP) {
+ IPath filename;
+ IPath remotePath;
+ IPath newpath;
+ IPath localPath;
+ String local;
+
+ if (remote) {
+ filename = phpLBP.getMarker().getResource().getProjectRelativePath();
+ filename = remoteSourcePath.append (filename);
+ } else {
+ filename = phpLBP.getMarker().getResource().getFullPath();
+ }
+
+ String path = filename.toOSString();
+
+ if ((pathmap != null) && remote) {
+ java.util.Iterator i = pathmap.keySet().iterator();
+
+ while (i.hasNext()) {
+ String k = (String) i.next();
+ if (path.startsWith(k)) {
+ path = pathmap.get(k) + path.substring(k.length());
+ break;
+ }
+ }
+ }
+
+ if (remoteSourcePath.isEmpty ()) {
+ if ((pathmap != null) && remote) {
+ java.util.Iterator iterator = pathmap.keySet().iterator();
+
+ while (iterator.hasNext ()) {
+ local = (String) iterator.next (); // Get the local/client side path of the mapping
+ remotePath = new Path ((String) pathmap.get (local)); // Get the remote/server side path of the mapping
+ localPath = new Path (local); // Get the remote/server side path of the mapping
+
+ if (localPath.isPrefixOf (filename)) { // Starts the remote/server side file path with the remote/server side mapping path
+ // dann prefix abh�ngen und den remote path davorh�gen
+ newpath = filename.removeFirstSegments (localPath.matchingFirstSegments (filename));
+ newpath = remotePath.append (newpath);
+ path = newpath.toString ();
+
+ if (path.substring (0, 1).equals ("/")) {
+ path = path.replace ('\\', '/');
+ }
+ else {
+ path = path.replace ('/', '\\');
+ }
+
+ return path;
+ }
+ }
+ }
+ }
+ else {
+ if (pathtranslation && remote) {
+ if (remoteSourcePath.toString ().substring (0, 1).equals ("/")) {
+ path = path.replace ('\\', '/');
+ }
+ else {
+ path = path.replace ('/', '\\');
+ }
+ }
+ }
+
+ return path;
+ }
+
+ /**
+ *
+ */
+ public void addBreakpoint (IBreakpoint breakpoint) {
+ if (DBGInt == null) {
+ return;
+ }
+
+ int bpNo = 0;
+
+ try {
+ PHPLineBreakpoint phpLBP;
+
+ if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier()) {
+ phpLBP = (PHPLineBreakpoint) breakpoint;
+
+ // bpNo= DBGInt.addBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber());
+ if (phpLBP.isConditionEnabled ()) {
+ bpNo = DBGInt.addBreakpoint (MapPath(phpLBP),
+ phpLBP.getLineNumber(),
+ phpLBP.getHitCount(),
+ phpLBP.getCondition ());
+ }
+ else {
+ bpNo = DBGInt.addBreakpoint (MapPath(phpLBP),
+ phpLBP.getLineNumber(),
+ phpLBP.getHitCount(),
+ "");
+ }
+
+ phpLBP.setDBGBpNo(bpNo);
+ }
+ } catch (IOException e) {
+ PHPDebugCorePlugin.log(e);
+ stop();
+ } catch (CoreException e) {
+ PHPDebugCorePlugin.log(e);
+ stop();
+ }
+ }
+
+ /**
+ *
+ */
+ public void removeBreakpoint (IBreakpoint breakpoint) {
+ if (DBGInt == null) {
+ return;
+ }
+
+ try {
+ PHPLineBreakpoint phpLBP;
+
+ if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier ()) {
+ phpLBP = (PHPLineBreakpoint) breakpoint;
+
+ // bpNo= DBGInt.addBreakpoint(filename.toOSString(), phpLBP.getLineNumber());
+
+ DBGInt.removeBreakpoint(MapPath(phpLBP), phpLBP.getLineNumber(), phpLBP.getDBGBpNo());
+ }
+ } catch (IOException e) {
+ PHPDebugCorePlugin.log (e);
+ stop ();
+ } catch (CoreException e) {
+ PHPDebugCorePlugin.log (e);
+ stop ();
+ }
+ }
+
+ /**
+ *
+ */
+ public void phpLoopNotify () {
+ phpLoop.notifyWait ();
+ }
+
+ /**
+ *
+ */
+ public void startPHPLoop () {
+ phpLoop = new PHPLoop (); // Create a DBG communication loop object
+
+ phpLoop.start (); // And start the communication loop
+ }
+
+ /**
+ *
+ */
+ public void resume () {
+ try {
+ DBGInt.continueExecution();
+ phpLoop.notifyWait();
+ } catch (IOException e) {
+ PHPeclipsePlugin.log("Debugging session ended.", e);
+ stop();
+ }
+ }
+
+ /**
+ *
+ */
+ public void pause () {
+ try {
+ if (null != DBGInt) {
+ DBGInt.pauseExecution();
+ }
+ else {
+ // TODO Make sure the Suspend action is grayed out
+ // when DBGInt is null
+ }
+ } catch (IOException e) {
+ PHPDebugCorePlugin.log (e);
+ stop ();
+ }
+ }
+
+ /**
+ *
+ */
+ protected PHPDebugTarget getDebugTarget() {
+ return debugTarget;
+ }
+
+ /**
+ * Is called by the DebuggerRunner
+ *
+ * @param debugTarget
+ */
+ public void setDebugTarget (PHPDebugTarget debugTarget) {
+ this.debugTarget = debugTarget;
+ debugTarget.setPHPDBGProxy(this);
+ }
+
+ /**
+ * This method is called by a stackframe.
+ * It reads the variables from PHP via DBG
+ *
+ * @param frame The stackframe which wants the variables.
+ * @return The list of variables for this stackframe.
+ */
+ public Vector readVariables (PHPStackFrame frame) {
+ try {
+ return DBGInt.getVariables (frame); // Get the variables from DBG interface
+ } catch (IOException ioex) {
+ ioex.printStackTrace ();
+ throw new RuntimeException (ioex.getMessage ());
+ } catch (DebugException ex) {
+ ex.printStackTrace ();
+ throw new RuntimeException (ex.getMessage ());
+ }
+ }
+
+ /**
+ *
+ * @param frame
+ * @param evalString
+ * @return
+ */
+ public PHPVariable[] eval (PHPStackFrame frame, String evalString) {
+ try {
+ return DBGInt.evalBlock (frame, evalString);
+ //return DBGInt.getVariables(frame);
+ } catch (IOException ioex) {
+ ioex.printStackTrace();
+ throw new RuntimeException(ioex.getMessage());
+ } catch (DebugException ex) {
+ ex.printStackTrace();
+ throw new RuntimeException(ex.getMessage());
+ }
+ }
+
+ public void readStepOverEnd (PHPStackFrame stackFrame) {
+ try {
+ DBGInt.stepOver();
+ phpLoop.notifyWait();
+ } catch (Exception e) {
+ PHPDebugCorePlugin.log(e);
+ }
+ }
+
+ public void readStepReturnEnd (PHPStackFrame stackFrame) {
+ try {
+ DBGInt.stepOut();
+ phpLoop.notifyWait();
+ } catch (Exception e) {
+ PHPDebugCorePlugin.log(e);
+ }
+ }
+
+ public void readStepIntoEnd (PHPStackFrame stackFrame) {
+ try {
+ DBGInt.stepInto();
+ phpLoop.notifyWait();
+ } catch (Exception e) {
+ PHPDebugCorePlugin.log(e);
+ }
+ }
+
+ /*
+ * public PHPStackFrame[] readFrames(PHPThread thread) { //try { //this.println("th " + thread.getId() + " ; f "); //return new
+ * FramesReader(getMultiReaderStrategy()).readFrames(thread); return null; //} catch (IOException e) { //
+ * PHPDebugCorePlugin.log(e); // return null; //}
+ * }
+ */
+
+ public void closeSocket() throws IOException {
+ if (socket != null) {
+ socket.close();
+ }
+ }
+
+ public void closeServerSocket() throws IOException {
+ if (server != null) {
+ server.close();
+ }
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ *
+ *
+ */
+ class PHPLoop extends Thread {
+ private boolean shouldStop;
+
+ public PHPLoop () {
+ shouldStop = false;
+ this.setName ("PHPDebuggerLoop");
+ }
+
+ /**
+ *
+ */
+ public synchronized void setShouldStop () {
+ shouldStop = true; // The run loop should stop
+
+ try {
+ // If the loop thread is blocked on the server socket,
+ // forcibly unblock it to avoid leaking the thread,
+ // the socket and the port
+ closeServerSocket ();
+ } catch (IOException x) {
+ // Log this as a warning?
+ PHPDebugCorePlugin.log (x);
+ }
+ }
+
+ /**
+ *
+ */
+ public synchronized void notifyWait () {
+ notify ();
+ }
+
+ /**
+ *
+ *
+ */
+ public void run () {
+ try {
+ int i;
+ int timeout;
+ long interval = 200; // Wait 200 ms maximum for a DBG response
+ boolean newconnect = false; //
+ Socket newSocket = null;
+ PHPStackFrame[] StackList;
+ PHPDBGInterface newDBGInt;
+
+ // synchronized (this) {
+ // wait();
+ // }
+
+ PHPMainThread = new PHPThread (getDebugTarget (), getPort ());
+ PHPMainThread.setName ("Thread [main]");
+ timeout = 0;
+
+ // while ((getDebugTarget() == null) && (timeout < 100)) {
+ // sleep(100);
+ // timeout++;
+ // }
+ // Be sure debug target is set
+ // PHPMainThread.setDebugTarget(getDebugTarget());
+
+ getDebugTarget ().addThread (PHPMainThread);
+
+ //System.out.println("Waiting for breakpoints.");
+
+ while (!shouldStop) { // As long as nobody will stop us
+ newconnect = true; // The first time
+
+ try {
+ newSocket = server.accept(); // Waits until DBG want to connect
+ //System.out.println("Accepted! : " + socket.toString());
+ } catch (SocketTimeoutException e) {
+ newconnect = false; // No one wants to connect (connection already done)
+ } catch (IOException e) {
+ PHPDebugCorePlugin.log(e);
+ return;
+ }
+
+ if (newconnect) { // Is it just after a new connection
+ if (DBGInt == null) { // Do we have a DBG interface?
+ server.setSoTimeout(1); // ???
+ }
+
+ newDBGInt = new PHPDBGInterface (getReader (newSocket), // Create a new interface
+ newSocket.getOutputStream (),
+ thisProxy);
+ newDBGInt.waitResponse (1000); // Wait for the initial DBG response
+ newDBGInt.flushAllPackets (); // Read and process the DBG response
+
+ // Check version and session ID
+ if ((DBGInt == null) || // If we have no interface
+ (DBGInt.getSID () == newDBGInt.getSID ())) {// or the new session ID is different to the old one
+ DBGInt = newDBGInt; // Set the new interface as current one
+
+ try {
+ closeSocket ();
+ }
+ catch (IOException e) {
+ PHPDebugCorePlugin.log (e);
+ shouldStop = true;
+ }
+
+ socket = newSocket;
+ setBreakPoints ();
+ DBGInt.continueExecution (); // Notify DBG that PHP should continue
+ }
+ else {
+ newDBGInt.continueExecution (); // Notify DBG that PHP should continue
+ newSocket.close ();
+ }
+ }
+
+ if (DBGInt.waitResponse (interval)) { // Wait for a DBG response (200 ms)
+ DBGInt.flushAllPackets (); // If we got something, read and process it
+
+ if (DBGInt.BPUnderHit != 0) { // ???
+ StackList = DBGInt.getStackList (); // Get the stack list from DBGInterface
+
+ if (StackList.length > 0) { // If there is something in stack list
+ for (i = 0; i < StackList.length; i++) { // For all stack list
+ StackList[i].setThread (PHPMainThread); // Set the PHPTread for all PHPStackFrames
+
+ if (DBGInt.getModByNo (StackList[i].getModNo ()).equals ("")) {
+ DBGInt.getSourceTree ();
+ }
+
+ StackList[i].setFile (DBGInt.getModByNo (StackList[i].getModNo ()));
+ }
+
+ PHPMainThread.setStackFrames (StackList);
+ }
+
+ PHPMainThread.suspend (); // Fire debug event
+
+ synchronized (this) {
+ wait ();
+ }
+ }
+ }
+
+ if (remote) {
+ if (PHPMainThread.isTerminated ()) {
+ shouldStop = true;
+
+ break; // Go for terminating the thread
+ }
+ } else {
+ if (PHPMainThread.isTerminated () ||
+ getDebugTarget ().getProcess ().isTerminated ()) {
+ shouldStop = true;
+
+ break; // Go for terminating the thread
+ }
+ }
+ }
+ } 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.");
+ }
+ }
+ }
+}