@Override
 public DebugProcessImpl getDebugProcess(final ProcessHandler processHandler) {
   synchronized (mySessions) {
     DebuggerSession session = mySessions.get(processHandler);
     return session != null ? session.getProcess() : null;
   }
 }
        @Override
        public void changeEvent(DebuggerContextImpl newContext, DebuggerSession.Event event) {

          final DebuggerSession session = newContext.getDebuggerSession();
          if (event == DebuggerSession.Event.PAUSE
              && myDebuggerStateManager.myDebuggerSession != session) {
            // if paused in non-active session; switch current session
            myDebuggerStateManager.setState(
                newContext,
                session != null ? session.getState() : DebuggerSession.State.DISPOSED,
                event,
                null);
            return;
          }

          if (myDebuggerStateManager.myDebuggerSession == session) {
            myDebuggerStateManager.fireStateChanged(newContext, event);
          }
          if (event == DebuggerSession.Event.ATTACHED) {
            myDispatcher.getMulticaster().sessionAttached(session);
          } else if (event == DebuggerSession.Event.DETACHED) {
            myDispatcher.getMulticaster().sessionDetached(session);
          } else if (event == DebuggerSession.Event.DISPOSE) {
            dispose(session);
            if (myDebuggerStateManager.myDebuggerSession == session) {
              myDebuggerStateManager.setState(
                  DebuggerContextImpl.EMPTY_CONTEXT,
                  DebuggerSession.State.DISPOSED,
                  DebuggerSession.Event.DISPOSE,
                  null);
            }
          }
        }
 @Override
 public DebuggerSession getSession(DebugProcess process) {
   ApplicationManager.getApplication().assertIsDispatchThread();
   for (final DebuggerSession debuggerSession : getSessions()) {
     if (process == debuggerSession.getProcess()) return debuggerSession;
   }
   return null;
 }
 private void dispose(DebuggerSession session) {
   ProcessHandler processHandler = session.getProcess().getProcessHandler();
   synchronized (mySessions) {
     DebuggerSession removed = mySessions.remove(processHandler);
     LOG.assertTrue(removed != null);
     myDispatcher.getMulticaster().sessionRemoved(session);
   }
 }
 @Override
 public void setState(
     final DebuggerContextImpl context,
     DebuggerSession.State state,
     DebuggerSession.Event event,
     String description) {
   ApplicationManager.getApplication().assertIsDispatchThread();
   myDebuggerSession = context.getDebuggerSession();
   if (myDebuggerSession != null) {
     myDebuggerSession.getContextManager().setState(context, state, event, description);
   } else {
     fireStateChanged(context, event);
   }
 }
Exemple #6
0
  public static void addThreadDump(
      Project project,
      List<ThreadState> threads,
      final RunnerLayoutUi ui,
      DebuggerSession session) {
    final TextConsoleBuilder consoleBuilder =
        TextConsoleBuilderFactory.getInstance().createBuilder(project);
    consoleBuilder.filters(ExceptionFilters.getFilters(session.getSearchScope()));
    final ConsoleView consoleView = consoleBuilder.getConsole();
    final DefaultActionGroup toolbarActions = new DefaultActionGroup();
    consoleView.allowHeavyFilters();
    final ThreadDumpPanel panel =
        new ThreadDumpPanel(project, consoleView, toolbarActions, threads);

    final String id = THREAD_DUMP_CONTENT_PREFIX + " #" + myCurrentThreadDumpId;
    final Content content = ui.createContent(id, panel, id, null, null);
    content.putUserData(RunnerContentUi.LIGHTWEIGHT_CONTENT_MARKER, Boolean.TRUE);
    content.setCloseable(true);
    content.setDescription("Thread Dump");
    ui.addContent(content);
    ui.selectAndFocus(content, true, true);
    myThreadDumpsCount++;
    myCurrentThreadDumpId++;
    Disposer.register(
        content,
        new Disposable() {
          @Override
          public void dispose() {
            myThreadDumpsCount--;
            if (myThreadDumpsCount == 0) {
              myCurrentThreadDumpId = 1;
            }
          }
        });
    Disposer.register(content, consoleView);
    ui.selectAndFocus(content, true, false);
    if (threads.size() > 0) {
      panel.selectStackFrame(0);
    }
  }
 @Override
 public DebuggerContextImpl getContext() {
   return myDebuggerSession == null
       ? DebuggerContextImpl.EMPTY_CONTEXT
       : myDebuggerSession.getContextManager().getContext();
 }
  @Override
  @Nullable
  public DebuggerSession attachVirtualMachine(@NotNull DebugEnvironment environment)
      throws ExecutionException {
    ApplicationManager.getApplication().assertIsDispatchThread();
    final DebugProcessEvents debugProcess = new DebugProcessEvents(myProject);
    debugProcess.addDebugProcessListener(
        new DebugProcessAdapter() {
          @Override
          public void processAttached(final DebugProcess process) {
            process.removeDebugProcessListener(this);
            for (Function<DebugProcess, PositionManager> factory :
                myCustomPositionManagerFactories) {
              final PositionManager positionManager = factory.fun(process);
              if (positionManager != null) {
                process.appendPositionManager(positionManager);
              }
            }
            for (PositionManagerFactory factory :
                Extensions.getExtensions(PositionManagerFactory.EP_NAME, myProject)) {
              final PositionManager manager = factory.createPositionManager(debugProcess);
              if (manager != null) {
                process.appendPositionManager(manager);
              }
            }
          }

          @Override
          public void processDetached(final DebugProcess process, final boolean closedByUser) {
            debugProcess.removeDebugProcessListener(this);
          }

          @Override
          public void attachException(
              final RunProfileState state,
              final ExecutionException exception,
              final RemoteConnection remoteConnection) {
            debugProcess.removeDebugProcessListener(this);
          }
        });
    DebuggerSession session =
        DebuggerSession.create(environment.getSessionName(), debugProcess, environment);
    ExecutionResult executionResult = session.getProcess().getExecutionResult();
    if (executionResult == null) {
      return null;
    }
    session.getContextManager().addListener(mySessionListener);
    getContextManager()
        .setState(
            DebuggerContextUtil.createDebuggerContext(
                session, session.getContextManager().getContext().getSuspendContext()),
            session.getState(),
            DebuggerSession.Event.CONTEXT,
            null);

    final ProcessHandler processHandler = executionResult.getProcessHandler();

    synchronized (mySessions) {
      mySessions.put(processHandler, session);
    }

    if (!(processHandler instanceof RemoteDebugProcessHandler)) {
      // add listener only to non-remote process handler:
      // on Unix systems destroying process does not cause VMDeathEvent to be generated,
      // so we need to call debugProcess.stop() explicitly for graceful termination.
      // RemoteProcessHandler on the other hand will call debugProcess.stop() as a part of
      // destroyProcess() and detachProcess() implementation,
      // so we shouldn't add the listener to avoid calling stop() twice
      processHandler.addProcessListener(
          new ProcessAdapter() {
            @Override
            public void processWillTerminate(ProcessEvent event, boolean willBeDestroyed) {
              final DebugProcessImpl debugProcess = getDebugProcess(event.getProcessHandler());
              if (debugProcess != null) {
                // if current thread is a "debugger manager thread", stop will execute synchronously
                // it is KillableColoredProcessHandler responsibility to terminate VM
                debugProcess.stop(
                    willBeDestroyed
                        && !(event.getProcessHandler() instanceof KillableColoredProcessHandler));

                // wait at most 10 seconds: the problem is that debugProcess.stop() can hang if
                // there are troubles in the debuggee
                // if processWillTerminate() is called from AWT thread debugProcess.waitFor() will
                // block it and the whole app will hang
                if (!DebuggerManagerThreadImpl.isManagerThread()) {
                  if (SwingUtilities.isEventDispatchThread()) {
                    ProgressManager.getInstance()
                        .runProcessWithProgressSynchronously(
                            new Runnable() {
                              @Override
                              public void run() {
                                ProgressManager.getInstance()
                                    .getProgressIndicator()
                                    .setIndeterminate(true);
                                debugProcess.waitFor(10000);
                              }
                            },
                            "Waiting For Debugger Response",
                            false,
                            debugProcess.getProject());
                  } else {
                    debugProcess.waitFor(10000);
                  }
                }
              }
            }
          });
    }
    myDispatcher.getMulticaster().sessionCreated(session);
    return session;
  }