Contributors:
Vicente Fernando - www.alfersoft.com.ar - Initial implementation
+ Christian Perkonig - remote debug
**********************************************************************/
package net.sourceforge.phpdt.internal.debug.core;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.util.Vector;
-import java.lang.System;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
+
import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
import net.sourceforge.phpdt.internal.debug.core.model.PHPValue;
-import net.sourceforge.phpdt.internal.debug.core.PHPDBGMod;
public class PHPDBGInterface {
private String serGlobals= new String("");
private String typeRead= new String("");
private String className= new String("");
- private int finalPos=0, refCounter=0, rawCounter=0;
+ private int finalPos=0, refCounter=0, rawCounter=1000;
+ private PHPDBGProxy proxy= null;
+
+ private int lastCmd=-1;
+ private int sid=0;
+ private boolean stopOnError= false;
+ private char[] lastCommand= new char[4];
- public PHPDBGInterface(BufferedReader in, OutputStream os) {
+ public PHPDBGInterface(BufferedReader in, OutputStream os, PHPDBGProxy proxy) {
DBGBPList.clear();
this.in= in;
this.os= os;
+ this.proxy= proxy;
}
public int addBreakpoint(String mod_name, int line) throws IOException {
PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_VER);
DBGPacket.addFrame(DBGFrame);
+
+ if(proxy.getSocket().isClosed()) return;
+ DBGPacket.sendPacket(os);
+ }
+
+ public void getSourceTree() throws IOException {
+ PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
+ PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_SRC_TREE);
+
+ DBGPacket.addFrame(DBGFrame);
+
+ if(proxy.getSocket().isClosed()) return;
+ DBGPacket.sendPacket(os);
+
+ // Wait response (1 second) and read response
+ waitResponse(1000);
+ flushAllPackets();
+ }
+
+ public void addDBGModName(String modName) throws IOException {
+ PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
+ PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
+
+ rawCounter++;
+ DBGFrame.addInt(rawCounter); // FRAME_RAWDATA ID
+ DBGFrame.addInt(modName.length() + 1); // length of rawdata (+ null char)
+ DBGFrame.addString(modName); // file name
+ DBGFrame.addChar('\0'); // null char
+
+ DBGPacket.addFrame(DBGFrame);
+ if(proxy.getSocket().isClosed()) return;
DBGPacket.sendPacket(os);
}
// Second add command data
DBGPacket.addFrame(DBGFrame1);
+ if(proxy.getSocket().isClosed()) return 0;
DBGPacket.sendPacket(os);
clearLastBP();
public void continueExecution() throws IOException {
BPUnderHit= 0;
PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_CONTINUE);
+ if(proxy.getSocket().isClosed()) return;
+ DBGPacket.sendPacket(os);
+ lastCommand= PHPDBGBase.DBGA_CONTINUE;
+ }
+
+ public void pauseExecution() throws IOException {
+ PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.IntToChar4(PHPDBGBase.DBGC_PAUSE));
+ if(proxy.getSocket().isClosed()) return;
DBGPacket.sendPacket(os);
}
}
return BPUnder;
}
+
+ public int getLastCmd()
+ {
+ return lastCmd;
+ }
+
+ public int getSID()
+ {
+ return sid;
+ }
+
+ public void setLastCmd(int cmd)
+ {
+ lastCmd=cmd;
+ }
public void stepInto() throws IOException {
BPUnderHit= 0;
PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPINTO);
+ if(proxy.getSocket().isClosed()) return;
DBGPacket.sendPacket(os);
+ lastCommand= PHPDBGBase.DBGA_STEPINTO;
}
public void stepOver() throws IOException {
BPUnderHit= 0;
PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPOVER);
+ if(proxy.getSocket().isClosed()) return;
DBGPacket.sendPacket(os);
+ lastCommand= PHPDBGBase.DBGA_STEPOVER;
}
public void stepOut() throws IOException {
BPUnderHit= 0;
PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPOUT);
+ if(proxy.getSocket().isClosed()) return;
DBGPacket.sendPacket(os);
+ lastCommand= PHPDBGBase.DBGA_STEPOUT;
}
public void stopExecution() throws IOException {
BPUnderHit= 0;
PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STOP);
+ if(proxy.getSocket().isClosed()) return;
DBGPacket.sendPacket(os);
}
public PHPVariable[] getVariables(PHPStackFrame stack) throws IOException, DebugException {
PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
- //PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
DBGFrame1.addInt(0); // istr = raw data ID
DBGFrame1.addInt(1); // scope_id = -1 means current location, 0 never used, +1 first depth
-
- /*
- String evalBlock= new String("$GLOBALS");
- DBGFrame2.addInt(1); // FRAME_RAWDATA ID
- DBGFrame2.addInt(evalBlock.length() + 1); // length of rawdata (+ null char)
- DBGFrame2.addString(evalBlock); // eval block
- DBGFrame2.addChar('\0'); // null char
- */
// Add command data
DBGPacket.addFrame(DBGFrame1);
+ if(proxy.getSocket().isClosed()) return null;
DBGPacket.sendPacket(os);
waitResponse(1000);
return DBGVariableList;
}
+ public void log(String logString) throws IOException, DebugException {
+ PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
+ PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_LOG);
+ PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
+
+ rawCounter++;
+ DBGFrame1.addInt(rawCounter); // ilog
+ DBGFrame1.addInt(1); // type
+ DBGFrame1.addInt(0); // mod_no
+ DBGFrame1.addInt(0); // line_no
+ DBGFrame1.addInt(0); // imod_name
+ DBGFrame1.addInt(0); // ext_info
+
+ DBGFrame2.addInt(rawCounter); // FRAME_RAWDATA ID
+ DBGFrame2.addInt(logString.length() + 1); // length of rawdata (+ null char)
+ DBGFrame2.addString(logString); // log string
+ DBGFrame2.addChar('\0'); // null char
+
+ // Add raw data first
+ DBGPacket.addFrame(DBGFrame2);
+ // Add command data
+ DBGPacket.addFrame(DBGFrame1);
+
+ if(proxy.getSocket().isClosed()) return;
+ DBGPacket.sendPacket(os);
+
+ waitResponse(1000);
+ flushAllPackets();
+ }
+
public void evalBlock(String evalString) throws IOException, DebugException {
PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
rawCounter++;
DBGFrame1.addInt(rawCounter); // istr = raw data ID
- DBGFrame1.addInt(1); // scope_id = -1 means current location, 0 never used, +1 first depth
+ DBGFrame1.addInt(-1); // scope_id = -1 means current location, 0 never used, +1 first depth
DBGFrame2.addInt(rawCounter); // FRAME_RAWDATA ID
DBGFrame2.addInt(evalString.length() + 1); // length of rawdata (+ null char)
DBGFrame2.addChar('\0'); // null char
// Add raw data first
- DBGPacket.addFrame(DBGFrame2);
+ DBGPacket.addFrame(DBGFrame2);
// Add command data
DBGPacket.addFrame(DBGFrame1);
+ if(proxy.getSocket().isClosed()) return;
DBGPacket.sendPacket(os);
waitResponse(1000);
while(readResponse() != 0);
}
- private String getModByNo(int modNo) {
+ public String getModByNo(int modNo) {
int i;
PHPDBGMod dbg_mod;
String value= new String("");
String name= new String("");
String tmp= new String("");
+ String[] tmpSplit;
if(finalPos > serGlobals.length() || serGlobals.equals("") || serGlobals.substring(finalPos).equals("")) return;
hasChildren= false;
isRef= false;
value= readValue(serGlobals.substring(finalPos));
+ // replaceAll doesn't work, why???
+ tmpSplit= value.split("\\\\");
+ value= "";
+ for(i= 0; i < tmpSplit.length; i++) {
+ value= value + tmpSplit[i];
+ if(!tmpSplit[i].equals("")) {
+ if(i < (tmpSplit.length - 1)) {
+ value= value + "\\";
+ }
+ }
+ }
}
if(!name.equals("")) {
public int readResponse() throws IOException {
int bytesToRead=0, nextFrame=0, i=0, cmdReceived=0, stackIndex=0;
+ boolean errorStack= false;
char[] dbg_header_struct_read= new char[16];
int[] dbg_header_struct= new int[4];
int[] dbg_bpl_tmp= new int[10];
int[] dbg_frame= new int[2];
int[] dbg_eval_tmp= new int[3];
+ int[] dbg_src_tree_tmp= new int[4];
+ int[] dbg_error_tmp= new int[2];
Vector rawList= new Vector();
Vector stackList= new Vector();
PHPStackFrame[] newStackList;
if(dbg_header_struct[0] != 0x5953) return 0;
cmdReceived= dbg_header_struct[1];
+ setLastCmd(cmdReceived);
bytesToRead= dbg_header_struct[3];
- System.out.println("Response Received: " + cmdReceived);
-
+ //System.out.println("Response Received: " + cmdReceived);
char[] entirePack= new char[bytesToRead];
if(bytesToRead > 0) {
dbg_stack_new[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8); // scope id
dbg_stack_new[3] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 12); // id of description string
- stackIndex++;
- if(!getModByNo(dbg_stack_new[1]).equals("")) {
- PHPStackFrame newStack= new PHPStackFrame(null, getModByNo(dbg_stack_new[1]), dbg_stack_new[0], stackIndex, getRawFrameData(entirePack, dbg_stack_new[3]));
+ if(dbg_stack_new[1] != 0 && !errorStack) {
+ stackIndex++;
+ PHPStackFrame newStack= new PHPStackFrame(null, getModByNo(dbg_stack_new[1]), dbg_stack_new[0], stackIndex, getRawFrameData(entirePack, dbg_stack_new[3]), dbg_stack_new[1]);
stackList.add(newStack);
}
+ errorStack= false;
break;
case PHPDBGBase.FRAME_SOURCE:
break;
case PHPDBGBase.FRAME_SRC_TREE:
+ dbg_src_tree_tmp[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0); // parent_mod_no
+ dbg_src_tree_tmp[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4); // parent_line_no /* NOT USED */
+ dbg_src_tree_tmp[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8); // mod_no
+ dbg_src_tree_tmp[3] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 12); // imod_name
+
+ if(getModByNo(dbg_src_tree_tmp[2]).equals("")) {
+ String fileName= new String(getRawFrameData(entirePack, dbg_src_tree_tmp[3]));
+ // Remove '\0' char
+ if(fileName.length() > 0) fileName= fileName.substring(0, fileName.length() - 1);
+
+ if(dbg_src_tree_tmp[2] != 0) {
+ PHPDBGMod modNew= new PHPDBGMod(dbg_src_tree_tmp[2], fileName);
+ DBGMods.add(modNew);
+ }
+ }
break;
case PHPDBGBase.FRAME_RAWDATA:
break;
case PHPDBGBase.FRAME_ERROR:
+ errorStack= true;
+ dbg_error_tmp[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0); // type /* type of error */
+ dbg_error_tmp[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4); // imessage /* ID of error message */
+
+ String error= "\n";
+ switch(dbg_error_tmp[0]) {
+ case PHPDBGBase.E_ERROR:
+ error+= "[Error]";
+ break;
+ case PHPDBGBase.E_WARNING:
+ error+= "[Warning]";
+ break;
+ case PHPDBGBase.E_PARSE:
+ error+= "[Parse Error]";
+ break;
+ case PHPDBGBase.E_NOTICE:
+ error+= "[Notice]";
+ break;
+ case PHPDBGBase.E_CORE_ERROR:
+ error+= "[Core Error]";
+ break;
+ case PHPDBGBase.E_CORE_WARNING:
+ error+= "[Core Warning]";
+ break;
+ case PHPDBGBase.E_COMPILE_ERROR:
+ error+= "[Compile Error]";
+ break;
+ case PHPDBGBase.E_COMPILE_WARNING:
+ error+= "[Compile Warning]";
+ break;
+ case PHPDBGBase.E_USER_ERROR:
+ error+= "[User Error]";
+ break;
+ case PHPDBGBase.E_USER_WARNING:
+ error+= "[User Warning]";
+ break;
+ case PHPDBGBase.E_USER_NOTICE:
+ error+= "[User Notice]";
+ break;
+ default:
+ error+= "[Unexpected Error]";
+ break;
+ }
+ error+= ": ";
+ error+= new String(getRawFrameData(entirePack, dbg_error_tmp[1]));
+ // Remove '\0' char
+ if(error.length() > 0) error= error.substring(0, error.length() - 1);
+ error+= "\n";
+
+ PHPDebugCorePlugin.log(new DebugException(new Status(IStatus.WARNING, PHPDebugCorePlugin.PLUGIN_ID, IStatus.OK, error, null)));
+ // To print errors on the console, I must execute a code in the
+ // php context, that write the stderr... I didn't found a better way
+ // TODO: Find a better way????
+ String codeExec= "";
+ codeExec= "fwrite(fopen('php://stderr', 'w'),\\\"" + error + "\\\");";
+ try {
+ evalBlock("eval(\"" + codeExec + "\");");
+ } catch (DebugException e) {
+ PHPDebugCorePlugin.log(e);
+ }
+ if(!stopOnError) {
+ if(lastCommand.equals(PHPDBGBase.DBGA_CONTINUE)) {
+ continueExecution();
+ } else if(lastCommand.equals(PHPDBGBase.DBGA_STEPINTO)) {
+ stepInto();
+ } else if(lastCommand.equals(PHPDBGBase.DBGA_STEPOUT)) {
+ stepOut();
+ } else if(lastCommand.equals(PHPDBGBase.DBGA_STEPOVER)) {
+ stepOver();
+ }
+ }
break;
case PHPDBGBase.FRAME_EVAL:
String evalString= new String("");
String fileName= new String(getRawFrameData(entirePack, dbg_bpl_new[2]));
// Remove '\0' char
if(fileName.length() > 0) fileName= fileName.substring(0, fileName.length() - 1);
- PHPDBGMod modNew= new PHPDBGMod(dbg_bpl_new[0], fileName);
- DBGMods.add(modNew);
+ if(dbg_bpl_new[0] != 0) {
+ PHPDBGMod modNew= new PHPDBGMod(dbg_bpl_new[0], fileName);
+ DBGMods.add(modNew);
+ }
}
break;
case PHPDBGBase.FRAME_VER:
break;
case PHPDBGBase.FRAME_SID:
+ sid = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);
break;
case PHPDBGBase.FRAME_SRCLINESINFO:
break;
case PHPDBGBase.DBGC_STEPOVER_DONE:
case PHPDBGBase.DBGC_STEPOUT_DONE:
case PHPDBGBase.DBGC_EMBEDDED_BREAK:
+ case PHPDBGBase.DBGC_PAUSE:
BPUnderHit= 1;
newStackList= new PHPStackFrame[stackList.size()];
newStackList= (PHPStackFrame[]) stackList.toArray(newStackList);
DBGStackList= newStackList;
break;
case PHPDBGBase.DBGC_ERROR:
+ stackList.clear();
newStackList= new PHPStackFrame[stackList.size()];
newStackList= (PHPStackFrame[]) stackList.toArray(newStackList);
DBGStackList= newStackList;
break;
case PHPDBGBase.DBGC_SID:
break;
- case PHPDBGBase.DBGC_PAUSE:
- break;
}
}
-
return cmdReceived;
}
this.shouldStop= true;
}
- public void waitResponse(long milliseconds) throws IOException {
+ public boolean waitResponse(long milliseconds) throws IOException {
long timeout= System.currentTimeMillis() + milliseconds;
while(System.currentTimeMillis() < timeout) {
if(in.ready() || shouldStop) {
break;
}
}
+ return in.ready();
}
-}
\ No newline at end of file
+}