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.PHPDebugTarget;
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;
24 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
26 import org.eclipse.core.runtime.CoreException;
27 import org.eclipse.core.runtime.IPath;
28 import org.eclipse.core.runtime.Path;
29 import org.eclipse.debug.core.DebugException;
30 import org.eclipse.debug.core.DebugPlugin;
31 import org.eclipse.debug.core.model.IBreakpoint;
33 public class PHPDBGProxy {
35 private ServerSocket server = null;
37 private Socket socket;
39 private BufferedReader reader = null;
41 private PHPDBGInterface DBGInt = null;
43 private PHPDebugTarget debugTarget = null;
45 private PHPLoop phpLoop;
47 private PHPThread PHPMainThread;
49 private PHPDBGProxy thisProxy = null;
53 private boolean remote;
55 private boolean pathtranslation;
59 private IPath remoteSourcePath;
61 public PHPDBGProxy() {
65 public PHPDBGProxy(boolean remote, String remoteSourcePath,boolean pathTranslate,Map paths) {
68 this.remoteSourcePath = new Path(remoteSourcePath);
70 this.pathtranslation=pathTranslate;
79 phpLoop.setShouldStop();
81 DBGInt.setShouldStop();
84 getDebugTarget().getProcess().terminate();
85 } catch (DebugException e) {
92 protected ServerSocket getServerSocket() throws IOException {
99 protected void createServerSocket() {
100 port = SocketUtil.findUnusedLocalPort("localhost", 10001, 10101);
103 PHPDebugCorePlugin.log(5, "Cannot find free port!!!!");
107 if (server == null) {
108 server = new ServerSocket(port);
109 //System.out.println("ServerSocket on port: " + port);
111 } catch (IOException e) {
113 PHPDebugCorePlugin.log(e);
118 public Socket getSocket() throws IOException {
122 protected void setDBGInterface(PHPDBGInterface DBGInt) {
123 this.DBGInt = DBGInt;
126 public BufferedReader getReader() throws IOException {
127 if (reader == null) {
128 reader = new BufferedReader(new InputStreamReader(this.getSocket().getInputStream(), "ISO8859_1"));
133 public BufferedReader getReader(Socket socket) throws IOException {
135 return new BufferedReader(new InputStreamReader(socket.getInputStream(), "ISO8859_1"));
140 public OutputStream getOutputStream() throws IOException {
141 return this.getSocket().getOutputStream();
144 protected void setBreakPoints() throws IOException, CoreException {
145 IBreakpoint[] breakpoints = DebugPlugin.getDefault()
146 .getBreakpointManager().getBreakpoints();
147 for (int i = 0; i < breakpoints.length; i++) {
148 if (breakpoints[i].isEnabled()) {
149 addBreakpoint(breakpoints[i]);
154 private String MapPath(PHPLineBreakpoint phpLBP) {
157 filename = phpLBP.getMarker().getResource()
158 .getProjectRelativePath();
159 filename = remoteSourcePath.append(filename);
161 filename = phpLBP.getMarker().getResource().getLocation();
162 String path = filename.toOSString();
163 if (pathmap != null && remote) {
164 java.util.Iterator i = pathmap.keySet().iterator();
165 while (i.hasNext()) {
166 String k = (String) i.next();
167 if (path.startsWith(k)) {
168 path = pathmap.get(k) + path.substring(k.length());
173 if (pathtranslation && remote) {
174 if (remoteSourcePath.toString().substring(0, 1).equals("/"))
175 path = path.replace('\\', '/');
177 path = path.replace('/', '\\');
182 public void addBreakpoint(IBreakpoint breakpoint) {
187 PHPLineBreakpoint phpLBP;
188 if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier()) {
189 phpLBP = (PHPLineBreakpoint) breakpoint;
190 // bpNo= DBGInt.addBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber());
192 bpNo = DBGInt.addBreakpoint(MapPath(phpLBP), phpLBP.getLineNumber());
193 phpLBP.setDBGBpNo(bpNo);
195 } catch (IOException e) {
196 PHPDebugCorePlugin.log(e);
198 } catch (CoreException e) {
199 PHPDebugCorePlugin.log(e);
204 public void removeBreakpoint(IBreakpoint breakpoint) {
208 PHPLineBreakpoint phpLBP;
209 if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier()) {
210 phpLBP = (PHPLineBreakpoint) breakpoint;
212 // bpNo= DBGInt.addBreakpoint(filename.toOSString(), phpLBP.getLineNumber());
213 DBGInt.removeBreakpoint(MapPath(phpLBP), phpLBP.getLineNumber(), phpLBP.getDBGBpNo());
215 } catch (IOException e) {
216 PHPDebugCorePlugin.log(e);
218 } catch (CoreException e) {
219 PHPDebugCorePlugin.log(e);
224 public void phpLoopNotify() {
225 phpLoop.notifyWait();
228 public void startPHPLoop() {
229 phpLoop = new PHPLoop();
233 public void resume() {
235 DBGInt.continueExecution();
236 phpLoop.notifyWait();
237 } catch (IOException e) {
238 PHPeclipsePlugin.log("Debugging session ended.", e);
243 public void pause() {
246 DBGInt.pauseExecution();
248 // TODO Make sure the Suspend action is grayed out
249 // when DBGInt is null
251 } catch (IOException e) {
252 PHPDebugCorePlugin.log(e);
257 protected PHPDebugTarget getDebugTarget() {
261 public void setDebugTarget(PHPDebugTarget debugTarget) {
262 this.debugTarget = debugTarget;
263 debugTarget.setPHPDBGProxy(this);
266 public PHPVariable[] readVariables(PHPStackFrame frame) {
268 return DBGInt.getVariables(frame);
269 } catch (IOException ioex) {
270 ioex.printStackTrace();
271 throw new RuntimeException(ioex.getMessage());
272 } catch (DebugException ex) {
273 ex.printStackTrace();
274 throw new RuntimeException(ex.getMessage());
278 public PHPVariable[] eval(PHPStackFrame frame, String evalString) {
280 return DBGInt.evalBlock(frame, evalString);
281 // return DBGInt.getVariables(frame);
282 } catch (IOException ioex) {
283 ioex.printStackTrace();
284 throw new RuntimeException(ioex.getMessage());
285 } catch (DebugException ex) {
286 ex.printStackTrace();
287 throw new RuntimeException(ex.getMessage());
291 public void readStepOverEnd(PHPStackFrame stackFrame) {
294 phpLoop.notifyWait();
295 } catch (Exception e) {
296 PHPDebugCorePlugin.log(e);
300 public void readStepReturnEnd(PHPStackFrame stackFrame) {
303 phpLoop.notifyWait();
304 } catch (Exception e) {
305 PHPDebugCorePlugin.log(e);
309 public void readStepIntoEnd(PHPStackFrame stackFrame) {
312 phpLoop.notifyWait();
313 } catch (Exception e) {
314 PHPDebugCorePlugin.log(e);
319 * public PHPStackFrame[] readFrames(PHPThread thread) { //try { //this.println("th " + thread.getId() + " ; f "); //return new
320 * FramesReader(getMultiReaderStrategy()).readFrames(thread); return null; //} catch (IOException e) { //
321 * PHPDebugCorePlugin.log(e); // return null; //}
325 public void closeSocket() throws IOException {
326 if (socket != null) {
331 public void closeServerSocket() throws IOException {
332 if (server != null) {
337 public int getPort() {
341 class PHPLoop extends Thread {
342 private boolean shouldStop;
346 this.setName("PHPDebuggerLoop");
349 public synchronized void setShouldStop() {
352 // If the loop thread is blocked on the server socket,
353 // forcibly unblock it to avoid leaking the thread,
354 // the socket and the port
356 } catch (IOException x) {
357 // Log this as a warning?
358 PHPDebugCorePlugin.log(x);
362 public synchronized void notifyWait() {
368 char[] buf = new char[16];
370 long interval = 200; // 200ms
372 PHPStackFrame[] StackList;
373 boolean endFile = false;
374 boolean newconnect = false;
375 Socket newSocket = null;
376 PHPDBGInterface newDBGInt;
379 // synchronized (this) {
383 PHPMainThread = new PHPThread(getDebugTarget(), getPort());
384 PHPMainThread.setName("Thread [main]");
387 // while ((getDebugTarget() == null) && (timeout < 100)) {
391 // Be sure debug target is set
392 // PHPMainThread.setDebugTarget(getDebugTarget());
393 getDebugTarget().addThread(PHPMainThread);
395 //System.out.println("Waiting for breakpoints.");
396 while (!shouldStop) {
399 newSocket = server.accept();
400 //System.out.println("Accepted! : " + socket.toString());
401 } catch (SocketTimeoutException e) {
402 // no one wants to connect
404 } catch (IOException e) {
405 PHPDebugCorePlugin.log(e);
411 server.setSoTimeout(1);
412 newDBGInt = new PHPDBGInterface(getReader(newSocket), newSocket.getOutputStream(), thisProxy);
413 newDBGInt.waitResponse(1000);
414 newDBGInt.flushAllPackets();
415 // Check version and session ID
416 if ((DBGInt == null) || (DBGInt.getSID() == newDBGInt.getSID())) {
420 } catch (IOException e) {
421 PHPDebugCorePlugin.log(e);
426 DBGInt.continueExecution();
428 newDBGInt.continueExecution();
433 if (DBGInt.waitResponse(interval)) {
435 DBGInt.flushAllPackets();
437 if (DBGInt.BPUnderHit != 0) {
438 StackList = DBGInt.getStackList();
439 if (StackList.length > 0) {
440 for (i = 0; i < StackList.length; i++) {
441 StackList[i].setThread(PHPMainThread);
442 if (DBGInt.getModByNo(StackList[i].getModNo()).equals("")) {
443 DBGInt.getSourceTree();
445 StackList[i].setFile(DBGInt.getModByNo(StackList[i].getModNo()));
447 PHPMainThread.setStackFrames(StackList);
450 PHPMainThread.suspend();
452 synchronized (this) {
458 if (PHPMainThread.isTerminated()) {
463 if (PHPMainThread.isTerminated() || getDebugTarget().getProcess().isTerminated()) {
469 } catch (Exception ex) {
470 PHPDebugCorePlugin.log(ex);
471 System.out.println(ex);
474 getDebugTarget().terminate();
477 } catch (IOException e) {
478 PHPDebugCorePlugin.log(e);
481 //System.out.println("Socket loop finished.");