1) Although dbg will be dropped from being supported or bundled with PHPeclipse,...
[phpeclipse.git] / net.sourceforge.phpeclipse.debug.core / src / net / sourceforge / phpdt / internal / debug / core / PHPDBGInterface.java
index 79a9ae5..d2262ae 100644 (file)
@@ -14,10 +14,10 @@ package net.sourceforge.phpdt.internal.debug.core;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Vector;
 
+//import net.sourceforge.phpdt.internal.debug.core.PHPDBGProxy.PHPLoop;
 import net.sourceforge.phpdt.internal.debug.core.model.PHPDBGEvalString;
 import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
 import net.sourceforge.phpdt.internal.debug.core.model.PHPValue;
@@ -32,43 +32,47 @@ import org.eclipse.debug.core.DebugException;
  *
  */
 public class PHPDBGInterface {
-       public boolean                  sessionEnded = false;
-       public int                              sessType = -1;
-       public int                              BPUnderHit = 0;
-       public String                           sessID = new String();
-
-       private int[]                           LastBPRead = new int[10];
-       private Vector                  DBGBPList = new Vector();
-       private Vector                  DBGVarList = new Vector();
+       public boolean                      sessionEnded = false;
+       public int                              sessType     = -1;
+       public int                              BPUnderHit   = 0;
+       public String                           sessID       = new String();
+
+       private int[]                           LastBPRead   = new int[10];
+       private Vector                      DBGBPList    = new Vector();
+       private Vector                      DBGVarList   = new Vector();
        private PHPStackFrame[]         DBGStackList = new PHPStackFrame[0];
-       private Vector                  DBGMods = new Vector();                         // The module names and their numbers
-       private Vector                  stackListOld = new Vector();
-       private BufferedReader  in;
-       private OutputStream            os;                                                             // The stream which goes to DBG
-       private boolean                         shouldStop = false;
-       private String                  evalRet = new String("");
-       //private String                        serGlobals = new String("");
-       private int                             rawCounter = 1000;                                      // An rawData frame ID counter
-       private PHPDBGProxy             proxy = null;
-       private int                             lastCmd = -1;
-       private int                             sid = 0;
-       private boolean                         stopOnError = false;
-       private char[]                  lastCommand = new char[4];
+       private Vector                  DBGMods      = new Vector();                    // The module names and their numbers
+       private Vector                      stackListOld = new Vector();
+       private BufferedReader          dbgInput;
+       private OutputStream            dbgOutput;                                                      // The stream which goes to DBG
+       private boolean                         shouldStop   = false;
+       private String                      evalRet      = new String("");
+       private int                             rawCounter   = 1000;                                    // An rawData frame ID counter
+       private PHPDBGProxy             proxy        = null;
+//  private int                                lastCmd      = -1;
+       private int                             sid          = 0;
+       private boolean                         stopOnError  = false;                                   // If we the debugger should be relaunched after script termination
+       private boolean             bRelaunch    = true;
+       private char[]                  lastCommand  = new char[4];
+       private boolean             bBusy        = false;
+       private boolean             bDebug       = true;                                        // Prints text to console for debugging purposes
 
        private static final String GlobalVariablesTitle = PHPDebugCorePlugin
                        .getResourceString("VariablesView.GlobalVariables.title");
 
        /**
-        * @param in    The input stream (communication from DBG).
-        * @param os    The output stream (communication to DBG).
-        * @param proxy The proxy to which this interface belongs.
+        * @param in        The input stream (communication from DBG).
+        * @param os        The output stream (communication to DBG).
+        * @param proxy     The proxy to which this interface belongs.
+        * @param bRelaunch The debugger should be relaunched after PHP script termination
         */
-       public PHPDBGInterface (BufferedReader in, OutputStream os, PHPDBGProxy proxy) {
+       public PHPDBGInterface (BufferedReader in, OutputStream os, PHPDBGProxy proxy, boolean bRelaunch) {
                DBGBPList.clear ();
 
-               this.in         = in;
-               this.os         = os;
-               this.proxy      = proxy;
+               this.dbgInput   = in;
+               this.dbgOutput  = os;
+               this.proxy              = proxy;
+               this.bRelaunch  = bRelaunch;
        }
 
        /**
@@ -97,21 +101,21 @@ public class PHPDBGInterface {
         * Is this method used anywhere?
         *
         */
-       public void requestDBGVersion () throws IOException {
-               PHPDBGPacket DBGPacket;                                     // A DBG message packet
-               PHPDBGFrame  DBGFrame;                                      // A frame within a DBG packet
-
-               DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     // A request for DBG
-               DBGFrame  = new PHPDBGFrame (PHPDBGBase.FRAME_VER);         // We want the version of DBG
-
-               DBGPacket.addFrame (DBGFrame);                              // Add the 'what we want' to the DBG packet
-
-               if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
-                       return;                                                 //  No
-               }
-
-               DBGPacket.sendPacket (os);                                                                      // Send the request to DBG
-       }
+//     public void requestDBGVersion () throws IOException {
+//             PHPDBGPacket DBGPacket;                                     // A DBG message packet
+//             PHPDBGFrame  DBGFrame;                                      // A frame within a DBG packet
+//
+//             DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     // A request for DBG
+//             DBGFrame  = new PHPDBGFrame (PHPDBGBase.FRAME_VER);         // We want the version of DBG
+//
+//             DBGPacket.addFrame (DBGFrame);                              // Add the 'what we want' to the DBG packet
+//
+//             if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
+//                     return;                                                 //  No
+//             }
+//
+//             DBGPacket.sendPacket (os);                                                                      // Send the request to DBG
+//     }
 
        /**
         * Called by the proxy
@@ -121,16 +125,26 @@ public class PHPDBGInterface {
                PHPDBGPacket DBGPacket;                                     // A DBG message packet
                PHPDBGFrame  DBGFrame;                                      // A frame within a DBG packet
 
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: getSourceTree");
+               }
+
                DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     // A request for DBG
                DBGFrame  = new PHPDBGFrame (PHPDBGBase.FRAME_SRC_TREE);        // We want a source tree from DBG
 
                DBGPacket.addFrame (DBGFrame);                              // Add the 'what we want' to the DBG packet
 
                if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
+                       bBusy = false;
                        return;                                                                                                 //  No
                }
 
-               DBGPacket.sendPacket (os);                                  // Send the request to DBG
+               DBGPacket.sendPacket (dbgOutput);                           // Send the request to DBG
 
                waitResponse (1000);                                        // Wait for the DBG response (1 second)
                flushAllPackets ();                                                                             // Read and process the response from DBG
@@ -141,27 +155,27 @@ public class PHPDBGInterface {
         *
         * @param modName The modul (filename).
         */
-       public void addDBGModName (String modName) throws IOException {
-               PHPDBGPacket DBGPacket;                                     // A DBG message packet
-               PHPDBGFrame  DBGFrame;                                      // A frame within a DBG packet
-
-               DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     // A request for DBG
-               DBGFrame  = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);     // We want Module name from DBG
-
-               rawCounter++;                                               // Increment the rawData ID counter
-               DBGFrame.addInt (rawCounter);                                                           // FRAME_RAWDATA ID
-               DBGFrame.addInt (modName.length () + 1);                                        // The length of rawdata string (incl. null char termination)
-               DBGFrame.addString (modName);                                                           // The file name (module name)
-               DBGFrame.addChar ('\0');                                                                        // Add the C-String null termination
-
-               DBGPacket.addFrame (DBGFrame);
-
-               if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
-                       return;                                                                                                 //  No
-               }
-
-               DBGPacket.sendPacket (os);
-       }
+//     public void addDBGModName (String modName) throws IOException {
+//             PHPDBGPacket DBGPacket;                                     // A DBG message packet
+//             PHPDBGFrame  DBGFrame;                                      // A frame within a DBG packet
+//
+//             DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     // A request for DBG
+//             DBGFrame  = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);     // We want Module name from DBG
+//
+//             rawCounter++;                                               // Increment the rawData ID counter
+//             DBGFrame.addInt (rawCounter);                                                           // FRAME_RAWDATA ID
+//             DBGFrame.addInt (modName.length () + 1);                                        // The length of rawdata string (incl. null char termination)
+//             DBGFrame.addString (modName);                                                           // The file name (module name)
+//             DBGFrame.addChar ('\0');                                                                        // Add the C-String null termination
+//
+//             DBGPacket.addFrame (DBGFrame);
+//
+//             if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
+//                     return;                                                                                                 //  No
+//             }
+//
+//             DBGPacket.sendPacket (os);
+//     }
 
        /**
         * This method is called for adding or removing breakpoints.
@@ -184,6 +198,15 @@ public class PHPDBGInterface {
                PHPDBGFrame             DBGFrame3;
                int                     modNo;
 
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: setBreakpoint");
+               }
+
                DBGPacket       = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);
                DBGFrame1       = new PHPDBGFrame (PHPDBGBase.FRAME_BPS);
                DBGFrame2       = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);
@@ -241,10 +264,11 @@ public class PHPDBGInterface {
                DBGPacket.addFrame (DBGFrame1);                                                         // Second add command data
 
                if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
+                       bBusy = false;
                        return 0;                                               //  No
                }
 
-               DBGPacket.sendPacket (os);                                  // Send the request to DBG
+               DBGPacket.sendPacket (dbgOutput);                           // Send the request to DBG
 
                clearLastBP ();
 
@@ -282,14 +306,17 @@ public class PHPDBGInterface {
        public void continueExecution () throws IOException {
                PHPDBGPacket DBGPacket;
 
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: continueExecution");
+               }
+
                BPUnderHit = 0;
                DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_CONTINUE);
 
                if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
                        return;                                                 //  No
                }
-
-               DBGPacket.sendPacket (os);                                  // Send the request to DBG
+               DBGPacket.sendPacket (dbgOutput);                           // Send the request to DBG
 
                lastCommand = PHPDBGBase.DBGA_CONTINUE;                     // Store the info about the command we sent
        }
@@ -300,13 +327,17 @@ public class PHPDBGInterface {
        public void pauseExecution () throws IOException {
                PHPDBGPacket DBGPacket;
 
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: pauseExecution");
+               }
+
                DBGPacket = new PHPDBGPacket (PHPDBGBase.IntToChar4 (PHPDBGBase.DBGC_PAUSE));
 
                if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
                         return;                                                //  No
                }
 
-               DBGPacket.sendPacket (os);                                  // Send the request to DBG
+               DBGPacket.sendPacket (dbgOutput);                           // Send the request to DBG
        }
 
        /**
@@ -328,10 +359,10 @@ public class PHPDBGInterface {
                return BPUnder;
        }
 
-       public int getLastCmd()
-       {
-               return lastCmd;
-       }
+//     public int getLastCmd()
+//     {
+//             return lastCmd;
+//     }
 
        public int getSID()
        {
@@ -340,78 +371,129 @@ public class PHPDBGInterface {
 
        public void setLastCmd (int cmd)
        {
-               lastCmd = cmd;
+               //lastCmd = cmd;
        }
 
        /**
         *
         */
-       public void stepInto () throws IOException {
+       public boolean stepInto () throws IOException {
                PHPDBGPacket DBGPacket;
 
+               if (bBusy) {
+                       if (bDebug) {
+                               System.out.println ("PHPDBGInterface: stepOver vetoed");
+                       }
+               }
+
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: stepInto");
+               }
+
                BPUnderHit = 0;
                DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STEPINTO);
 
                if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
-                       return;                                                 //  No
+                       return false;                                           //  No
                }
 
-               DBGPacket.sendPacket (os);                                  // Send the request to DBG
+               DBGPacket.sendPacket (dbgOutput);                           // Send the request to DBG
 
                lastCommand = PHPDBGBase.DBGA_STEPINTO;                                         // Store the info about the command we sent
+
+               return true;
        }
 
        /**
         *
         */
-       public void stepOver () throws IOException {
+       public boolean stepOver () throws IOException {
                PHPDBGPacket DBGPacket;
 
+               if (bBusy) {
+                       if (bDebug) {
+                               System.out.println ("PHPDBGInterface: stepOver vetoed");
+                       }
+               }
+
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: stepOver");
+               }
+
                BPUnderHit = 0;
                DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STEPOVER);
 
                if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
-                       return;                                                 //  No
+                       return false;                                           //  No
                }
 
-               DBGPacket.sendPacket (os);                                  // Send the request to DBG
+               DBGPacket.sendPacket (dbgOutput);                           // Send the request to DBG
 
                lastCommand = PHPDBGBase.DBGA_STEPOVER;                     // Store the info about the command we sent
+
+               return true;
        }
 
        /**
         *
         */
-       public void stepOut () throws IOException {
+       public boolean stepOut () throws IOException {
                PHPDBGPacket DBGPacket;
 
+               if (bBusy) {
+                       if (bDebug) {
+                               System.out.println ("PHPDBGInterface: stepOver vetoed");
+                       }
+               }
+
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: stepOut");
+               }
+
                BPUnderHit = 0;
                DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STEPOUT);
 
                if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
-                       return;                                                 //  No
+                       return false;                                           //  No
                }
 
-               DBGPacket.sendPacket (os);                                  // Send the request to DBG
+               DBGPacket.sendPacket (dbgOutput);                           // Send the request to DBG
 
                lastCommand = PHPDBGBase.DBGA_STEPOUT;                      // Store the info about the command we sent
+
+               return true;
        }
 
        /**
         *
         */
-       public void stopExecution () throws IOException {
-               PHPDBGPacket DBGPacket;
-
-               BPUnderHit = 0;
-               DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STOP);
-
-               if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
-                       return;                                                 //  No
-               }
-
-               DBGPacket.sendPacket (os);                                  // Send the request to DBG
-       }
+//     public void stopExecution () throws IOException {
+//             PHPDBGPacket DBGPacket;
+//
+//             BPUnderHit = 0;
+//             DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STOP);
+//
+//             if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
+//                     return;                                                 //  No
+//             }
+//
+//             DBGPacket.sendPacket (os);                                  // Send the request to DBG
+//     }
 
        /**
         * This method is called by the proxy.
@@ -423,67 +505,50 @@ public class PHPDBGInterface {
         * @return      The array of variables
         */
        public synchronized Vector getVariables(PHPStackFrame stack) throws IOException, DebugException {
-               PHPDBGPacket            DBGPacket;
-               PHPDBGFrame             DBGFrame1;
-               PHPDBGEvalString        evalStr;
-
-               Vector globalList = new Vector();
-               // IStackFrame[] stacks = stack.getThread().getStackFrames();
-               // ( PHPStackFrame.getThread().getStackFrames() returns DBGStackList )
-               if (DBGStackList.length > 1) {
-                       // get global variables (and assign them to 'main()' stackframe)
-                       globalList = getVariables(DBGStackList[DBGStackList.length - 1], PHPDBGBase.GLOBAL_SCOPE_ID);
-                       if (!globalList.isEmpty()) {
-                               // remove unexpected '$this=?' variable
-                               PHPVariable var = (PHPVariable) globalList.get(0);
-                               PHPValue val = (PHPValue) var.getValue();
-                               Vector workList = val.getChildVariables();
-                               for (int i = 0; i < workList.size(); i++) {
-                                       if (((PHPVariable) workList.get(i)).getName().equals("$this")) {
-                                               workList.remove(i);
-                                               break;
-                                       }
-                               }
-                               var.setName(GlobalVariablesTitle);
-                               var.setModifiable(false);
-                       }
+               if (DBGStackList.length == 0) {
+                       DBGVarList.clear();
+
+                       return DBGVarList;
                }
 
-//             DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     //
-//         DBGFrame1 = new PHPDBGFrame (PHPDBGBase.FRAME_EVAL);        //
-//
-//             DBGFrame1.addInt (0);                                                                           // istr = raw data ID
-//             DBGFrame1.addInt (1);                                                                           // scope_id = -1 means current location, 0 never used, +1 first depth
-//
-//             DBGPacket.addFrame (DBGFrame1);                             // Add command data
-//
-//             if (proxy.getSocket ().isClosed ()) {                       // Do we have a socket for DBG communication?
-//                     return new Vector ();                                                                   // No, then leave here with an empty vector 
-//             }
-//
-//             serGlobals = "";
-//             DBGPacket.sendPacket (os);                                  // Send the request to DBG
-//
-//             waitResponse (1000);                                        // Wait for the DBG response (1 second)
-//             flushAllPackets ();                                         // Read and process the response from DBG
-//
-//             evalStr         = new PHPDBGEvalString (stack, serGlobals); // Process serialized variables
-//             DBGVarList      = evalStr.getVariables ();
+               // get global variables (and assign them to 'main()' stackframe)
+               int global_scope_id = (DBGStackList.length > 1) ? 2 : PHPDBGBase.GLOBAL_SCOPE_ID;
+               // DBG 2.13.1 doesn't return Super Globals with GLOBAL_SCOPE_ID in nested stackframes,
+               // so using 2(most out-standing stack context) instead of GLOBAL_SCOPE_ID.
+               // Also note that 2.13.1 doesn't return $this in class context.
+               // (You can inspect $this in Expressions View. And once it is shown, 2.13.1 comes to return $this.)
+               Vector globalList = getVariables(DBGStackList[DBGStackList.length - 1], global_scope_id);
 
-               int scopeID = stack.getScopeID(); 
-               if (scopeID == PHPDBGBase.CURLOC_SCOPE_ID) {
-                       // current stackframe
-                       DBGVarList = getVariables(stack, PHPDBGBase.CURLOC_SCOPE_ID);
-               } else if ((scopeID == PHPDBGBase.CURLOC_SCOPE_ID + 1) && !globalList.isEmpty()) {
+               if (!globalList.isEmpty()) {
+                       // remove unresolved '$this=?' variable
+                       removeUnresolvedThisVar(globalList);
+
+                       PHPVariable var = (PHPVariable) globalList.get(0);
+                       var.setName(GlobalVariablesTitle);
+                       var.setModifiable(false);
+               }
+
+               int scopeID = stack.getScopeID();
+
+               if (!globalList.isEmpty () &&
+                   ((DBGStackList.length == 1) || (scopeID == PHPDBGBase.CURLOC_SCOPE_ID + 1))) {
                        // 'main()' stackframe
                        PHPVariable var = (PHPVariable) globalList.get(0);
-                       PHPValue val = (PHPValue) var.getValue();
-                       DBGVarList = val.getChildVariables();
+                       PHPValue    val = (PHPValue) var.getValue();
+
+                       DBGVarList      = val.getChildVariables();
+
                        return DBGVarList;
-               } else {
+               }
+               else if (scopeID == PHPDBGBase.CURLOC_SCOPE_ID) {
+                       // current stackframe
+                       DBGVarList = getVariables(stack, PHPDBGBase.CURLOC_SCOPE_ID);
+               }
+               else {
                        // back-trace stackframe
-                       // Never: DBGVarList = getVariables(stack, scopeID);
-                       // DBG 2.15.5 causes Application Error (on win32) in some cases
+                       //DBGVarList = getVariables(stack, scopeID);
+                       //removeUnresolvedThisVar(DBGVarList);
+                       // DBG 2.15.5 causes Application Error (on win32) in *some* cases.
                        DBGVarList.clear();
                }
 
@@ -500,7 +565,7 @@ public class PHPDBGInterface {
                                                                                                                                        // The eclipse variable view cannot handle Variables which have an empty name
                                                                                                                                        // when it comes to variable tree restore operation. Without a name, no restore!
                                //var.setName (" ");                                                            // Give a name to the variable root node. Even if it is only a space :-)
-                       }                                                                                                               // TODO the best would be to remove the empty root node, but this would
+                       }                                                                                                               // TO DO the best would be to remove the empty root node, but this would
                                                                                                                                        // require a understanding and reworking of the PHPDBGEvalstring class.
                }
 
@@ -512,13 +577,27 @@ public class PHPDBGInterface {
        }
 
        /**
-        * 
-        * @throws IOException 
+        *
         */
        private Vector getVariables(PHPStackFrame stack, int scope_id) throws IOException {
                PHPDBGPacket DBGPacket = new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
                PHPDBGFrame DBGFrame1 = new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
 
+               if (bBusy) {
+                       if (bDebug) {
+                               System.out.println ("PHPDBGInterface: getVariables vetoed");
+                       }
+               }
+
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: getVariables");
+               }
+
                DBGFrame1.addInt(0);
                DBGFrame1.addInt(scope_id);
 
@@ -526,17 +605,52 @@ public class PHPDBGInterface {
                evalRet = "";
 
                if (proxy.getSocket().isClosed()) {
+                       bBusy = false;
                        return new Vector();
                }
-               DBGPacket.sendPacket(os);
+
+               DBGPacket.sendPacket(dbgOutput);
+
                waitResponse(1000);
                flushAllPackets();
 
+               bBusy = false;                                                          // Already done in flushAllPackets ()
+
                PHPDBGEvalString evalStr = new PHPDBGEvalString(stack, evalRet);
                return evalStr.getVariables();
        }
 
        /**
+        * Remove unresolved $this variable
+        *
+        * DBG returns $this=? in function's or intermediate stackframes.
+        * (In current method's stackframe, DBG returns $this=classname)
+        *
+        * @param varList
+        */
+       private void removeUnresolvedThisVar(Vector varList) {
+               if (varList.size() > 0) {
+                       PHPVariable var       = (PHPVariable) varList.get(0);
+                       PHPValue    val       = (PHPValue) var.getValue();
+                       Vector      workList  = val.getChildVariables ();
+
+                       for (int i = 0; i < workList.size(); i++) {
+                               PHPVariable workvar = (PHPVariable) workList.get(i);
+
+                               if (workvar.getName().equals ("$this")) {
+                                       String workval = ((PHPValue) workvar.getValue ()).getValueString ();
+
+                                       if (workval.equals ("?") ||
+                                           workval.equals ("NULL")) {
+                                               workList.remove (i);
+                                       }
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       /**
         *
         * @param logString
         */
@@ -545,6 +659,15 @@ public class PHPDBGInterface {
                PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_LOG);
                PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
 
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: log");
+               }
+
                rawCounter++;
                DBGFrame1.addInt(rawCounter);                           // ilog
                DBGFrame1.addInt(1);                                            // type
@@ -564,10 +687,11 @@ public class PHPDBGInterface {
                DBGPacket.addFrame(DBGFrame1);
 
                if (proxy.getSocket ().isClosed ()) {                   // Do we have a socket for DBG communication?
+                       bBusy = false;
                        return;                                                                                         //  No, then leave here
                }
 
-               DBGPacket.sendPacket(os);
+               DBGPacket.sendPacket(dbgOutput);
 
                waitResponse(1000);
                flushAllPackets();
@@ -578,10 +702,25 @@ public class PHPDBGInterface {
                PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
                PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
 
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: evalBlock");
+               }
+
                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(stack.getScopeID());
+               int scope_id = stack.getScopeID();
+               /* test code : unnecessary
+               if (DBGStackList.length == 1 || scope_id == (PHPDBGBase.CURLOC_SCOPE_ID + 1)) {
+                       scope_id = PHPDBGBase.GLOBAL_SCOPE_ID;
+               }
+               */
+               DBGFrame1.addInt(scope_id);
 
                DBGFrame2.addInt(rawCounter);                           // FRAME_RAWDATA ID
                DBGFrame2.addInt(evalString.length() + 1);      // length of rawdata (+ null char)
@@ -594,14 +733,16 @@ public class PHPDBGInterface {
                DBGPacket.addFrame(DBGFrame1);
 
                if (proxy.getSocket().isClosed()) {                     // Do we have a socket for DBG communication?
+                       bBusy = false;
                        return null;                                                    //  No, then leave here
                }
-               DBGPacket.sendPacket(os);
+
+               DBGPacket.sendPacket(dbgOutput);
 
                waitResponse(1000);
                flushAllPackets();
 
-               PHPDBGEvalString evalStr=new PHPDBGEvalString(stack,evalRet);
+               PHPDBGEvalString evalStr=new PHPDBGEvalString(stack, evalRet);
 
                return evalStr.getVars();
        }
@@ -734,6 +875,7 @@ public class PHPDBGInterface {
                                stackFrameOld.setAvailable (true);                                      // We found the new stackframe in the list of old stack frames
                 stackFrameOld.setIndex (stackFrameNew.getIndex ());
                 stackFrameOld.setScopeID(stackFrameNew.getScopeID());
+
                                return true;                                                            // The stackframe was found in the list
                        }
                }
@@ -764,7 +906,7 @@ public class PHPDBGInterface {
                        if (isStackFrameInList (stackFrameNew, oldList)) {                          // Is this stackframe in the list
                                stackFrameNew.setAvailable (true);                                                                              //
                                                                                                                                                                                //
-                               break;
+//                             break;
                        }
                }
        }
@@ -799,6 +941,10 @@ public class PHPDBGInterface {
                PHPStackFrame   stackFrameOld;
                PHPStackFrame[] newStackList;
 
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: updateStackFrameList Start");
+               }
+
                markIdenticalStackFrames (stackListOld, stackList);                     // Check whether the newly send stack frames can be found in the list
                                                                                                                                                                // of old stack frames
 
@@ -832,17 +978,11 @@ public class PHPDBGInterface {
 
                // And now for removing unused stackframes from list
 
-               for (n = 0; n < stackListOld.size (); n++) {                                            // For all StackFrames in the StackFrame list
-                       stackFrameOld = (PHPStackFrame) stackListOld.get (n);                           //
-
-                       i = 0;
-                       if (!stackFrameOld.isAvailable ()) {
-                               i = stackList.size ();
-                       }
+               for (n = 0; n < stackListOld.size(); n++) {
+                       stackFrameOld = (PHPStackFrame) stackListOld.get(n);
 
-                       if (i == stackList.size ()) {                                           // Did not find the old stackframe within the list of new ones
-                                stackListOld.remove (n);                                       //  then remove the old stackframe from list
-                                n -= 1;                                                        // Adjust the stack list index
+                       if (!stackFrameOld.isAvailable()) {
+                               stackListOld.remove(n--);
                        }
                }
 
@@ -851,6 +991,10 @@ public class PHPDBGInterface {
                newStackList = new PHPStackFrame[stackListOld.size ()];
                newStackList = (PHPStackFrame[]) stackListOld.toArray (newStackList);
                DBGStackList = newStackList;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: updateStackFrameList End");
+               }
        }
 
     /**
@@ -877,6 +1021,10 @@ public class PHPDBGInterface {
         Vector  rawList                = new Vector();
         Vector  stackList              = new Vector();              // Intermediate stacklist which is build up in FRAME_STACK frame
 
+               if (bDebug) {
+               System.out.println ("PHPDBGInterface: readResponse start");
+               }
+
         rawList.clear ();
         stackList.clear ();
 
@@ -888,6 +1036,11 @@ public class PHPDBGInterface {
             dbg_header_struct[3] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 12);      // Bytes within this block
 
             if (dbg_header_struct[0] != 0x5953) {                                           // Check DBG sync bytes
+                       if (bDebug) {
+                       System.out.println ("PHPDBGInterface: readResponse. Wrong sync");
+                       }
+
+               bBusy = false;
                 return 0;                                                                   // Wrong header
             }
 
@@ -900,10 +1053,15 @@ public class PHPDBGInterface {
 
             if (bytesToRead > 0) {                                                          // If there is something within the frame
                 if (readInput (entirePack, bytesToRead) < bytesToRead) {                    // Read the frame into the buffer
+                       if (bDebug) {
+                       System.out.println ("PHPDBGInterface: readResponse. Did not read enough");
+                       }
+
+                   bBusy = false;
                     return 0;                                                               // We did not read enough bytes, error
                 }
                        }
-                       
+
                        nextFrame = 0;                                                                  // Start with the first frame
 
                        while (nextFrame < bytesToRead) {                                               // As long as we have something within this block
@@ -912,6 +1070,11 @@ public class PHPDBGInterface {
                                nextFrame   += 8;                                                           // The next read position
 
                                if (dbg_frame[1] == 0) {                                                    // Something within the frame?
+                                       if (bDebug) {
+                                               System.out.println ("PHPDBGInterface: readResponse. Nothing within the frame");
+                                       }
+
+                                       bBusy = false;
                                        return 0;                                                               //  Nothing to read, error
                                }
 
@@ -1026,16 +1189,15 @@ public class PHPDBGInterface {
                                                break;
 
                                        case PHPDBGBase.FRAME_EVAL:
-                                               String evalString;
+                                               //String evalString;
 
-                                               evalString      = new String ("");
+                                               //evalString      = new String ("");
                                                dbg_eval_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);                    // istr
                                                dbg_eval_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);                    // iresult
                                                dbg_eval_tmp[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8);                    // ierror
 
                                                evalRet                 = getRawFrameData (entirePack, dbg_eval_tmp[1]);                //
-                                               evalString              = getRawFrameData (entirePack, dbg_eval_tmp[0]);                //
-                                               //serGlobals            = evalRet;                                                      //
+                                               //evalString    = getRawFrameData (entirePack, dbg_eval_tmp[0]);                //
                                                break;
 
                                        case PHPDBGBase.FRAME_BPS:                                                          //
@@ -1125,8 +1287,15 @@ public class PHPDBGInterface {
                                        break;
 
                                case PHPDBGBase.DBGC_END:
-                                       sessionEnded = true;
-                                       this.proxy.setTerminated();
+                                       if (bRelaunch) {
+                       continueExecution ();                           // Inform dbg that we want to continue execution
+                       proxy.updateView ();                            // Sent a change event and create thread event to eclipse core
+                       updateStackFrameList (stackList);               // ??? Just a try
+                                       }
+                                       else {
+                                               sessionEnded = true;
+                                               proxy.setTerminated ();
+                                       }
                                        break;
 
                                case PHPDBGBase.DBGC_BREAKPOINT:
@@ -1156,6 +1325,12 @@ public class PHPDBGInterface {
                        }
                }
 
+               if (bDebug) {
+               System.out.println ("PHPDBGInterface: readResponse finish, received: " + cmdReceived);
+               }
+
+        bBusy = false;
+
                return cmdReceived;                                         // Return the command we received with this block
        }
 
@@ -1177,14 +1352,51 @@ public class PHPDBGInterface {
         */
        private int readInput (char[] buffer, int bytes) throws IOException {
                int bytesRead = 0;                                                                                      // Reset the bytes read counter
+               int nRetry    = 0;                                          // Retry counter
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: readInput " + bytes);
+               }
 
-               for (int i = 0; i < bytes; i++) {                           // For the number of bytes we should read
-                       if (in.ready ()) {                                                                              // If input stream is ready for reading
-                               buffer[i] = (char) (in.read () & 0x00FF);           // Read a char and store only the least significant 8-bits
+               for (int i = 0; i < bytes;) {                               // For the number of bytes we should read
+                       if (dbgInput.ready ()) {                                                                // If input stream is ready for reading
+                               nRetry    = 0;                                      // Reset the retry counter
+                               buffer[i] = (char) (dbgInput.read () & 0x00FF);     // Read a char and store only the least significant 8-bits
                                bytesRead++;                                        // Increment the bytes read counter
+                               i++;
                        }
                        else {                                                  // Input stream is not ready
-                               break;                                              // Break the loop
+                               nRetry++;                                           // Increment the retry counter
+
+                               if (nRetry > 10) {                                  // If nothing received within 100 retries
+                                       if (i > 0) {
+                                               if (bDebug) {
+                                                       System.out.println ("PHPDBGInterface: Too many retries without receiving something");
+                                               }
+                                       }
+                                       break;                                          // we break the loop
+                               }
+
+                               synchronized (dbgInput) {
+                                       if (i > 0) {
+                                               if (bDebug) {
+                                                       System.out.println ("PHPDBGInterface: retry: " + nRetry + " Wait for something to receive, received: " + i + " need " + bytes);
+                                               }
+                                       }
+                               try {
+                                       dbgInput.wait (10);                          // wait 5 ms maximum for something to receive
+                                   } catch (InterruptedException e) {
+                                   }
+                               }
+                       }
+               }
+
+               if (bytesRead > 0) {
+                       if (bytes != bytesRead) {
+                               if (bDebug) {
+                                       System.out.println ("PHPDBGInterface: readInput: Possible error: not enough bytes in buffer should read: " + bytes +
+                                                                               " actually read: " + bytesRead);
+                               }
                        }
                }
 
@@ -1205,18 +1417,33 @@ public class PHPDBGInterface {
         * @return             - true if something was received from DBG
         *                                         - false if nothing was send from DBG within the given time
         *
+        * This method has been a busy wait loop. It was changed to use
+        * a non busy wait to avoid a heavy load after automatic relaunch
+        * after script termination
+        *
         */
        public boolean waitResponse (long milliseconds) throws IOException {
                long timeout;
 
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: waitResponse " + milliseconds);
+               }
+
                timeout = System.currentTimeMillis () + milliseconds;           // Calculate the system time till we wait.
 
                while (System.currentTimeMillis () < timeout) {             // Is waiting time running out?
-                       if (in.ready () || shouldStop) {                        //  No, so did we get something or should we stop now
-                               break;                                              //   Yes, break the waiting
+                       synchronized (dbgInput) {
+                       try {
+                               dbgInput.wait (5);                              // wait 5 ms maximum for something to receive
+                           } catch (InterruptedException e) {
+                           }
+                       }
+
+                       if (dbgInput.ready () || shouldStop) {                  //  If something is received of if we should stop now
+                               break;                                              //    break the waiting loop
                        }
                }
 
-               return in.ready ();                                         // true if we got something from DBG
+               return dbgInput.ready ();                                   // true if we got something from DBG
        }
 }