feb5325eb7ca4caea97c63206eafc065d8afedc9
[phpeclipse.git] /
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 **********************************************************************/
12 package net.sourceforge.phpdt.internal.debug.core;
13
14 import java.io.BufferedReader;
15 import java.io.IOException;
16 import java.io.InputStreamReader;
17 import java.io.OutputStream;
18 import java.net.Socket;
19 import java.net.ServerSocket;
20
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.debug.core.DebugPlugin;
23 import org.eclipse.debug.core.DebugException;
24 import org.eclipse.debug.core.model.IBreakpoint;
25 import net.sourceforge.phpdt.internal.debug.core.model.IPHPDebugTarget;
26 import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
27 import net.sourceforge.phpdt.internal.debug.core.model.PHPThread;
28 import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
29 import net.sourceforge.phpdt.internal.debug.core.breakpoints.PHPLineBreakpoint;
30
31 public class PHPDBGProxy {
32
33         private ServerSocket server= null;
34         private Socket socket;
35         private BufferedReader reader= null;
36         private PHPDBGInterface DBGInt= null;
37         private IPHPDebugTarget debugTarget= null;
38         private PHPLoop phpLoop;
39         private PHPThread PHPMainThread;
40         private PHPDBGProxy thisProxy= null;
41         private int port;
42
43         public PHPDBGProxy() {
44                 thisProxy= this;
45         }
46
47         public void start() {
48                 createServerSocket();
49                 this.startPHPLoop();
50         }
51
52         public void stop() {
53                 phpLoop.setShouldStop();
54                 if(DBGInt != null) DBGInt.setShouldStop();
55                 try {
56                         getDebugTarget().getProcess().terminate();
57                 } catch (DebugException e) {
58                         e.printStackTrace();
59                 }
60                 phpLoop.notifyWait();
61         }
62
63         protected ServerSocket getServerSocket() throws IOException {
64                 if (server == null) {
65                         createServerSocket();
66                 }
67                 return server;
68         }
69
70         protected void createServerSocket() {
71                 port = SocketUtil.findUnusedLocalPort("localhost", 10001, 10101);
72                 if (port == -1) {
73                         PHPDebugCorePlugin.log(5, "Cannot find free port!!!!");
74                         return;
75                 }
76                 try {
77                         if (server == null) {
78                                 server = new ServerSocket(port);
79                                 //System.out.println("ServerSocket on port: " + port);
80                         } 
81                 } catch (IOException e) {
82                         // IO Error
83                         PHPDebugCorePlugin.log(e);
84                         stop();
85                 }
86         }
87
88         public Socket getSocket() throws IOException {
89                 return socket;
90         }
91
92         protected void setDBGInterface(PHPDBGInterface DBGInt) {
93                 this.DBGInt= DBGInt;
94         }
95
96         public BufferedReader getReader() throws IOException {
97                 if (reader == null) {
98                         reader = new BufferedReader(new InputStreamReader(this.getSocket().getInputStream(), "ISO8859_1"));
99                 }
100                 return reader;
101         }
102
103         public OutputStream getOutputStream() throws IOException {
104                 return this.getSocket().getOutputStream();
105         }
106
107         protected void setBreakPoints() throws IOException, CoreException {
108                 IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints();
109                 for (int i = 0; i < breakpoints.length; i++) {
110                         addBreakpoint(breakpoints[i]);
111                 }
112         }
113
114         public void addBreakpoint(IBreakpoint breakpoint) {
115                 if (DBGInt == null) return;
116                 int bpNo= 0;
117                 try {
118                         PHPLineBreakpoint phpLBP;
119                         if(breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getDefault().getDescriptor().getUniqueIdentifier()) {
120                                 phpLBP= (PHPLineBreakpoint)breakpoint;
121                                 bpNo= DBGInt.addBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber());
122                                 phpLBP.setDBGBpNo(bpNo);
123                         }
124                 } catch (IOException e) {
125                         PHPDebugCorePlugin.log(e);
126                         stop();
127                 } catch (CoreException e) {
128                         PHPDebugCorePlugin.log(e);
129                         stop();
130                 }
131         }
132
133         public void removeBreakpoint(IBreakpoint breakpoint) {
134                 if (DBGInt == null) return;
135                 try {
136                         PHPLineBreakpoint phpLBP;
137                         if(breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getDefault().getDescriptor().getUniqueIdentifier()) {
138                                 phpLBP= (PHPLineBreakpoint)breakpoint;
139                                 DBGInt.removeBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber(), phpLBP.getDBGBpNo());
140                         }
141                 } catch (IOException e) {
142                         PHPDebugCorePlugin.log(e);
143                         stop();
144                 } catch (CoreException e) {
145                         PHPDebugCorePlugin.log(e);
146                         stop();
147                 }
148         }
149
150         public void startPHPLoop() {
151                 phpLoop = new PHPLoop();
152                 phpLoop.start();
153         }
154
155         public void resume() {
156                 try {
157                         DBGInt.continueExecution();
158                         phpLoop.notifyWait();
159                 } catch (IOException e) {
160                         PHPDebugCorePlugin.log(e);
161                         stop();
162                 }
163         }
164
165         public void pause() {
166                 try {
167                         DBGInt.pauseExecution();
168                 } catch (IOException e) {
169                         PHPDebugCorePlugin.log(e);
170                         stop();
171                 }
172         }
173         protected IPHPDebugTarget getDebugTarget() {
174                 return debugTarget;
175         }
176
177         public void setDebugTarget(IPHPDebugTarget debugTarget) {
178                 this.debugTarget = debugTarget;
179                 debugTarget.setPHPDBGProxy(this);
180         }
181
182         public PHPVariable[] readVariables(PHPStackFrame frame) {
183                 try {
184                         return DBGInt.getVariables(frame);
185                 } catch (IOException ioex) {
186                         ioex.printStackTrace();
187                         throw new RuntimeException(ioex.getMessage());
188                 } catch (DebugException ex) {
189                         ex.printStackTrace();
190                         throw new RuntimeException(ex.getMessage());
191                 }
192         }
193
194         public PHPVariable[] readInstanceVariables(PHPVariable variable) {
195                 try {
196                         return DBGInt.getInstVars(variable);
197                 } catch (DebugException ex) {
198                         ex.printStackTrace();
199                         throw new RuntimeException(ex.getMessage());
200                 }
201
202         }
203
204         public void readStepOverEnd(PHPStackFrame stackFrame) {
205                 try {
206                         DBGInt.stepOver();
207                         phpLoop.notifyWait();
208                 } catch (Exception e) {
209                         PHPDebugCorePlugin.log(e);
210                 }
211         }
212
213         public void readStepReturnEnd(PHPStackFrame stackFrame) {
214                 try {
215                         DBGInt.stepOut();
216                         phpLoop.notifyWait();
217                 } catch (Exception e) {
218                         PHPDebugCorePlugin.log(e);
219                 }
220         }
221
222         public void readStepIntoEnd(PHPStackFrame stackFrame) {
223                 try {
224                         DBGInt.stepInto();
225                         phpLoop.notifyWait();
226                 } catch (Exception e) {
227                         PHPDebugCorePlugin.log(e);
228                 }
229         }
230
231 /*
232         public PHPStackFrame[] readFrames(PHPThread thread) {
233                 //try {
234                         //this.println("th " + thread.getId() + " ; f ");
235                         //return new FramesReader(getMultiReaderStrategy()).readFrames(thread);
236                         return null;
237                 //} catch (IOException e) {
238                 //      PHPDebugCorePlugin.log(e);
239                 //      return null;
240                 //}
241
242         }
243 */
244         
245         public void closeSocket() throws IOException {
246                 if (socket != null) {
247                         socket.close();
248                 }
249         }
250
251         public void closeServerSocket() throws IOException {
252                 if (server != null) {
253                         server.close();
254                 }
255         }
256
257         public int getPort() {
258                 return port;
259         }
260
261         class PHPLoop extends Thread {
262                 private boolean shouldStop;
263         
264                 public PHPLoop() {
265                         shouldStop = false;
266                         this.setName("PHPDebuggerLoop");
267                 }
268
269                 public synchronized void setShouldStop() {
270                         shouldStop = true;
271                 }
272
273                 public synchronized void notifyWait() {
274                         notify();
275                 }
276
277                 public void run() {
278                         try {
279                                 char[] buf= new char[16];
280                                 int i, pos, timeout;
281                                 long interval= 1000*20;
282                                 String line;
283                                 PHPStackFrame[] StackList;
284                                 
285                                 //System.out.println("Waiting for breakpoints.");                       
286                                 try{
287                                         socket = server.accept();
288                                         //System.out.println("Accepted! : " + socket.toString());
289                                 } catch (IOException e) {
290                                         PHPDebugCorePlugin.log(e);
291                                         return;                 
292                                 }
293                                 
294                                 PHPMainThread= new PHPThread(getDebugTarget(), getPort());
295                                 PHPMainThread.setName("Thread [main]");
296                                 timeout= 0;
297                                 while((getDebugTarget() == null) && (timeout < 100)) {
298                                         sleep(100);
299                                         timeout++;
300                                 }
301                                 // Be sure debug target is set
302                                 PHPMainThread.setDebugTarget(getDebugTarget());
303                                 getDebugTarget().addThread(PHPMainThread);
304                                 setDBGInterface(new PHPDBGInterface(getReader(), getOutputStream(), thisProxy));
305
306                                 DBGInt.waitResponse(1000);
307                                 DBGInt.flushAllPackets();
308
309                                 // Check version and session ID
310                                 setBreakPoints();
311                                 DBGInt.continueExecution();
312
313                                 while (!shouldStop) {
314                                         DBGInt.waitResponse(interval);
315                                         DBGInt.flushAllPackets();
316
317                                         if (DBGInt.BPUnderHit != 0) {
318                                                 StackList= DBGInt.getStackList();
319                                                 if(StackList.length > 0) {
320                                                         for(i=0; i < StackList.length; i++) {
321                                                                 StackList[i].setThread(PHPMainThread);
322                                                                 if(DBGInt.getModByNo(StackList[i].getModNo()).equals("")) {
323                                                                         DBGInt.getSourceTree();
324                                                                 }
325                                                                 StackList[i].setFile(DBGInt.getModByNo(StackList[i].getModNo()));
326                                                         }
327                                                         PHPMainThread.setStackFrames(StackList);
328                                                 }
329                                                 // Fire debug event
330                                                 PHPMainThread.suspend();
331
332                                                 synchronized(this) {
333                                                         wait();
334                                                 }
335                                         }                                       
336                                         if(PHPMainThread.isTerminated() || getDebugTarget().getProcess().isTerminated()) break;
337                                 }
338                         } catch (Exception ex) {
339                                 PHPDebugCorePlugin.log(ex);
340                                 System.out.println(ex);
341                         } finally {
342                                 try {
343                                         getDebugTarget().terminate();
344                                         closeSocket();
345                                         closeServerSocket();
346                                 } catch (IOException e) {
347                                         PHPDebugCorePlugin.log(e);
348                                         return;
349                                 }
350                                 //System.out.println("Socket loop finished.");
351                         }
352                 }
353         }
354 }