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