dd3b8f6a00e8202c56bd891ce0bfc8167418fca9
[phpeclipse.git] / net.sourceforge.phpeclipse.debug.core / bin / net / sourceforge / phpdt / internal / debug / core / .#PHPDBGProxy.java.1.3
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
7
8 Contributors:
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;
14
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;
22
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;
34
35 public class PHPDBGProxy {
36
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;
45         private int port;
46         private boolean remote;
47         private IPath remoteSourcePath;
48
49         public PHPDBGProxy() {
50                 thisProxy= this;
51         }
52
53         public PHPDBGProxy(boolean remote,String remoteSourcePath) {
54                 thisProxy= this;
55                 this.remote=remote;
56                 this.remoteSourcePath= new Path(remoteSourcePath);
57         }
58
59         public void start() {
60                 createServerSocket();
61                 this.startPHPLoop();
62         }
63
64         public void stop() {
65                 phpLoop.setShouldStop();
66                 if(DBGInt != null) DBGInt.setShouldStop();
67                 phpLoop.notifyWait();
68         }
69
70         protected ServerSocket getServerSocket() throws IOException {
71                 if (server == null) {
72                         createServerSocket();
73                 }
74                 return server;
75         }
76
77         protected void createServerSocket() {
78 //              port = SocketUtil.findUnusedLocalPort("localhost", 10001, 10101);
79     port =      10001;
80                 if (port == -1) {
81                         PHPDebugCorePlugin.log(5, "Cannot find free port!!!!");
82                         return;
83                 }
84                 try {
85                         if (server == null) {
86                                 server = new ServerSocket(port);
87                                 //System.out.println("ServerSocket on port: " + port);
88                         } 
89                 } catch (IOException e) {
90                         // IO Error
91                         PHPDebugCorePlugin.log(e);
92                         stop();
93                 }
94         }
95
96         public Socket getSocket() throws IOException {
97                 return socket;
98         }
99
100         protected void setDBGInterface(PHPDBGInterface DBGInt) {
101                 this.DBGInt= DBGInt;
102         }
103
104         public BufferedReader getReader() throws IOException {
105                 if (reader == null) {                   
106                         reader = new BufferedReader(new InputStreamReader(this.getSocket().getInputStream(), "ISO8859_1"));
107                 }
108                 return reader;
109         }
110         
111         public BufferedReader getReader(Socket socket) throws IOException {
112                 if (socket != null)
113                   return new BufferedReader(new InputStreamReader(socket.getInputStream(), "ISO8859_1"));
114                 else
115                   return null;
116         }
117
118         public OutputStream getOutputStream() throws IOException {
119                 return this.getSocket().getOutputStream();
120         }
121
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]);
126                 }
127         }
128
129         public void addBreakpoint(IBreakpoint breakpoint) {
130                 if (DBGInt == null) return;
131                 int bpNo= 0;
132                 try {
133                         PHPLineBreakpoint phpLBP;
134                         if(breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getDefault().getDescriptor().getUniqueIdentifier()) {
135                                 IPath filename;
136                                 phpLBP= (PHPLineBreakpoint)breakpoint;
137                                 //                              bpNo= DBGInt.addBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber());
138                                 if (remote)
139                                         filename=remoteSourcePath.append(phpLBP.getMarker().getResource().getProjectRelativePath());
140                                 else
141                                         filename=phpLBP.getMarker().getResource().getLocation();
142                                 bpNo= DBGInt.addBreakpoint(filename.toOSString(), phpLBP.getLineNumber());
143                                 phpLBP.setDBGBpNo(bpNo);
144                         }
145                 } catch (IOException e) {
146                         PHPDebugCorePlugin.log(e);
147                         stop();
148                 } catch (CoreException e) {
149                         PHPDebugCorePlugin.log(e);
150                         stop();
151                 }
152         }
153
154         public void removeBreakpoint(IBreakpoint breakpoint) {
155                 if (DBGInt == null) return;
156                 try {
157                         PHPLineBreakpoint phpLBP;
158                         if(breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getDefault().getDescriptor().getUniqueIdentifier()) {
159                                 phpLBP= (PHPLineBreakpoint)breakpoint;
160                                 IPath filename;
161                                 if (remote)
162                                         filename=remoteSourcePath.append(phpLBP.getMarker().getResource().getProjectRelativePath());
163                                 else
164                                         filename=phpLBP.getMarker().getResource().getLocation();
165 //                                      bpNo= DBGInt.addBreakpoint(filename.toOSString(), phpLBP.getLineNumber());                              
166                                 DBGInt.removeBreakpoint(filename.toOSString(), phpLBP.getLineNumber(), phpLBP.getDBGBpNo());
167                         }
168                 } catch (IOException e) {
169                         PHPDebugCorePlugin.log(e);
170                         stop();
171                 } catch (CoreException e) {
172                         PHPDebugCorePlugin.log(e);
173                         stop();
174                 }
175         }
176
177         public void startPHPLoop() {
178                 phpLoop = new PHPLoop();
179                 phpLoop.start();
180         }
181
182         public void resume(PHPThread thread) {
183                 try {
184                         DBGInt.continueExecution();
185                         phpLoop.notifyWait();
186                 } catch (IOException e) {
187                         PHPDebugCorePlugin.log(e);
188                         stop();
189                 }
190         }
191
192         protected IPHPDebugTarget getDebugTarget() {
193                 return debugTarget;
194         }
195
196         public void setDebugTarget(IPHPDebugTarget debugTarget) {
197                 this.debugTarget = debugTarget;
198                 debugTarget.setPHPDBGProxy(this);
199         }
200
201         public PHPVariable[] readVariables(PHPStackFrame frame) {
202                 try {
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());
210                 }
211         }
212
213         public PHPVariable[] readInstanceVariables(PHPVariable variable) {
214                 try {
215                         return DBGInt.getInstVars(variable);
216                 } catch (DebugException ex) {
217                         ex.printStackTrace();
218                         throw new RuntimeException(ex.getMessage());
219                 }
220
221         }
222
223         public void readStepOverEnd(PHPStackFrame stackFrame) {
224                 try {
225                         DBGInt.stepOver();
226                         phpLoop.notifyWait();
227                 } catch (Exception e) {
228                         PHPDebugCorePlugin.log(e);
229                 }
230         }
231
232         public void readStepReturnEnd(PHPStackFrame stackFrame) {
233                 try {
234                         DBGInt.stepOut();
235                         phpLoop.notifyWait();
236                 } catch (Exception e) {
237                         PHPDebugCorePlugin.log(e);
238                 }
239         }
240
241         public void readStepIntoEnd(PHPStackFrame stackFrame) {
242                 try {
243                         DBGInt.stepInto();
244                         phpLoop.notifyWait();
245                 } catch (Exception e) {
246                         PHPDebugCorePlugin.log(e);
247                 }
248         }
249
250 /*
251         public PHPStackFrame[] readFrames(PHPThread thread) {
252                 //try {
253                         //this.println("th " + thread.getId() + " ; f ");
254                         //return new FramesReader(getMultiReaderStrategy()).readFrames(thread);
255                         return null;
256                 //} catch (IOException e) {
257                 //      PHPDebugCorePlugin.log(e);
258                 //      return null;
259                 //}
260
261         }
262 */
263         
264         public void closeSocket() throws IOException {
265                 if (socket != null) {
266                         socket.close();
267                 }
268         }
269
270         public void closeServerSocket() throws IOException {
271                 if (server != null) {
272                         server.close();
273                 }
274         }
275
276         public int getPort() {
277                 return port;
278         }
279
280         class PHPLoop extends Thread {
281                 private boolean shouldStop;
282         
283                 public PHPLoop() {
284                         shouldStop = false;
285                         this.setName("PHPDebuggerLoop");
286                 }
287
288                 public synchronized void setShouldStop() {
289                         shouldStop = true;
290                 }
291
292                 public synchronized void notifyWait() {
293                         notify();
294                 }
295
296                 public void run() {
297                         try {
298                                 char[] buf= new char[16];
299                                 int i, pos, timeout;
300                                 long interval= 200; // 200ms
301                                 String line;
302                                 PHPStackFrame[] StackList;
303                                 boolean endFile=false;
304                                 boolean newconnect=false;
305                                 Socket newSocket=null;
306                                 PHPDBGInterface newDBGInt;
307                                 int sid=-1;
308                                 
309                                 PHPMainThread = new PHPThread(getDebugTarget(), getPort());
310                                 PHPMainThread.setName("Thread [main]");
311                                 timeout = 0;
312                                 while ((getDebugTarget() == null) && (timeout < 100)) {
313                                         sleep(100);
314                                         timeout++;
315                                 }
316                                 // Be sure debug target is set
317                                 PHPMainThread.setDebugTarget(getDebugTarget());
318                                 getDebugTarget().addThread(PHPMainThread);
319                                 
320                                 //System.out.println("Waiting for breakpoints.");       
321                                 while (!shouldStop)     
322                                 {       
323                                         newconnect=true;
324                 try {
325                   newSocket = server.accept();
326                  //System.out.println("Accepted! : " + socket.toString());
327                 } catch (SocketTimeoutException e) {
328                                                 // no one wants to connect
329                                                 newconnect=false;
330                     } catch (IOException e) {
331                 PHPDebugCorePlugin.log(e);
332               return;
333               }
334         
335                                         if (newconnect)
336                                         {
337                                                 if (DBGInt==null)
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()))
344                   {
345                         DBGInt=newDBGInt;
346                                                         try     {
347                                                                 closeSocket();
348                                                         }       catch (IOException e) {
349                                                                 PHPDebugCorePlugin.log(e);
350                                                                 shouldStop=true;
351                                                         }
352                         socket=newSocket;
353                                                         setBreakPoints();
354                                                         DBGInt.continueExecution();                     
355                   } else
356                   {
357                                                         newDBGInt.continueExecution();
358                         newSocket.close();
359                   }
360                                         }
361
362                 if(DBGInt.waitResponse(interval))
363                 {
364                 
365                 DBGInt.flushAllPackets();
366
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();
374                         }
375                         StackList[i].setFile(
376                                 DBGInt.getModByNo(StackList[i].getModNo()));
377                         }
378                         PHPMainThread.setStackFrames(StackList);
379                         }
380                         // Fire debug event
381                         PHPMainThread.suspend();
382
383                         synchronized (this) {
384                         wait();
385                         }
386                 }
387                 }
388           if (remote) {
389                 if (PHPMainThread.isTerminated())
390                 {
391                         shouldStop=true;
392                         break;
393                 }
394           } else {
395                 if (PHPMainThread.isTerminated() || getDebugTarget().getProcess().isTerminated())
396                 {
397                                                         shouldStop=true;
398                                                         break;                   
399                 }
400           }
401 //              if (DBGInt.getLastCmd()==PHPDBGBase.DBGC_LOG)
402 //                      endFile=true;
403 //              }
404 //              try
405 //              {
406 //                                              closeSocket();
407 //              }
408 //                                      catch (IOException e) {
409 //                                              PHPDebugCorePlugin.log(e);
410 //                                              shouldStop=true;
411 //                                      }
412 //              endFile=false;
413                                 }
414         } 
415         catch (Exception ex) {
416         PHPDebugCorePlugin.log(ex);
417         System.out.println(ex);
418         } 
419         finally {
420                 try {
421                 getDebugTarget().terminate();
422                 closeSocket();
423                 closeServerSocket();
424                 }
425                 catch (IOException e) {
426                 PHPDebugCorePlugin.log(e);
427                 return;
428         }
429         //System.out.println("Socket loop finished.");
430         }
431                 }
432         }       
433 }