예제 #1
0
  /**
   * Generate the trace. Enable events, start thread to display events, start threads to forward
   * remote error and output streams, resume the remote VM, wait for the final event, and shutdown.
   */
  protected void generateTrace() {
    // vm.setDebugTraceMode(debugTraceMode);
    //    vm.setDebugTraceMode(VirtualMachine.TRACE_ALL);
    //    vm.setDebugTraceMode(VirtualMachine.TRACE_NONE);  // formerly, seems to have no effect

    // For internal debugging
    PrintWriter writer = null;

    // Calling this seems to set something internally to make the
    // Eclipse JDI wake up. Without it, an ObjectCollectedException
    // is thrown on excReq.enable(). No idea why this works,
    // but at least exception handling has returned. (Suspect that it may
    // block until all or at least some threads are available, meaning
    // that the app has launched and we have legit objects to talk to).
    vm.allThreads();
    // The bug may not have been noticed because the test suite waits for
    // a thread to be available, and queries it by calling allThreads().
    // See org.eclipse.debug.jdi.tests.AbstractJDITest for the example.

    EventRequestManager mgr = vm.eventRequestManager();
    // get only the uncaught exceptions
    ExceptionRequest excReq = mgr.createExceptionRequest(null, false, true);
    //    System.out.println(excReq);
    // this version reports all exceptions, caught or uncaught
    //  ExceptionRequest excReq = mgr.createExceptionRequest(null, true, true);
    // suspend so we can step
    excReq.setSuspendPolicy(EventRequest.SUSPEND_ALL);
    //    excReq.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
    //    excReq.setSuspendPolicy(EventRequest.SUSPEND_NONE);  // another option?
    excReq.enable();

    Thread eventThread =
        new Thread() {
          public void run() {
            try {
              boolean connected = true;
              while (connected) {
                EventQueue eventQueue = vm.eventQueue();
                // remove() blocks until event(s) available
                EventSet eventSet = eventQueue.remove();
                //            listener.vmEvent(eventSet);

                for (Event event : eventSet) {
                  //              System.out.println("EventThread.handleEvent -> " + event);
                  if (event instanceof VMStartEvent) {
                    vm.resume();
                  } else if (event instanceof ExceptionEvent) {
                    //                for (ThreadReference thread : vm.allThreads()) {
                    //                  System.out.println("thread : " + thread);
                    ////                  thread.suspend();
                    //                }
                    exceptionEvent((ExceptionEvent) event);
                  } else if (event instanceof VMDisconnectEvent) {
                    connected = false;
                  }
                }
              }
              //        } catch (VMDisconnectedException e) {
              //          Logger.getLogger(VMEventReader.class.getName()).log(Level.INFO,
              // "VMEventReader quit on VM disconnect");
            } catch (Exception e) {
              System.err.println("crashed in event thread due to " + e.getMessage());
              //          Logger.getLogger(VMEventReader.class.getName()).log(Level.SEVERE,
              // "VMEventReader quit", e);
              e.printStackTrace();
            }
          }
        };
    eventThread.start();

    errThread = new MessageSiphon(process.getErrorStream(), this).getThread();

    outThread = new StreamRedirectThread("JVM stdout Reader", process.getInputStream(), System.out);
    errThread.start();
    outThread.start();

    // Shutdown begins when event thread terminates
    try {
      if (eventThread != null) eventThread.join(); // is this the problem?

      //      System.out.println("in here");
      // Bug #852 tracked to this next line in the code.
      // http://dev.processing.org/bugs/show_bug.cgi?id=852
      errThread.join(); // Make sure output is forwarded
      //      System.out.println("and then");
      outThread.join(); // before we exit
      //      System.out.println("finished join for errThread and outThread");

      // At this point, disable the run button.
      // This happens when the sketch is exited by hitting ESC,
      // or the user manually closes the sketch window.
      // TODO this should be handled better, should it not?
      if (editor != null) {
        editor.deactivateRun();
      }
    } catch (InterruptedException exc) {
      // we don't interrupt
    }
    // System.out.println("and leaving");
    if (writer != null) writer.close();
  }
  /**
   * Starts the debugger. The method stops the current debugging (if any) and takes information from
   * the provided info (containing the class to start and arguments to pass it and name of class to
   * stop debugging in) and starts new debugging session.
   *
   * @param info debugger info about class to start
   * @exception DebuggerException if an error occures during the start of the debugger
   */
  public void startDebugger(DebuggerInfo info) throws DebuggerException {
    debuggerInfo = info;
    if (virtualMachine != null) finishDebugger();

    stopOnMain = info.getStopClassName() != null;
    mainClassName =
        info
            .getClassName(); // S ystem.out.println ("JPDADebugger stop on " + info.getStopClassName
                             // ()); // NOI18N

    // open output window ...
    super.startDebugger(info);

    // stop on main
    if (stopOnMain) {
      try {
        String stopClassName = debuggerInfo.getStopClassName();
        AbstractDebugger d = (AbstractDebugger) TopManager.getDefault().getDebugger();
        breakpointMain = new CoreBreakpoint[stopMethodNames.length];
        for (int x = 0; x < breakpointMain.length; x++) {
          breakpointMain[x] = (CoreBreakpoint) d.createBreakpoint(true);
          breakpointMain[x].setClassName(""); // NOI18N
          breakpointMain[x].setMethodName(stopMethodNames[x]); // NOI18N
          CoreBreakpoint.Action[] a = breakpointMain[x].getActions();
          int i, ii = a.length;
          for (i = 0; i < ii; i++)
            if (a[i] instanceof PrintAction) {
              ((PrintAction) a[i]).setPrintText(bundle.getString("CTL_Stop_On_Main_print_text"));
            }
          breakpointMain[x].setClassName(stopClassName);
        }

        addPropertyChangeListener(
            new PropertyChangeListener() {
              public void propertyChange(PropertyChangeEvent ev) {
                if (ev.getPropertyName().equals(PROP_STATE)) {
                  if ((((Integer) ev.getNewValue()).intValue() == DEBUGGER_STOPPED)
                      || (((Integer) ev.getNewValue()).intValue() == DEBUGGER_NOT_RUNNING)) {
                    if (breakpointMain != null) {
                      for (int x = 0; x < breakpointMain.length; x++) breakpointMain[x].remove();
                      breakpointMain = null;
                    }
                    removePropertyChangeListener(this);
                  }
                }
              }
            });

      } catch (DebuggerException e) {
        e.printStackTrace();
      }
    }

    // start & init remote debugger ............................................
    boolean launch = false;
    if (info instanceof ReconnectDebuggerInfo) {
      virtualMachine = reconnect((ReconnectDebuggerInfo) info);
    } else if (info instanceof RemoteDebuggerInfo) {
      virtualMachine = connect((RemoteDebuggerInfo) info);
    } else {
      virtualMachine = launch(info);
      process = virtualMachine.process();
      showOutput(process, STD_OUT, STD_OUT);
      connectInput(process);
      launch = true;
    }
    requestManager = virtualMachine.eventRequestManager();
    operator =
        new Operator(
            virtualMachine,
            launch
                ? new Runnable() {
                  public void run() {
                    startDebugger();
                  }
                }
                : null,
            new Runnable() {
              public void run() {
                try {
                  finishDebugger();
                } catch (DebuggerException e) {
                }
              }
            });
    operator.start();
    if (!launch) startDebugger();
  }