1 /***********************************************************************************************************************************
2 * Copyright (c) 2000, 2002 IBM Corp. and others. All rights reserved. This program and the accompanying materials are made
3 * available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at
4 * http://www.eclipse.org/legal/cpl-v10.html
6 * Contributors: IBM Corporation - Initial implementation Vicente Fernando - www.alfersoft.com.ar Christian Perkonig - remote debug
7 **********************************************************************************************************************************/
8 package net.sourceforge.phpdt.internal.debug.core;
10 import java.io.BufferedReader;
11 import java.io.IOException;
12 import java.io.InputStreamReader;
13 import java.io.OutputStream;
14 import java.net.ServerSocket;
15 import java.net.Socket;
16 import java.net.SocketTimeoutException;
19 import net.sourceforge.phpdt.internal.debug.core.breakpoints.PHPLineBreakpoint;
20 import net.sourceforge.phpdt.internal.debug.core.model.IPHPDebugTarget;
21 import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
22 import net.sourceforge.phpdt.internal.debug.core.model.PHPThread;
23 import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
25 import org.eclipse.core.runtime.CoreException;
26 import org.eclipse.core.runtime.IPath;
27 import org.eclipse.core.runtime.Path;
28 import org.eclipse.debug.core.DebugException;
29 import org.eclipse.debug.core.DebugPlugin;
30 import org.eclipse.debug.core.model.IBreakpoint;
32 public class PHPDBGProxy {
34 private ServerSocket server = null;
36 private Socket socket;
38 private BufferedReader reader = null;
40 private PHPDBGInterface DBGInt = null;
42 private IPHPDebugTarget debugTarget = null;
44 private PHPLoop phpLoop;
46 private PHPThread PHPMainThread;
48 private PHPDBGProxy thisProxy = null;
52 private boolean remote;
54 private boolean pathtranslation;
58 private IPath remoteSourcePath;
60 public PHPDBGProxy() {
64 public PHPDBGProxy(boolean remote, String remoteSourcePath,boolean pathTranslate,Map paths) {
67 this.remoteSourcePath = new Path(remoteSourcePath);
69 this.pathtranslation=pathTranslate;
78 phpLoop.setShouldStop();
80 DBGInt.setShouldStop();
83 getDebugTarget().getProcess().terminate();
84 } catch (DebugException e) {
91 protected ServerSocket getServerSocket() throws IOException {
98 protected void createServerSocket() {
99 port = SocketUtil.findUnusedLocalPort("localhost", 10001, 10101);
102 PHPDebugCorePlugin.log(5, "Cannot find free port!!!!");
106 if (server == null) {
107 server = new ServerSocket(port);
108 //System.out.println("ServerSocket on port: " + port);
110 } catch (IOException e) {
112 PHPDebugCorePlugin.log(e);
117 public Socket getSocket() throws IOException {
121 protected void setDBGInterface(PHPDBGInterface DBGInt) {
122 this.DBGInt = DBGInt;
125 public BufferedReader getReader() throws IOException {
126 if (reader == null) {
127 reader = new BufferedReader(new InputStreamReader(this.getSocket().getInputStream(), "ISO8859_1"));
132 public BufferedReader getReader(Socket socket) throws IOException {
134 return new BufferedReader(new InputStreamReader(socket.getInputStream(), "ISO8859_1"));
139 public OutputStream getOutputStream() throws IOException {
140 return this.getSocket().getOutputStream();
143 protected void setBreakPoints() throws IOException, CoreException {
144 IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints();
145 for (int i = 0; i < breakpoints.length; i++) {
146 addBreakpoint(breakpoints[i]);
150 private String MapPath(PHPLineBreakpoint phpLBP) {
153 filename = phpLBP.getMarker().getResource()
154 .getProjectRelativePath();
155 filename = remoteSourcePath.append(filename);
157 filename = phpLBP.getMarker().getResource().getLocation();
158 String path = filename.toOSString();
159 if (pathmap != null && remote) {
160 java.util.Iterator i = pathmap.keySet().iterator();
161 while (i.hasNext()) {
162 String k = (String) i.next();
163 if (path.startsWith(k)) {
164 path = pathmap.get(k) + path.substring(k.length());
169 if (pathtranslation && remote) {
170 if (path.substring(0, 1).equals("/"))
171 path = path.replace('\\', '/');
173 path = path.replace('/', '\\');
178 public void addBreakpoint(IBreakpoint breakpoint) {
183 PHPLineBreakpoint phpLBP;
184 if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier()) {
185 phpLBP = (PHPLineBreakpoint) breakpoint;
186 // bpNo= DBGInt.addBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber());
188 bpNo = DBGInt.addBreakpoint(MapPath(phpLBP), phpLBP.getLineNumber());
189 phpLBP.setDBGBpNo(bpNo);
191 } catch (IOException e) {
192 PHPDebugCorePlugin.log(e);
194 } catch (CoreException e) {
195 PHPDebugCorePlugin.log(e);
200 public void removeBreakpoint(IBreakpoint breakpoint) {
204 PHPLineBreakpoint phpLBP;
205 if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier()) {
206 phpLBP = (PHPLineBreakpoint) breakpoint;
208 // bpNo= DBGInt.addBreakpoint(filename.toOSString(), phpLBP.getLineNumber());
209 DBGInt.removeBreakpoint(MapPath(phpLBP), phpLBP.getLineNumber(), phpLBP.getDBGBpNo());
211 } catch (IOException e) {
212 PHPDebugCorePlugin.log(e);
214 } catch (CoreException e) {
215 PHPDebugCorePlugin.log(e);
220 public void phpLoopNotify() {
221 phpLoop.notifyWait();
224 public void startPHPLoop() {
225 phpLoop = new PHPLoop();
229 public void resume() {
231 DBGInt.continueExecution();
232 phpLoop.notifyWait();
233 } catch (IOException e) {
234 PHPDebugCorePlugin.log(e);
239 public void pause() {
242 DBGInt.pauseExecution();
244 // TODO Make sure the Suspend action is grayed out
245 // when DBGInt is null
247 } catch (IOException e) {
248 PHPDebugCorePlugin.log(e);
253 protected IPHPDebugTarget getDebugTarget() {
257 public void setDebugTarget(IPHPDebugTarget debugTarget) {
258 this.debugTarget = debugTarget;
259 debugTarget.setPHPDBGProxy(this);
262 public PHPVariable[] readVariables(PHPStackFrame frame) {
264 return DBGInt.getVariables(frame);
265 } catch (IOException ioex) {
266 ioex.printStackTrace();
267 throw new RuntimeException(ioex.getMessage());
268 } catch (DebugException ex) {
269 ex.printStackTrace();
270 throw new RuntimeException(ex.getMessage());
274 public PHPVariable[] eval(PHPStackFrame frame, String evalString) {
276 return DBGInt.evalBlock(frame, evalString);
277 // return DBGInt.getVariables(frame);
278 } catch (IOException ioex) {
279 ioex.printStackTrace();
280 throw new RuntimeException(ioex.getMessage());
281 } catch (DebugException ex) {
282 ex.printStackTrace();
283 throw new RuntimeException(ex.getMessage());
287 public void readStepOverEnd(PHPStackFrame stackFrame) {
290 phpLoop.notifyWait();
291 } catch (Exception e) {
292 PHPDebugCorePlugin.log(e);
296 public void readStepReturnEnd(PHPStackFrame stackFrame) {
299 phpLoop.notifyWait();
300 } catch (Exception e) {
301 PHPDebugCorePlugin.log(e);
305 public void readStepIntoEnd(PHPStackFrame stackFrame) {
308 phpLoop.notifyWait();
309 } catch (Exception e) {
310 PHPDebugCorePlugin.log(e);
315 * public PHPStackFrame[] readFrames(PHPThread thread) { //try { //this.println("th " + thread.getId() + " ; f "); //return new
316 * FramesReader(getMultiReaderStrategy()).readFrames(thread); return null; //} catch (IOException e) { //
317 * PHPDebugCorePlugin.log(e); // return null; //}
321 public void closeSocket() throws IOException {
322 if (socket != null) {
327 public void closeServerSocket() throws IOException {
328 if (server != null) {
333 public int getPort() {
337 class PHPLoop extends Thread {
338 private boolean shouldStop;
342 this.setName("PHPDebuggerLoop");
345 public synchronized void setShouldStop() {
348 // If the loop thread is blocked on the server socket,
349 // forcibly unblock it to avoid leaking the thread,
350 // the socket and the port
352 } catch (IOException x) {
353 // Log this as a warning?
354 PHPDebugCorePlugin.log(x);
358 public synchronized void notifyWait() {
364 char[] buf = new char[16];
366 long interval = 200; // 200ms
368 PHPStackFrame[] StackList;
369 boolean endFile = false;
370 boolean newconnect = false;
371 Socket newSocket = null;
372 PHPDBGInterface newDBGInt;
375 // synchronized (this) {
379 PHPMainThread = new PHPThread(getDebugTarget(), getPort());
380 PHPMainThread.setName("Thread [main]");
383 // while ((getDebugTarget() == null) && (timeout < 100)) {
387 // Be sure debug target is set
388 // PHPMainThread.setDebugTarget(getDebugTarget());
389 getDebugTarget().addThread(PHPMainThread);
391 //System.out.println("Waiting for breakpoints.");
392 while (!shouldStop) {
395 newSocket = server.accept();
396 //System.out.println("Accepted! : " + socket.toString());
397 } catch (SocketTimeoutException e) {
398 // no one wants to connect
400 } catch (IOException e) {
401 PHPDebugCorePlugin.log(e);
407 server.setSoTimeout(1);
408 newDBGInt = new PHPDBGInterface(getReader(newSocket), newSocket.getOutputStream(), thisProxy);
409 newDBGInt.waitResponse(1000);
410 newDBGInt.flushAllPackets();
411 // Check version and session ID
412 if ((DBGInt == null) || (DBGInt.getSID() == newDBGInt.getSID())) {
416 } catch (IOException e) {
417 PHPDebugCorePlugin.log(e);
422 DBGInt.continueExecution();
424 newDBGInt.continueExecution();
429 if (DBGInt.waitResponse(interval)) {
431 DBGInt.flushAllPackets();
433 if (DBGInt.BPUnderHit != 0) {
434 StackList = DBGInt.getStackList();
435 if (StackList.length > 0) {
436 for (i = 0; i < StackList.length; i++) {
437 StackList[i].setThread(PHPMainThread);
438 if (DBGInt.getModByNo(StackList[i].getModNo()).equals("")) {
439 DBGInt.getSourceTree();
441 StackList[i].setFile(DBGInt.getModByNo(StackList[i].getModNo()));
443 PHPMainThread.setStackFrames(StackList);
446 PHPMainThread.suspend();
448 synchronized (this) {
454 if (PHPMainThread.isTerminated()) {
459 if (PHPMainThread.isTerminated() || getDebugTarget().getProcess().isTerminated()) {
465 } catch (Exception ex) {
466 PHPDebugCorePlugin.log(ex);
467 System.out.println(ex);
470 getDebugTarget().terminate();
473 } catch (IOException e) {
474 PHPDebugCorePlugin.log(e);
477 //System.out.println("Socket loop finished.");