1 /**********************************************************************
2 Copyright (c) 2000, 2002 IBM Corp. and others.
3 All rights reserved. This program and the accompanying materials
4 are made available under the terms of the Common Public License v1.0
5 which accompanies this distribution, and is available at
6 http://www.eclipse.org/legal/cpl-v10.html
9 Vicente Fernando - www.alfersoft.com.ar - Initial implementation
10 Christian Perkonig - remote debug
11 **********************************************************************/
12 package net.sourceforge.phpdt.internal.debug.core;
14 import java.io.BufferedReader;
15 import java.io.IOException;
16 import java.io.OutputStream;
17 import java.util.Vector;
18 import java.util.Collections;
20 import net.sourceforge.phpdt.internal.debug.core.model.PHPDBGEvalString;
21 import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
22 import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
23 import net.sourceforge.phpdt.internal.debug.core.model.PHPValue;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.core.runtime.Status;
27 import org.eclipse.debug.core.DebugException;
29 import java.io.RandomAccessFile;
32 * The interface object are created by the proxy
35 public class PHPDBGInterface {
37 public boolean sessionEnded = false;
38 public int sessType = -1;
39 public int BPUnderHit = 0;
40 public String sessID = new String ();
42 private int[] LastBPRead = new int[10];
43 private Vector DBGBPList = new Vector ();
44 private Vector DBGVarList = new Vector ();
45 private PHPStackFrame[] DBGStackList;
46 private Vector DBGMods = new Vector (); // The module names and their numbers
47 private Vector stackListOld = new Vector ();
48 private BufferedReader in;
49 private OutputStream os; // The stream which goes to DBG
50 private boolean shouldStop = false;
51 private String evalRet = new String ("");
52 private String serGlobals = new String ("");
53 private int rawCounter = 1000; // An rawData frame ID counter
54 private PHPDBGProxy proxy = null;
55 private int lastCmd = -1;
57 private boolean stopOnError = false;
58 private char[] lastCommand = new char[4];
61 * @param in The input stream (communication from DBG).
62 * @param os The output stream (communication to DBG).
63 * @param proxy The proxy to which this interface belongs.
65 public PHPDBGInterface (BufferedReader in, OutputStream os, PHPDBGProxy proxy) {
75 * @param mod_name The module (source file) to which we add the breakpoint.
76 * @param line The line where the breakpoint is set.
77 * @return Breakpoint ID ???.
79 public int addBreakpoint (String mod_name, int line) throws IOException {
80 return setBreakpoint (mod_name, "", line, PHPDBGBase.BPS_ENABLED + PHPDBGBase.BPS_UNRESOLVED, 0, 0, 0, 0, 0);
85 * @param mod_name The module (source file) to which we add the breakpoint.
86 * @param line The line where the breakpoint is set.
87 * @param bpNo The breakpoint ID ???.
89 public void removeBreakpoint (String mod_name, int line, int bpNo) throws IOException {
90 setBreakpoint (mod_name, "", line, PHPDBGBase.BPS_DISABLED, 0, 0, 0, bpNo, 0);
94 * Is this method used anywhere?
97 public void requestDBGVersion () throws IOException {
98 PHPDBGPacket DBGPacket; // A DBG message packet
99 PHPDBGFrame DBGFrame; // A frame within a DBG packet
101 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST); // A request for DBG
102 DBGFrame = new PHPDBGFrame (PHPDBGBase.FRAME_VER); // We want the version of DBG
104 DBGPacket.addFrame (DBGFrame); // Add the 'what we want' to the DBG packet
106 if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG?
110 DBGPacket.sendPacket (os); // Send the request to DBG
114 * Called by the proxy
117 public void getSourceTree () throws IOException {
118 PHPDBGPacket DBGPacket; // A DBG message packet
119 PHPDBGFrame DBGFrame; // A frame within a DBG packet
121 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST); // A request for DBG
122 DBGFrame = new PHPDBGFrame (PHPDBGBase.FRAME_SRC_TREE); // We want a source tree from DBG
124 DBGPacket.addFrame (DBGFrame); // Add the 'what we want' to the DBG packet
126 if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG?
130 DBGPacket.sendPacket (os); // Send the request to DBG
132 waitResponse (1000); // Wait for the DBG response (1 second)
133 flushAllPackets (); // Read and process the response from DBG
137 * Is this method called from anywhere?
139 * @param modName The modul (filename).
141 public void addDBGModName (String modName) throws IOException {
142 PHPDBGPacket DBGPacket; // A DBG message packet
143 PHPDBGFrame DBGFrame; // A frame within a DBG packet
145 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST); // A request for DBG
146 DBGFrame = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA); // We want Module name from DBG
148 rawCounter++; // Increment the rawData ID counter
149 DBGFrame.addInt (rawCounter); // FRAME_RAWDATA ID
150 DBGFrame.addInt (modName.length () + 1); // The length of rawdata string (incl. null char termination)
151 DBGFrame.addString (modName); // The file name (module name)
152 DBGFrame.addChar ('\0'); // Add the C-String null termination
154 DBGPacket.addFrame (DBGFrame);
156 if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG?
160 DBGPacket.sendPacket (os);
164 * This method is called for adding or removing breakpoints.
166 * @param mod_name The module name (file name).
167 * @param condition Info about the condition when to break (not used at the moment).
168 * @param line The breakpoints line.
169 * @param state Info whether this breakpoint has to be dis- or enabled.
170 * @param istep Always 0.
171 * @param hitcount Always 0.
172 * @param skiphits Always 0.
173 * @param bpno The breakpoint ID.
174 * @param isunderhit ???
177 private int setBreakpoint (String mod_name, String condition, int line, int state, int istemp, int hitcount, int skiphits, int bpno, int isunderhit) throws IOException {
178 PHPDBGPacket DBGPacket;
179 PHPDBGFrame DBGFrame1;
180 PHPDBGFrame DBGFrame2;
183 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);
184 DBGFrame1 = new PHPDBGFrame (PHPDBGBase.FRAME_BPS);
185 DBGFrame2 = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);
187 modNo = getModByName (mod_name); // Get the module ID by name
189 if (modNo >= 0) { // Did we find a module ID for the module name?
190 DBGFrame1.addInt (modNo); // Add the module ID to frame 1
192 DBGFrame1.addInt (0); // mod number (0 use file name)
195 DBGFrame1.addInt (line); // line number
197 if (modNo >= 0) { // Did we find a module ID for the module name?
198 DBGFrame1.addInt (0); // use mod number
201 DBGFrame1.addInt (rawCounter); // ID of FRAME_RAWDATA to send file name
204 DBGFrame1.addInt (state); // state BPS_*
205 DBGFrame1.addInt (istemp); // istep
206 DBGFrame1.addInt (hitcount); // hit count
207 DBGFrame1.addInt (skiphits); // skip hits
208 DBGFrame1.addInt (0); // ID of condition
209 DBGFrame1.addInt (bpno); // breakpoint number
210 DBGFrame1.addInt (isunderhit); // is under hit
212 if (modNo < 0) { // Did we find a module ID for the module name?
213 DBGFrame2.addInt (rawCounter); // FRAME_RAWDATA ID
214 DBGFrame2.addInt (mod_name.length() + 1); // length of rawdata (+ null char)
215 DBGFrame2.addString (mod_name); // file name
216 DBGFrame2.addChar ('\0'); // null char
218 DBGPacket.addFrame (DBGFrame2); // First add file name data
221 DBGPacket.addFrame (DBGFrame1); // Second add command data
223 if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG?
227 DBGPacket.sendPacket (os); // Send the request to DBG
231 waitResponse (1000); // Wait for the DBG response (1 second)
232 flushAllPackets (); // Read and process the response from DBG
234 return LastBPRead[8]; // Return what ???
240 private void clearLastBP () {
243 for (i = 0; i < LastBPRead.length; i++) {
251 private void copyToLastBP (int[] BPBody) {
254 for (i = 0; i < LastBPRead.length; i++) {
255 LastBPRead[i] = BPBody[i];
262 public void continueExecution () throws IOException {
263 PHPDBGPacket DBGPacket;
266 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_CONTINUE);
268 if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG?
272 DBGPacket.sendPacket (os); // Send the request to DBG
274 lastCommand = PHPDBGBase.DBGA_CONTINUE; // Store the info about the command we sent
280 public void pauseExecution () throws IOException {
281 PHPDBGPacket DBGPacket;
283 DBGPacket = new PHPDBGPacket (PHPDBGBase.IntToChar4 (PHPDBGBase.DBGC_PAUSE));
285 if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG?
289 DBGPacket.sendPacket (os); // Send the request to DBG
295 private int getBPUnderHit () {
298 int[] dbg_bpl_body = new int[10];
300 for (i = 0; i < DBGBPList.size (); i++) { // look for bp under hit
301 dbg_bpl_body = (int[]) DBGBPList.get (i);
303 if (dbg_bpl_body[9] == 1) {
304 BPUnder = dbg_bpl_body[8];
311 public int getLastCmd()
321 public void setLastCmd (int cmd)
329 public void stepInto () throws IOException {
330 PHPDBGPacket DBGPacket;
333 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_STEPINTO);
335 if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG?
339 DBGPacket.sendPacket (os); // Send the request to DBG
341 lastCommand = PHPDBGBase.DBGA_STEPINTO; // Store the info about the command we sent
347 public void stepOver () throws IOException {
348 PHPDBGPacket DBGPacket;
351 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_STEPOVER);
353 if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG?
357 DBGPacket.sendPacket (os); // Send the request to DBG
359 lastCommand = PHPDBGBase.DBGA_STEPOVER; // Store the info about the command we sent
365 public void stepOut () throws IOException {
366 PHPDBGPacket DBGPacket;
369 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_STEPOUT);
371 if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG?
375 DBGPacket.sendPacket (os); // Send the request to DBG
377 lastCommand = PHPDBGBase.DBGA_STEPOUT; // Store the info about the command we sent
383 public void stopExecution () throws IOException {
384 PHPDBGPacket DBGPacket;
387 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_STOP);
389 if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG?
393 DBGPacket.sendPacket (os); // Send the request to DBG
397 * This method is called by the proxy.
398 * It sends a request to DBG to get the current variables
399 * with their values. It waits for the response and processes
400 * the input from DBG.
402 * @param stack The stackframe for which we want the variables.
403 * @return The array of variables
405 public Vector getVariables (PHPStackFrame stack) throws IOException, DebugException {
406 PHPDBGPacket DBGPacket;
407 PHPDBGFrame DBGFrame1;
408 PHPDBGEvalString evalStr;
410 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST); //
411 DBGFrame1 = new PHPDBGFrame (PHPDBGBase.FRAME_EVAL); //
413 DBGFrame1.addInt (0); // istr = raw data ID
414 DBGFrame1.addInt (1); // scope_id = -1 means current location, 0 never used, +1 first depth
416 DBGPacket.addFrame (DBGFrame1); // Add command data
418 if (proxy.getSocket ().isClosed ()) { // Do we have a socket for DBG communication?
419 return null; // No, then leave here
422 DBGPacket.sendPacket (os); // Send the request to DBG
424 waitResponse (1000); // Wait for the DBG response (1 second)
425 flushAllPackets (); // Read and process the response from DBG
427 evalStr = new PHPDBGEvalString (stack, serGlobals); // Process serialized variables
428 DBGVarList = evalStr.getVariables ();
430 PHPVariable var = (PHPVariable) DBGVarList.get (0);
432 if (var.getName ().equals ("")) { // The eclipse variable view cannot handle Variables which have an empty name
433 // when it comes to variable tree restore operation. Without a name, no restore!
434 var.setName (" "); // Give a name to the variable root node. Even if it is only a space :.)
435 } // TODO the best would be to remove the empty root node, but this would
436 // require a understanding and reworking of the PHPDBGEvalstring class.
439 return DBGVarList; // Return the variables as list
446 public void log(String logString) throws IOException, DebugException {
447 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
448 PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_LOG);
449 PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
452 DBGFrame1.addInt(rawCounter); // ilog
453 DBGFrame1.addInt(1); // type
454 DBGFrame1.addInt(0); // mod_no
455 DBGFrame1.addInt(0); // line_no
456 DBGFrame1.addInt(0); // imod_name
457 DBGFrame1.addInt(0); // ext_info
459 DBGFrame2.addInt(rawCounter); // FRAME_RAWDATA ID
460 DBGFrame2.addInt(logString.length() + 1); // length of rawdata (+ null char)
461 DBGFrame2.addString(logString); // log string
462 DBGFrame2.addChar('\0'); // null char
464 // Add raw data first
465 DBGPacket.addFrame(DBGFrame2);
467 DBGPacket.addFrame(DBGFrame1);
469 if(proxy.getSocket().isClosed()) return;
470 DBGPacket.sendPacket(os);
476 public PHPVariable[] evalBlock(PHPStackFrame stack, String evalString) throws IOException, DebugException {
477 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
478 PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
479 PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
482 DBGFrame1.addInt(rawCounter); // istr = raw data ID
483 DBGFrame1.addInt(1); // scope_id = -1 means current location, 0 never used, +1 first depth
485 DBGFrame2.addInt(rawCounter); // FRAME_RAWDATA ID
486 DBGFrame2.addInt(evalString.length() + 1); // length of rawdata (+ null char)
487 DBGFrame2.addString(evalString); // eval block
488 DBGFrame2.addChar('\0'); // null char
490 // Add raw data first
491 DBGPacket.addFrame(DBGFrame2);
493 DBGPacket.addFrame(DBGFrame1);
495 if(proxy.getSocket().isClosed()) return null;
496 DBGPacket.sendPacket(os);
501 PHPDBGEvalString evalStr=new PHPDBGEvalString(stack,evalRet);
503 return evalStr.getVars();
508 * Read and process everthing we got from DBG
510 public void flushAllPackets () throws IOException {
511 while (readResponse() != 0);
515 * Get the modules name by its number
517 * @param modNo The number (id) of the module
518 * @return The name of the module
520 public String getModByNo (int modNo) {
524 for (i = 0; i < DBGMods.size (); i++) { // For all the modules we have within the array
525 dbg_mod = (PHPDBGMod) DBGMods.get (i); // Get the module
527 if (dbg_mod.getNo () == modNo) { // Is the module from the array the module we want?
528 return dbg_mod.getName (); // Yes, return the name of the module
532 return ""; // If nothing was found return emtpy string
537 * @param modName The name of the module for which we want the ID
539 * - The ID of the module
540 * - -1 if nothing was found
542 private int getModByName (String modName) {
546 for (i = 0; i < DBGMods.size (); i++) { // For all the modules we have within the array
547 dbg_mod = (PHPDBGMod) DBGMods.get (i); // Get the module
549 if (dbg_mod.getName ().equalsIgnoreCase (modName)) { // Is the module from the array the module we want?
550 return dbg_mod.getNo (); // Yes, return the name of the module
554 return -1; // If nothing was found return -1
558 * Return the string for the given frame number
560 * @param framesInfo The buffer which is to read
561 * @param frameNo The frame number
564 private String getRawFrameData (char[] framesInfo, int frameNo) {
565 int nextFrame = 0; // The current read position within the buffer
566 int[] dbg_frame = new int[2]; // The two frame header numbers
568 while (nextFrame < framesInfo.length) { // As long we have something within the buffer
569 dbg_frame[0] = PHPDBGBase.Char4ToInt (framesInfo, nextFrame); // The frame type
570 dbg_frame[1] = PHPDBGBase.Char4ToInt (framesInfo, nextFrame + 4); // The frame size
572 nextFrame += 8; // The current read position
574 if (dbg_frame[1] == 0) { // If frame size is 0
575 return ""; // return an emtpy string
578 switch (dbg_frame[0]) { // Switch for the frame type
579 case PHPDBGBase.FRAME_RAWDATA: // The only frame type we are interrested in
580 if (frameNo == PHPDBGBase.Char4ToInt (framesInfo, nextFrame)) { // Is it correct number of the frame
583 toRead = PHPDBGBase.Char4ToInt (framesInfo, nextFrame + 4); // The size of the string
585 return String.copyValueOf (framesInfo, nextFrame + 8, toRead); // Copy frame content to String and return
590 nextFrame += dbg_frame[1]; // Go for the next frame (add the length of the current one)
593 return ""; // We did not found any FRAM_RAWDATA, so return an emtpy strin
598 * The stackList contains the currently read stackframes which were sent
599 * from DBG. The DBG interface holds a list of the active stack frames.
600 * This method replicates the 'static' stackframe list with the DBG stackframe list
601 * Replication is done in the following way:
603 * <li> It looks for new stackframes within the DBG stackframe list and
604 * adds them to the 'static' list.
605 * <li> It looks for stackframes within the 'static' list, and removes them
606 * from the 'static' list in case the do not appear within the DBG list.
607 * <li> It looks for stackframes which are already existent and replicates the
608 * line number and the index number.
609 * <li> At the end the 'static' stackfram list has to be sorted by the stackframes
613 * Removes the unused stackframes from the list, or adds stackframes which
614 * are not yet in the list.
619 private void updateStackFrameList (Vector stackList) {
622 PHPStackFrame stackFrameNew;
623 PHPStackFrame stackFrameOld;
624 PHPStackFrame[] newStackList;
626 for (i = 0; i < stackList.size (); i++) { // For all stackList entries
627 stackFrameNew = (PHPStackFrame) stackList.get(i);
629 for (n = 0; n < stackListOld.size (); n++) { // For all StackFrames in the StackFrame list
630 stackFrameOld = (PHPStackFrame) stackListOld.get (n); //
632 if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ())) { // Did we find the sent stackframe within the list of old stackframes?
633 stackFrameOld.setLineNumber (stackFrameNew.getLineNumber ());
634 stackFrameOld.setIndex (stackFrameNew.getIndex ());
636 break; // Yes, then break;
640 if (n == stackListOld.size ()) { // Did not find the new stackframe within the list
641 stackListOld.add (stackFrameNew); // then add the new stackframe
645 // And now for removing unused stackframes from list
647 for (n = 0; n < stackListOld.size (); n++) { // For all StackFrames in the StackFrame list
648 stackFrameOld = (PHPStackFrame) stackListOld.get (n); //
650 for (i = 0; i < stackList.size (); i++) { // For all stackList entries
651 stackFrameNew = (PHPStackFrame) stackList.get (i);
653 if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ())) { // Did we find the sent stackframe within the list of old stackframes?
654 break; // Yes, then break;
658 if (i == stackList.size ()) { // Did not find the old stackframe within the list of new ones
659 stackListOld.remove (n); // then remove the old stackframe from list
660 n -= 1; // Adjust the stack list index
664 Collections.sort (stackListOld); // Sort the 'static' stackframe list by the stackframe index numbers.
666 newStackList = new PHPStackFrame[stackListOld.size ()];
667 newStackList = (PHPStackFrame[]) stackListOld.toArray (newStackList);
668 DBGStackList = newStackList;
672 * Read the response from DBG and process the frame
675 * - The received command
676 * - or 0 if something was wrong
678 public int readResponse () throws IOException {
679 int bytesToRead = 0; // The number of byte to read for the current DBG block
680 int nextFrame = 0; // The current read position within entirePack
684 boolean errorStack = false;
685 char[] dbg_header_struct_read = new char[16]; // The buffer for the first 16 bytes of a block
686 int[] dbg_header_struct = new int[4]; // The first four numbers (long) of a block
687 int[] dbg_bpl_tmp = new int[10];
688 int[] dbg_frame = new int[2];
689 int[] dbg_eval_tmp = new int[3];
690 int[] dbg_src_tree_tmp = new int[4]; //
691 int[] dbg_error_tmp = new int[2];
692 Vector rawList = new Vector();
693 Vector stackList = new Vector(); // Intermediate stacklist which is build up in FRAME_STACK frame
699 while (readInput (dbg_header_struct_read, 16) != 0) { // Read 16 byte from input stream
700 dbg_header_struct[0] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 0); // Debug sync header
701 dbg_header_struct[1] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 4); // Command
702 dbg_header_struct[2] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 8); //
703 dbg_header_struct[3] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 12); // Bytes within this block
705 if (dbg_header_struct[0] != 0x5953) { // Check DBG sync bytes
706 return 0; // Wrong header
709 cmdReceived = dbg_header_struct[1]; // Get the command
710 setLastCmd (cmdReceived); // Store the info about the current command
711 bytesToRead = dbg_header_struct[3]; // Get the number of bytes to read for this block
713 //System.out.println("Response Received: " + cmdReceived);
714 char[] entirePack = new char[bytesToRead]; // Store the block data into buffer 'entirePack'
716 if (bytesToRead > 0) { // If there is something within the frame
717 if (readInput (entirePack, bytesToRead) < bytesToRead) { // Read the frame into the buffer
718 return 0; // We did not read enough bytes, error
722 nextFrame = 0; // Start with the first frame
724 while (nextFrame < bytesToRead) { // As long as we have something within this block
725 dbg_frame[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame); // The name of the frame
726 dbg_frame[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4); // The size of the frame
727 nextFrame += 8; // The next read position
729 if (dbg_frame[1] == 0) { // Something within the frame?
730 return 0; // Nothing to read, error
733 switch (dbg_frame[0]) {
734 case PHPDBGBase.FRAME_STACK:
735 int[] dbg_stack_new = new int[4]; //
737 dbg_stack_new[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0); // Source line number
738 dbg_stack_new[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4); // Module number
739 dbg_stack_new[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8); // Scope id
740 dbg_stack_new[3] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 12); // ID of description string
742 if ((dbg_stack_new[1] != 0) && !errorStack) {
743 PHPStackFrame newStack;
746 newStack = new PHPStackFrame (null, // The thread
747 getModByNo (dbg_stack_new[1]), // The name of the module (file)
748 dbg_stack_new[0], // The source line number
750 getRawFrameData (entirePack, // Get the string from this packet
751 dbg_stack_new[3]), // The frame ID for which we want the string
752 dbg_stack_new[1]); // The module number
753 stackList.add (newStack);
759 case PHPDBGBase.FRAME_SOURCE: // Nothing to be done here
760 break; // TODO: what's with that frame? Something interesting
762 case PHPDBGBase.FRAME_SRC_TREE: //
763 dbg_src_tree_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0); // The parent module number
764 dbg_src_tree_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4); // The parent line number (not used)
765 dbg_src_tree_tmp[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8); // The module number
766 dbg_src_tree_tmp[3] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 12); // The filename number
768 if (getModByNo (dbg_src_tree_tmp[2]).equals ("")) {
771 fileName = new String (getRawFrameData (entirePack, dbg_src_tree_tmp[3])); // Get the filename
773 if (fileName.length () > 0) { // If we have a filename
774 fileName = fileName.substring (0, fileName.length () - 1); // Remove '\0' char
777 if (dbg_src_tree_tmp[2] != 0) { // If there is a module number
780 modNew = new PHPDBGMod (dbg_src_tree_tmp[2], fileName); // Create a module object
782 DBGMods.add (modNew); // And store it to array
787 case PHPDBGBase.FRAME_RAWDATA: // Nothing to be done here
788 break; // FRAME_RAWDATA are processed within getRawFrameData
790 case PHPDBGBase.FRAME_ERROR: // An error frame
791 errorStack = true; // Yes, we have an error stack
792 dbg_error_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0); // Error type
793 dbg_error_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4); // Error message ID
795 String error = "\n"; //
797 switch (dbg_error_tmp[0]) { // Switch on error type
798 case PHPDBGBase.E_ERROR: error += "[Error]"; break;
799 case PHPDBGBase.E_WARNING: error += "[Warning]"; break;
800 case PHPDBGBase.E_PARSE: error += "[Parse Error]"; break;
801 case PHPDBGBase.E_NOTICE: error += "[Notice]"; break;
802 case PHPDBGBase.E_CORE_ERROR: error += "[Core Error]"; break;
803 case PHPDBGBase.E_CORE_WARNING: error += "[Core Warning]"; break;
804 case PHPDBGBase.E_COMPILE_ERROR: error += "[Compile Error]"; break;
805 case PHPDBGBase.E_COMPILE_WARNING: error += "[Compile Warning]"; break;
806 case PHPDBGBase.E_USER_ERROR: error += "[User Error]"; break;
807 case PHPDBGBase.E_USER_WARNING: error += "[User Warning]"; break;
808 case PHPDBGBase.E_USER_NOTICE: error += "[User Notice]"; break;
809 default: error += "[Unexpected Error]"; break;
813 error += new String (getRawFrameData (entirePack, dbg_error_tmp[1])); // Add the error string for this error message ID
815 if (error.length () > 0) { // If we have a error message
816 error = error.substring (0, error.length () - 1); // Remove '\0' char
819 error += "\n"; // Append a CR
821 PHPDebugCorePlugin.log (new DebugException (new Status (IStatus.WARNING,
822 PHPDebugCorePlugin.PLUGIN_ID,
826 // To print errors on the console, I must execute a code in the
827 // php context, that write the stderr... I didn't found a better way
828 // TODO: Find a better way????
830 // String codeExec= "";
831 // codeExec= "fwrite(fopen('php://stderr', 'w'),\\\"" + error + "\\\");";
833 // evalBlock("eval(\"" + codeExec + "\");");
834 // } catch (DebugException e) {
835 // PHPDebugCorePlugin.log(e);
838 if (!stopOnError) { // Is always false (Did not see where this is set to true!?)
839 if (lastCommand.equals (PHPDBGBase.DBGA_CONTINUE)) { // If last command for PHP was a 'continue',
840 continueExecution (); // send continue again
841 } else if (lastCommand.equals (PHPDBGBase.DBGA_STEPINTO)) { // If last command for PHP was a 'step into',
842 stepInto (); // send 'step into' again
843 } else if (lastCommand.equals (PHPDBGBase.DBGA_STEPOUT)) { // If last command for PHP was a 'step out',
844 stepOut (); // send 'step out' again
845 } else if (lastCommand.equals (PHPDBGBase.DBGA_STEPOVER)) { // If last command for PHP was a 'step over',
846 stepOver (); // send 'step over' again
851 case PHPDBGBase.FRAME_EVAL:
854 evalString = new String ("");
855 dbg_eval_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0); // istr
856 dbg_eval_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4); // iresult
857 dbg_eval_tmp[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8); // ierror
859 evalRet = getRawFrameData (entirePack, dbg_eval_tmp[1]); //
860 evalString = getRawFrameData (entirePack, dbg_eval_tmp[0]); //
861 serGlobals = evalRet; //
864 case PHPDBGBase.FRAME_BPS: //
867 case PHPDBGBase.FRAME_BPL:
870 dbg_bpl_new = new int[10];
871 dbg_bpl_new[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);
872 dbg_bpl_new[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);
873 dbg_bpl_new[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8);
874 dbg_bpl_new[3] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 12);
875 dbg_bpl_new[4] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 16);
876 dbg_bpl_new[5] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 20);
877 dbg_bpl_new[6] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 24);
878 dbg_bpl_new[7] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 28);
879 dbg_bpl_new[8] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 32);
880 dbg_bpl_new[9] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 36);
882 // look if breakpoint already exists in vector
883 for (i = 0; i < DBGBPList.size (); i++) {
884 dbg_bpl_tmp = (int[]) DBGBPList.get (i);
886 if (dbg_bpl_tmp[8] == dbg_bpl_new[8]) {
887 DBGBPList.remove (i);
893 // add breakpoint to vector
894 DBGBPList.add (dbg_bpl_new);
895 copyToLastBP (dbg_bpl_new);
898 if (getModByNo (dbg_bpl_new[0]).equals ("")) {
901 fileName = new String (getRawFrameData (entirePack, dbg_bpl_new[2]));
903 if (fileName.length () > 0) { // If we have filename
904 fileName = fileName.substring (0, fileName.length () - 1); // Remove '\0' char
907 if (dbg_bpl_new[0] != 0) {
910 modNew = new PHPDBGMod (dbg_bpl_new[0], fileName);
912 DBGMods.add (modNew);
917 case PHPDBGBase.FRAME_VER:
920 case PHPDBGBase.FRAME_SID:
921 sid = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);
924 case PHPDBGBase.FRAME_SRCLINESINFO:
927 case PHPDBGBase.FRAME_SRCCTXINFO:
930 case PHPDBGBase.FRAME_LOG:
933 case PHPDBGBase.FRAME_PROF:
936 case PHPDBGBase.FRAME_PROF_C:
939 case PHPDBGBase.FRAME_SET_OPT:
943 nextFrame += dbg_frame[1]; // go to next frame
946 // Now process command
947 switch(cmdReceived) {
948 case PHPDBGBase.DBGC_REPLY:
951 case PHPDBGBase.DBGC_STARTUP:
954 case PHPDBGBase.DBGC_END:
958 case PHPDBGBase.DBGC_BREAKPOINT:
959 BPUnderHit = getBPUnderHit ();
960 updateStackFrameList (stackList);
963 case PHPDBGBase.DBGC_STEPINTO_DONE:
964 case PHPDBGBase.DBGC_STEPOVER_DONE:
965 case PHPDBGBase.DBGC_STEPOUT_DONE:
966 case PHPDBGBase.DBGC_EMBEDDED_BREAK:
967 case PHPDBGBase.DBGC_PAUSE:
969 updateStackFrameList (stackList);
972 case PHPDBGBase.DBGC_ERROR:
974 updateStackFrameList (stackList);
977 case PHPDBGBase.DBGC_LOG:
980 case PHPDBGBase.DBGC_SID:
985 return cmdReceived; // Return the command we received with this block
992 public PHPStackFrame[] getStackList() {
997 * Reads from input buffer (response sent from DBG) the given number of chars
1000 * @param buffer The frame buffer where to store the read data from DBG.
1001 * @param bytes The number of bytes (chars) which are to read from input stream.
1002 * @return The number of bytes actually read.
1004 private int readInput (char[] buffer, int bytes) throws IOException {
1005 int bytesRead = 0; // Reset the bytes read counter
1007 for (int i = 0; i < bytes; i++) { // For the number of bytes we should read
1008 if (in.ready ()) { // If input stream is ready for reading
1009 buffer[i] = (char) (in.read () & 0x00FF); // Read a char and store only the least significant 8-bits
1010 bytesRead++; // Increment the bytes read counter
1012 else { // Input stream is not ready
1013 break; // Break the loop
1017 return bytesRead; // Return the number of bytes actually read
1021 * PHPProxy could stop the waiting for a response with this method.
1024 public void setShouldStop () {
1025 this.shouldStop = true;
1029 * @param milliseconds The maximum time in milliseconds we wait for something
1030 * to be send from DBG.
1031 * @return - true if something was received from DBG
1032 * - false if nothing was send from DBG within the given time
1035 public boolean waitResponse (long milliseconds) throws IOException {
1038 timeout = System.currentTimeMillis () + milliseconds; // Calculate the system time till we wait.
1040 while (System.currentTimeMillis () < timeout) { // Is waiting time running out?
1041 if (in.ready () || shouldStop) { // No, so did we get something or should we stop now
1042 break; // Yes, break the waiting
1046 return in.ready (); // true if we got something from DBG