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.logview.LogView;
21 import net.sourceforge.phpdt.internal.debug.core.model.IPHPDebugTarget;
22 import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
23 import net.sourceforge.phpdt.internal.debug.core.model.PHPThread;
24 import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
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;
32 import org.eclipse.ui.IViewPart;
33 import org.eclipse.ui.IWorkbenchPage;
35 public class PHPDBGProxy {
37 private ServerSocket server = null;
39 private Socket socket;
41 private BufferedReader reader = null;
43 private PHPDBGInterface DBGInt = null;
45 private IPHPDebugTarget debugTarget = null;
47 private PHPLoop phpLoop;
49 private PHPThread PHPMainThread;
51 private PHPDBGProxy thisProxy = null;
55 private boolean remote;
57 private boolean pathtranslation;
61 private IPath remoteSourcePath;
63 public PHPDBGProxy() {
67 public PHPDBGProxy(boolean remote, String remoteSourcePath,boolean pathTranslate,Map paths) {
70 this.remoteSourcePath = new Path(remoteSourcePath);
72 this.pathtranslation=pathTranslate;
81 phpLoop.setShouldStop();
83 DBGInt.setShouldStop();
86 getDebugTarget().getProcess().terminate();
87 } catch (DebugException e) {
94 protected ServerSocket getServerSocket() throws IOException {
101 protected void createServerSocket() {
102 port = SocketUtil.findUnusedLocalPort("localhost", 10001, 10101);
105 PHPDebugCorePlugin.log(5, "Cannot find free port!!!!");
109 if (server == null) {
110 server = new ServerSocket(port);
111 //System.out.println("ServerSocket on port: " + port);
113 } catch (IOException e) {
115 PHPDebugCorePlugin.log(e);
120 public Socket getSocket() throws IOException {
124 protected void setDBGInterface(PHPDBGInterface DBGInt) {
125 this.DBGInt = DBGInt;
128 public BufferedReader getReader() throws IOException {
129 if (reader == null) {
130 reader = new BufferedReader(new InputStreamReader(this.getSocket().getInputStream(), "ISO8859_1"));
135 public BufferedReader getReader(Socket socket) throws IOException {
137 return new BufferedReader(new InputStreamReader(socket.getInputStream(), "ISO8859_1"));
142 public OutputStream getOutputStream() throws IOException {
143 return this.getSocket().getOutputStream();
146 protected void setBreakPoints() throws IOException, CoreException {
147 IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints();
148 for (int i = 0; i < breakpoints.length; i++) {
149 addBreakpoint(breakpoints[i]);
153 private String MapPath(PHPLineBreakpoint phpLBP) {
156 filename = phpLBP.getMarker().getResource()
157 .getProjectRelativePath();
158 filename = remoteSourcePath.append(filename);
160 filename = phpLBP.getMarker().getResource().getLocation();
161 String path = filename.toOSString();
162 if (pathmap != null && remote) {
163 java.util.Iterator i = pathmap.keySet().iterator();
164 while (i.hasNext()) {
165 String k = (String) i.next();
166 if (path.startsWith(k)) {
167 path = pathmap.get(k) + path.substring(k.length());
172 if (pathtranslation && remote) {
173 if (path.substring(0, 1).equals("/"))
174 path = path.replace('\\', '/');
176 path = path.replace('/', '\\');
181 public void addBreakpoint(IBreakpoint breakpoint) {
186 PHPLineBreakpoint phpLBP;
187 if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier()) {
188 phpLBP = (PHPLineBreakpoint) breakpoint;
189 // bpNo= DBGInt.addBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber());
191 bpNo = DBGInt.addBreakpoint(MapPath(phpLBP), phpLBP.getLineNumber());
192 phpLBP.setDBGBpNo(bpNo);
194 } catch (IOException e) {
195 PHPDebugCorePlugin.log(e);
197 } catch (CoreException e) {
198 PHPDebugCorePlugin.log(e);
203 public void removeBreakpoint(IBreakpoint breakpoint) {
207 PHPLineBreakpoint phpLBP;
208 if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier()) {
209 phpLBP = (PHPLineBreakpoint) breakpoint;
211 // bpNo= DBGInt.addBreakpoint(filename.toOSString(), phpLBP.getLineNumber());
212 DBGInt.removeBreakpoint(MapPath(phpLBP), phpLBP.getLineNumber(), phpLBP.getDBGBpNo());
214 } catch (IOException e) {
215 PHPDebugCorePlugin.log(e);
217 } catch (CoreException e) {
218 PHPDebugCorePlugin.log(e);
223 public void phpLoopNotify() {
224 phpLoop.notifyWait();
227 public void startPHPLoop() {
228 phpLoop = new PHPLoop();
232 public void resume() {
234 DBGInt.continueExecution();
235 phpLoop.notifyWait();
236 } catch (IOException e) {
237 PHPDebugCorePlugin.log(e);
242 public void pause() {
245 DBGInt.pauseExecution();
247 // TODO Make sure the Suspend action is grayed out
248 // when DBGInt is null
250 } catch (IOException e) {
251 PHPDebugCorePlugin.log(e);
256 protected IPHPDebugTarget getDebugTarget() {
260 public void setDebugTarget(IPHPDebugTarget debugTarget) {
261 this.debugTarget = debugTarget;
262 debugTarget.setPHPDBGProxy(this);
265 public PHPVariable[] readVariables(PHPStackFrame frame) {
267 return DBGInt.getVariables(frame);
268 } catch (IOException ioex) {
269 ioex.printStackTrace();
270 throw new RuntimeException(ioex.getMessage());
271 } catch (DebugException ex) {
272 ex.printStackTrace();
273 throw new RuntimeException(ex.getMessage());
277 public PHPVariable[] eval(PHPStackFrame frame, String evalString) {
279 return DBGInt.evalBlock(frame, evalString);
280 // return DBGInt.getVariables(frame);
281 } catch (IOException ioex) {
282 ioex.printStackTrace();
283 throw new RuntimeException(ioex.getMessage());
284 } catch (DebugException ex) {
285 ex.printStackTrace();
286 throw new RuntimeException(ex.getMessage());
290 public void readStepOverEnd(PHPStackFrame stackFrame) {
293 phpLoop.notifyWait();
294 } catch (Exception e) {
295 PHPDebugCorePlugin.log(e);
299 public void readStepReturnEnd(PHPStackFrame stackFrame) {
302 phpLoop.notifyWait();
303 } catch (Exception e) {
304 PHPDebugCorePlugin.log(e);
308 public void readStepIntoEnd(PHPStackFrame stackFrame) {
311 phpLoop.notifyWait();
312 } catch (Exception e) {
313 PHPDebugCorePlugin.log(e);
318 * public PHPStackFrame[] readFrames(PHPThread thread) { //try { //this.println("th " + thread.getId() + " ; f "); //return new
319 * FramesReader(getMultiReaderStrategy()).readFrames(thread); return null; //} catch (IOException e) { //
320 * PHPDebugCorePlugin.log(e); // return null; //}
324 public void closeSocket() throws IOException {
325 if (socket != null) {
330 public void closeServerSocket() throws IOException {
331 if (server != null) {
336 public int getPort() {
340 class PHPLoop extends Thread {
341 private boolean shouldStop;
345 this.setName("PHPDebuggerLoop");
348 public synchronized void setShouldStop() {
351 // If the loop thread is blocked on the server socket,
352 // forcibly unblock it to avoid leaking the thread,
353 // the socket and the port
355 } catch (IOException x) {
356 // Log this as a warning?
357 PHPDebugCorePlugin.log(x);
361 public synchronized void notifyWait() {
367 char[] buf = new char[16];
369 long interval = 200; // 200ms
371 PHPStackFrame[] StackList;
372 boolean endFile = false;
373 boolean newconnect = false;
374 Socket newSocket = null;
375 PHPDBGInterface newDBGInt;
378 // synchronized (this) {
382 PHPMainThread = new PHPThread(getDebugTarget(), getPort());
383 PHPMainThread.setName("Thread [main]");
386 // while ((getDebugTarget() == null) && (timeout < 100)) {
390 // Be sure debug target is set
391 // PHPMainThread.setDebugTarget(getDebugTarget());
392 getDebugTarget().addThread(PHPMainThread);
394 //System.out.println("Waiting for breakpoints.");
395 while (!shouldStop) {
398 newSocket = server.accept();
399 //System.out.println("Accepted! : " + socket.toString());
400 } catch (SocketTimeoutException e) {
401 // no one wants to connect
403 } catch (IOException e) {
404 PHPDebugCorePlugin.log(e);
410 server.setSoTimeout(1);
411 newDBGInt = new PHPDBGInterface(getReader(newSocket), newSocket.getOutputStream(), thisProxy);
412 newDBGInt.waitResponse(1000);
413 newDBGInt.flushAllPackets();
414 // Check version and session ID
415 if ((DBGInt == null) || (DBGInt.getSID() == newDBGInt.getSID())) {
419 } catch (IOException e) {
420 PHPDebugCorePlugin.log(e);
425 DBGInt.continueExecution();
427 newDBGInt.continueExecution();
432 if (DBGInt.waitResponse(interval)) {
434 DBGInt.flushAllPackets();
436 if (DBGInt.BPUnderHit != 0) {
437 StackList = DBGInt.getStackList();
438 if (StackList.length > 0) {
439 for (i = 0; i < StackList.length; i++) {
440 StackList[i].setThread(PHPMainThread);
441 if (DBGInt.getModByNo(StackList[i].getModNo()).equals("")) {
442 DBGInt.getSourceTree();
444 StackList[i].setFile(DBGInt.getModByNo(StackList[i].getModNo()));
446 PHPMainThread.setStackFrames(StackList);
449 PHPMainThread.suspend();
451 synchronized (this) {
457 if (PHPMainThread.isTerminated()) {
462 if (PHPMainThread.isTerminated() || getDebugTarget().getProcess().isTerminated()) {
468 } catch (Exception ex) {
469 PHPDebugCorePlugin.log(ex);
470 System.out.println(ex);
473 getDebugTarget().terminate();
476 } catch (IOException e) {
477 PHPDebugCorePlugin.log(e);
480 //System.out.println("Socket loop finished.");