1 /**********************************************************************
 
   2 Copyright (c) 2000, 2002 IBM Corp. and others.
 
   3 All rights reserved. This program and the accompanying materials
 
   4 are made available under the terms of the Common Public License v1.0
 
   5 which accompanies this distribution, and is available at
 
   6 http://www.eclipse.org/legal/cpl-v10.html
 
   9         IBM Corporation - Initial implementation
 
  10         Vicente Fernando - www.alfersoft.com.ar
 
  11         Christian Perkonig - remote debug
 
  12 **********************************************************************/
 
  13 package net.sourceforge.phpdt.internal.debug.core;
 
  15 import java.io.BufferedReader;
 
  16 import java.io.IOException;
 
  17 import java.io.InputStreamReader;
 
  18 import java.io.OutputStream;
 
  19 import java.net.Socket;
 
  20 import java.net.ServerSocket;
 
  21 import java.net.SocketTimeoutException;
 
  23 import org.eclipse.core.runtime.CoreException;
 
  24 import org.eclipse.core.runtime.IPath;
 
  25 import org.eclipse.core.runtime.Path;
 
  26 import org.eclipse.debug.core.DebugPlugin;
 
  27 import org.eclipse.debug.core.DebugException;
 
  28 import org.eclipse.debug.core.model.IBreakpoint;
 
  29 import net.sourceforge.phpdt.internal.debug.core.model.IPHPDebugTarget;
 
  30 import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
 
  31 import net.sourceforge.phpdt.internal.debug.core.model.PHPThread;
 
  32 import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
 
  33 import net.sourceforge.phpdt.internal.debug.core.breakpoints.PHPLineBreakpoint;
 
  35 public class PHPDBGProxy {
 
  37         private ServerSocket server= null;
 
  38         private Socket socket;
 
  39         private BufferedReader reader= null;
 
  40         private PHPDBGInterface DBGInt= null;
 
  41         private IPHPDebugTarget debugTarget= null;
 
  42         private PHPLoop phpLoop;
 
  43         private PHPThread PHPMainThread;
 
  44         private PHPDBGProxy thisProxy= null;
 
  46         private boolean remote;
 
  47         private IPath remoteSourcePath;
 
  49         public PHPDBGProxy() {
 
  53         public PHPDBGProxy(boolean remote,String remoteSourcePath) {
 
  56                 this.remoteSourcePath= new Path(remoteSourcePath);
 
  65                 phpLoop.setShouldStop();
 
  66                 if(DBGInt != null) DBGInt.setShouldStop();
 
  70         protected ServerSocket getServerSocket() throws IOException {
 
  77         protected void createServerSocket() {
 
  78 //              port = SocketUtil.findUnusedLocalPort("localhost", 10001, 10101);
 
  81                         PHPDebugCorePlugin.log(5, "Cannot find free port!!!!");
 
  86                                 server = new ServerSocket(port);
 
  87                                 //System.out.println("ServerSocket on port: " + port);
 
  89                 } catch (IOException e) {
 
  91                         PHPDebugCorePlugin.log(e);
 
  96         public Socket getSocket() throws IOException {
 
 100         protected void setDBGInterface(PHPDBGInterface DBGInt) {
 
 104         public BufferedReader getReader() throws IOException {
 
 105                 if (reader == null) {                   
 
 106                         reader = new BufferedReader(new InputStreamReader(this.getSocket().getInputStream(), "ISO8859_1"));
 
 111         public BufferedReader getReader(Socket socket) throws IOException {
 
 113                   return new BufferedReader(new InputStreamReader(socket.getInputStream(), "ISO8859_1"));
 
 118         public OutputStream getOutputStream() throws IOException {
 
 119                 return this.getSocket().getOutputStream();
 
 122         protected void setBreakPoints() throws IOException, CoreException {
 
 123                 IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints();
 
 124                 for (int i = 0; i < breakpoints.length; i++) {
 
 125                         addBreakpoint(breakpoints[i]);
 
 129         public void addBreakpoint(IBreakpoint breakpoint) {
 
 130                 if (DBGInt == null) return;
 
 133                         PHPLineBreakpoint phpLBP;
 
 134                         if(breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getDefault().getDescriptor().getUniqueIdentifier()) {
 
 136                                 phpLBP= (PHPLineBreakpoint)breakpoint;
 
 137                                 //                              bpNo= DBGInt.addBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber());
 
 139                                         filename=remoteSourcePath.append(phpLBP.getMarker().getResource().getProjectRelativePath());
 
 141                                         filename=phpLBP.getMarker().getResource().getLocation();
 
 142                                 bpNo= DBGInt.addBreakpoint(filename.toOSString(), phpLBP.getLineNumber());
 
 143                                 phpLBP.setDBGBpNo(bpNo);
 
 145                 } catch (IOException e) {
 
 146                         PHPDebugCorePlugin.log(e);
 
 148                 } catch (CoreException e) {
 
 149                         PHPDebugCorePlugin.log(e);
 
 154         public void removeBreakpoint(IBreakpoint breakpoint) {
 
 155                 if (DBGInt == null) return;
 
 157                         PHPLineBreakpoint phpLBP;
 
 158                         if(breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getDefault().getDescriptor().getUniqueIdentifier()) {
 
 159                                 phpLBP= (PHPLineBreakpoint)breakpoint;
 
 162                                         filename=remoteSourcePath.append(phpLBP.getMarker().getResource().getProjectRelativePath());
 
 164                                         filename=phpLBP.getMarker().getResource().getLocation();
 
 165 //                                      bpNo= DBGInt.addBreakpoint(filename.toOSString(), phpLBP.getLineNumber());                              
 
 166                                 DBGInt.removeBreakpoint(filename.toOSString(), phpLBP.getLineNumber(), phpLBP.getDBGBpNo());
 
 168                 } catch (IOException e) {
 
 169                         PHPDebugCorePlugin.log(e);
 
 171                 } catch (CoreException e) {
 
 172                         PHPDebugCorePlugin.log(e);
 
 177         public void startPHPLoop() {
 
 178                 phpLoop = new PHPLoop();
 
 182         public void resume(PHPThread thread) {
 
 184                         DBGInt.continueExecution();
 
 185                         phpLoop.notifyWait();
 
 186                 } catch (IOException e) {
 
 187                         PHPDebugCorePlugin.log(e);
 
 192         protected IPHPDebugTarget getDebugTarget() {
 
 196         public void setDebugTarget(IPHPDebugTarget debugTarget) {
 
 197                 this.debugTarget = debugTarget;
 
 198                 debugTarget.setPHPDBGProxy(this);
 
 201         public PHPVariable[] readVariables(PHPStackFrame frame) {
 
 203                         return DBGInt.getVariables(frame);
 
 204                 } catch (IOException ioex) {
 
 205                         ioex.printStackTrace();
 
 206                         throw new RuntimeException(ioex.getMessage());
 
 207                 } catch (DebugException ex) {
 
 208                         ex.printStackTrace();
 
 209                         throw new RuntimeException(ex.getMessage());
 
 213         public PHPVariable[] readInstanceVariables(PHPVariable variable) {
 
 215                         return DBGInt.getInstVars(variable);
 
 216                 } catch (DebugException ex) {
 
 217                         ex.printStackTrace();
 
 218                         throw new RuntimeException(ex.getMessage());
 
 223         public void readStepOverEnd(PHPStackFrame stackFrame) {
 
 226                         phpLoop.notifyWait();
 
 227                 } catch (Exception e) {
 
 228                         PHPDebugCorePlugin.log(e);
 
 232         public void readStepReturnEnd(PHPStackFrame stackFrame) {
 
 235                         phpLoop.notifyWait();
 
 236                 } catch (Exception e) {
 
 237                         PHPDebugCorePlugin.log(e);
 
 241         public void readStepIntoEnd(PHPStackFrame stackFrame) {
 
 244                         phpLoop.notifyWait();
 
 245                 } catch (Exception e) {
 
 246                         PHPDebugCorePlugin.log(e);
 
 251         public PHPStackFrame[] readFrames(PHPThread thread) {
 
 253                         //this.println("th " + thread.getId() + " ; f ");
 
 254                         //return new FramesReader(getMultiReaderStrategy()).readFrames(thread);
 
 256                 //} catch (IOException e) {
 
 257                 //      PHPDebugCorePlugin.log(e);
 
 264         public void closeSocket() throws IOException {
 
 265                 if (socket != null) {
 
 270         public void closeServerSocket() throws IOException {
 
 271                 if (server != null) {
 
 276         public int getPort() {
 
 280         class PHPLoop extends Thread {
 
 281                 private boolean shouldStop;
 
 285                         this.setName("PHPDebuggerLoop");
 
 288                 public synchronized void setShouldStop() {
 
 292                 public synchronized void notifyWait() {
 
 298                                 char[] buf= new char[16];
 
 300                                 long interval= 200; // 200ms
 
 302                                 PHPStackFrame[] StackList;
 
 303                                 boolean endFile=false;
 
 304                                 boolean newconnect=false;
 
 305                                 Socket newSocket=null;
 
 306                                 PHPDBGInterface newDBGInt;
 
 309                                 PHPMainThread = new PHPThread(getDebugTarget(), getPort());
 
 310                                 PHPMainThread.setName("Thread [main]");
 
 312                                 while ((getDebugTarget() == null) && (timeout < 100)) {
 
 316                                 // Be sure debug target is set
 
 317                                 PHPMainThread.setDebugTarget(getDebugTarget());
 
 318                                 getDebugTarget().addThread(PHPMainThread);
 
 320                                 //System.out.println("Waiting for breakpoints.");       
 
 325                   newSocket = server.accept();
 
 326                  //System.out.println("Accepted! : " + socket.toString());
 
 327                 } catch (SocketTimeoutException e) {
 
 328                                                 // no one wants to connect
 
 330                     } catch (IOException e) {
 
 331                 PHPDebugCorePlugin.log(e);
 
 338                                                         server.setSoTimeout(1);
 
 339                                                 newDBGInt= new PHPDBGInterface(getReader(newSocket), newSocket.getOutputStream(), thisProxy);
 
 340                                                 newDBGInt.waitResponse(1000);
 
 341                   newDBGInt.flushAllPackets();
 
 342                                                 // Check version and session ID
 
 343                   if ((DBGInt==null) || (DBGInt.getSID()==newDBGInt.getSID()))
 
 348                                                         }       catch (IOException e) {
 
 349                                                                 PHPDebugCorePlugin.log(e);
 
 354                                                         DBGInt.continueExecution();                     
 
 357                                                         newDBGInt.continueExecution();
 
 362                 if(DBGInt.waitResponse(interval))
 
 365                 DBGInt.flushAllPackets();
 
 367                 if (DBGInt.BPUnderHit != 0) {
 
 368                         StackList = DBGInt.getStackList();
 
 369                         if (StackList.length > 0) {
 
 370                         for (i = 0; i < StackList.length; i++) {
 
 371                         StackList[i].setThread(PHPMainThread);
 
 372                         if (DBGInt.getModByNo(StackList[i].getModNo()).equals("")) {
 
 373                                 DBGInt.getSourceTree();
 
 375                         StackList[i].setFile(
 
 376                                 DBGInt.getModByNo(StackList[i].getModNo()));
 
 378                         PHPMainThread.setStackFrames(StackList);
 
 381                         PHPMainThread.suspend();
 
 383                         synchronized (this) {
 
 389                 if (PHPMainThread.isTerminated())
 
 395                 if (PHPMainThread.isTerminated() || getDebugTarget().getProcess().isTerminated())
 
 401 //              if (DBGInt.getLastCmd()==PHPDBGBase.DBGC_LOG)
 
 408 //                                      catch (IOException e) {
 
 409 //                                              PHPDebugCorePlugin.log(e);
 
 415         catch (Exception ex) {
 
 416         PHPDebugCorePlugin.log(ex);
 
 417         System.out.println(ex);
 
 421                 getDebugTarget().terminate();
 
 425                 catch (IOException e) {
 
 426                 PHPDebugCorePlugin.log(e);
 
 429         //System.out.println("Socket loop finished.");