title: JDI ThreadReference.frame() causes IncompatibleThreadStateException
body: <p>Currently I am trying to extract some execution data via the JDI.
  Therefore I first start a java vm manually with the command</p>
  
  <pre><code>java -agentlib:jdwp=transport=dt_socket,server=y,address=8000 DebugDummy
  </code></pre>
  
  <p>My DebugDummy.java:</p>
  
  <pre><code>public class DebugDummy {
  
      public class MyInnerClass {
          private int a;
  
          public MyInnerClass(int a) {
              this.a = a;
              this.doSomething();
          }
  
          public void doSomething() {
              System.out.println(this.a);
          }
      }
  
      public DebugDummy() {
          MyInnerClass myInnerClass = new MyInnerClass(5);
          myInnerClass.doSomething();
      }
  
      public static void main(String[] args) {
          DebugDummy dd = new DebugDummy();
      }
  } 
  </code></pre>
  
  <p>And then connect with the JDI, waiting for the main-method entry and step line per line through the code execution.</p>
  
  <pre><code>public class VMStart {
  
  public static void main(String[] args) {
  
      //Check for argument count
      if(args.length != 3){
          System.err.println("Not enough parameter!");
          System.exit(0);
      }
  
      String cwd = "", mainClass = "", vmPort = "";
  
      cwd = args[0];
      mainClass = args[1];
      vmPort = args[2];
  
      System.out.println("CWD: " + cwd);
      System.out.println("MainClass: " + mainClass);
      System.out.println("VM Port: " + vmPort);
  
      //Init vm arguments and settings
      VirtualMachineManager vmm = Bootstrap.virtualMachineManager();
      AttachingConnector ac = vmm.attachingConnectors().get(0);
  
      //Setting port
      Map&lt;String, Connector.Argument&gt; env = ac.defaultArguments();
      Connector.Argument port = env.get("port");
      port.setValue(vmPort);
  
      //Setting hostname
      Connector.Argument hostname = env.get("hostname");
      hostname.setValue("localhost");
  
      //Attach vm to remote vm
      VirtualMachine vm = null;
      try {
          vm = ac.attach(env);
      } catch (IOException | IllegalConnectorArgumentsException e) {
          //Doesn't work, stop here...
          System.err.println("Can't connect to vm!");
          e.printStackTrace();
          System.exit(0);
      }
  
      //Create EventQueue and EventRequestManager for further event handling
      EventQueue eventQueue = vm.eventQueue();
      EventRequestManager mgr = vm.eventRequestManager();
  
      //Set the vm to sleep for further operations
      vm.suspend();
  
      //Searching for our main thread reference
      ThreadReference mainThread = null;
      List&lt;ThreadReference&gt; threads = vm.allThreads();
      for (ThreadReference thread : threads) {
          if ("main".equals(thread.name())) {
              mainThread = thread;
          }
      }
  
      //Create and register MethodEntryRequest, so we can pause execution at first line of main later on
      MethodEntryRequest methodEntryRequest = mgr.createMethodEntryRequest();
      methodEntryRequest.addClassFilter(mainClass);
      methodEntryRequest.addThreadFilter(mainThread);
      methodEntryRequest.enable();
  
      //Resume the execution of the remote vm
      vm.resume();
  
      //Resume the execution of the main thread in remote vm
      mainThread.resume();
  
      //Waiting for our needed MethodEntryEvent so execution started at first line of main method
      Event event = null;
      while (true) {
          EventSet eventSet = null;
          try {
              eventSet = eventQueue.remove();
          } catch (InterruptedException e) {
              System.err.println("Something went wrong while waiting for MethodEntryEvent");
              e.printStackTrace();
              System.exit(0);
          }
          event = eventSet.eventIterator().next();
          if (event instanceof MethodEntryEvent) {
              break;
          }
      }
  
      //Indicates whether there is still code execution in our remote vm
      boolean codeIsExecuting = true;
  
      //Step loop until there is no code execution
      while(codeIsExecuting){
          //Filter for steeping not into java api methods
          final String[] noBreakpointRequests = {"java.*", "javax.*", "sun.*", "com.sun.*"};
  
          //Creating our StepRequest for each line of code
          StepRequest stepRequest = mgr.createStepRequest(mainThread, StepRequest.STEP_LINE, StepRequest.STEP_INTO);
          for(String classInFilter : noBreakpointRequests){ //Apply filter 
              stepRequest.addClassExclusionFilter(classInFilter);
          }
          stepRequest.addCountFilter(1);
          try{
              stepRequest.enable();
          }catch(IllegalThreadStateException e){
              //program reached end of code, so there is no code execution anymore
              codeIsExecuting = false;
              System.out.println("Code execution ended...");
              break;
          }
  
          //Extract data from current vm execution state
          //TODO
          System.out.println("TODO - extract data from current vm execution state");
  
          //Test
          StackFrame stackFrame = null;
          try {
              stackFrame = mainThread.frame(0);
              System.out.println(stackFrame.location());
          } catch (IncompatibleThreadStateException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
  
          //Resume vm for code execution
          vm.resume();
  
          try {
              Thread.sleep(10L);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
  
          //StepRequest is done, remove it from event queue to prevent lock
          mgr.deleteEventRequest(stepRequest);
      }
  
      //Debugging has ended, we free our remote vm
      try{
          vm.dispose();
      }catch(VMDisconnectedException e){
  
      }
  
      //Print results
      //TODO
      System.out.println("TODO - print results...");
  
  }
  }
  </code></pre>
  
  <p>Unfortunally, if I delete the Thread.sleep(), I'm getting a IncompatibleThreadStateException at line</p>
  
  <pre><code>stackFrame = mainThread.frame(0);
  </code></pre>
  
  <p>Exception:</p>
  
  <pre><code>com.sun.jdi.IncompatibleThreadStateException at com.sun.tools.jdi.ThreadReferenceImpl.privateFrames(ThreadReferenceImpl.java:436)
  at com.sun.tools.jdi.ThreadReferenceImpl.frame(ThreadReferenceImpl.java:355)
  at VMStart.main(VMStart.java:143)
  </code></pre>
  
  <p>What's wrong? Do I have to wait for a certain event before stepping one line further?</p>