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;
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 IPHPDebugTarget 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().getBreakpointManager().getBreakpoints();
146 for (int i = 0; i < breakpoints.length; i++) {
147 addBreakpoint(breakpoints[i]);
151 private String MapPath(PHPLineBreakpoint phpLBP) {
154 filename = phpLBP.getMarker().getResource()
155 .getProjectRelativePath();
156 filename = remoteSourcePath.append(filename);
158 filename = phpLBP.getMarker().getResource().getLocation();
159 String path = filename.toOSString();
160 if (pathmap != null && remote) {
161 java.util.Iterator i = pathmap.keySet().iterator();
162 while (i.hasNext()) {
163 String k = (String) i.next();
164 if (path.startsWith(k)) {
165 path = pathmap.get(k) + path.substring(k.length());
170 if (pathtranslation && remote) {
171 if (path.substring(0, 1).equals("/"))
172 path = path.replace('\\', '/');
174 path = path.replace('/', '\\');
179 public void addBreakpoint(IBreakpoint breakpoint) {
184 PHPLineBreakpoint phpLBP;
185 if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier()) {
186 phpLBP = (PHPLineBreakpoint) breakpoint;
187 // bpNo= DBGInt.addBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber());
189 bpNo = DBGInt.addBreakpoint(MapPath(phpLBP), phpLBP.getLineNumber());
190 phpLBP.setDBGBpNo(bpNo);
192 } catch (IOException e) {
193 PHPDebugCorePlugin.log(e);
195 } catch (CoreException e) {
196 PHPDebugCorePlugin.log(e);
201 public void removeBreakpoint(IBreakpoint breakpoint) {
205 PHPLineBreakpoint phpLBP;
206 if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier()) {
207 phpLBP = (PHPLineBreakpoint) breakpoint;
209 // bpNo= DBGInt.addBreakpoint(filename.toOSString(), phpLBP.getLineNumber());
210 DBGInt.removeBreakpoint(MapPath(phpLBP), phpLBP.getLineNumber(), phpLBP.getDBGBpNo());
212 } catch (IOException e) {
213 PHPDebugCorePlugin.log(e);
215 } catch (CoreException e) {
216 PHPDebugCorePlugin.log(e);
221 public void phpLoopNotify() {
222 phpLoop.notifyWait();
225 public void startPHPLoop() {
226 phpLoop = new PHPLoop();
230 public void resume() {
232 DBGInt.continueExecution();
233 phpLoop.notifyWait();
234 } catch (IOException e) {
235 PHPeclipsePlugin.log("Debugging session ended.", e);
240 public void pause() {
243 DBGInt.pauseExecution();
245 // TODO Make sure the Suspend action is grayed out
246 // when DBGInt is null
248 } catch (IOException e) {
249 PHPDebugCorePlugin.log(e);
254 protected IPHPDebugTarget getDebugTarget() {
258 public void setDebugTarget(IPHPDebugTarget debugTarget) {
259 this.debugTarget = debugTarget;
260 debugTarget.setPHPDBGProxy(this);
263 public PHPVariable[] readVariables(PHPStackFrame frame) {
265 return DBGInt.getVariables(frame);
266 } catch (IOException ioex) {
267 ioex.printStackTrace();
268 throw new RuntimeException(ioex.getMessage());
269 } catch (DebugException ex) {
270 ex.printStackTrace();
271 throw new RuntimeException(ex.getMessage());
275 public PHPVariable[] eval(PHPStackFrame frame, String evalString) {
277 return DBGInt.evalBlock(frame, evalString);
278 // return DBGInt.getVariables(frame);
279 } catch (IOException ioex) {
280 ioex.printStackTrace();
281 throw new RuntimeException(ioex.getMessage());
282 } catch (DebugException ex) {
283 ex.printStackTrace();
284 throw new RuntimeException(ex.getMessage());
288 public void readStepOverEnd(PHPStackFrame stackFrame) {
291 phpLoop.notifyWait();
292 } catch (Exception e) {
293 PHPDebugCorePlugin.log(e);
297 public void readStepReturnEnd(PHPStackFrame stackFrame) {
300 phpLoop.notifyWait();
301 } catch (Exception e) {
302 PHPDebugCorePlugin.log(e);
306 public void readStepIntoEnd(PHPStackFrame stackFrame) {
309 phpLoop.notifyWait();
310 } catch (Exception e) {
311 PHPDebugCorePlugin.log(e);
316 * public PHPStackFrame[] readFrames(PHPThread thread) { //try { //this.println("th " + thread.getId() + " ; f "); //return new
317 * FramesReader(getMultiReaderStrategy()).readFrames(thread); return null; //} catch (IOException e) { //
318 * PHPDebugCorePlugin.log(e); // return null; //}
322 public void closeSocket() throws IOException {
323 if (socket != null) {
328 public void closeServerSocket() throws IOException {
329 if (server != null) {
334 public int getPort() {
338 class PHPLoop extends Thread {
339 private boolean shouldStop;
343 this.setName("PHPDebuggerLoop");
346 public synchronized void setShouldStop() {
349 // If the loop thread is blocked on the server socket,
350 // forcibly unblock it to avoid leaking the thread,
351 // the socket and the port
353 } catch (IOException x) {
354 // Log this as a warning?
355 PHPDebugCorePlugin.log(x);
359 public synchronized void notifyWait() {
365 char[] buf = new char[16];
367 long interval = 200; // 200ms
369 PHPStackFrame[] StackList;
370 boolean endFile = false;
371 boolean newconnect = false;
372 Socket newSocket = null;
373 PHPDBGInterface newDBGInt;
376 // synchronized (this) {
380 PHPMainThread = new PHPThread(getDebugTarget(), getPort());
381 PHPMainThread.setName("Thread [main]");
384 // while ((getDebugTarget() == null) && (timeout < 100)) {
388 // Be sure debug target is set
389 // PHPMainThread.setDebugTarget(getDebugTarget());
390 getDebugTarget().addThread(PHPMainThread);
392 //System.out.println("Waiting for breakpoints.");
393 while (!shouldStop) {
396 newSocket = server.accept();
397 //System.out.println("Accepted! : " + socket.toString());
398 } catch (SocketTimeoutException e) {
399 // no one wants to connect
401 } catch (IOException e) {
402 PHPDebugCorePlugin.log(e);
408 server.setSoTimeout(1);
409 newDBGInt = new PHPDBGInterface(getReader(newSocket), newSocket.getOutputStream(), thisProxy);
410 newDBGInt.waitResponse(1000);
411 newDBGInt.flushAllPackets();
412 // Check version and session ID
413 if ((DBGInt == null) || (DBGInt.getSID() == newDBGInt.getSID())) {
417 } catch (IOException e) {
418 PHPDebugCorePlugin.log(e);
423 DBGInt.continueExecution();
425 newDBGInt.continueExecution();
430 if (DBGInt.waitResponse(interval)) {
432 DBGInt.flushAllPackets();
434 if (DBGInt.BPUnderHit != 0) {
435 StackList = DBGInt.getStackList();
436 if (StackList.length > 0) {
437 for (i = 0; i < StackList.length; i++) {
438 StackList[i].setThread(PHPMainThread);
439 if (DBGInt.getModByNo(StackList[i].getModNo()).equals("")) {
440 DBGInt.getSourceTree();
442 StackList[i].setFile(DBGInt.getModByNo(StackList[i].getModNo()));
444 PHPMainThread.setStackFrames(StackList);
447 PHPMainThread.suspend();
449 synchronized (this) {
455 if (PHPMainThread.isTerminated()) {
460 if (PHPMainThread.isTerminated() || getDebugTarget().getProcess().isTerminated()) {
466 } catch (Exception ex) {
467 PHPDebugCorePlugin.log(ex);
468 System.out.println(ex);
471 getDebugTarget().terminate();
474 } catch (IOException e) {
475 PHPDebugCorePlugin.log(e);
478 //System.out.println("Socket loop finished.");