@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;
 }
 protected void createLocalProcess(String className)
     throws ExecutionException, InterruptedException, InvocationTargetException {
   LOG.assertTrue(myDebugProcess == null);
   myDebuggerSession =
       createLocalProcess(DebuggerSettings.SOCKET_TRANSPORT, createJavaParameters(className));
   myDebugProcess = myDebuggerSession.getProcess();
 }
 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);
   }
 }
 @NotNull
 @Override
 public ExecutionConsole createConsole() {
   ExecutionConsole console =
       myJavaSession.getProcess().getExecutionResult().getExecutionConsole();
   if (console != null) return console;
   return super.createConsole();
 }
  protected DebuggerSession createRemoteProcess(
      final int transport, final boolean serverMode, JavaParameters javaParameters)
      throws ExecutionException, InterruptedException, InvocationTargetException {
    boolean useSockets = transport == DebuggerSettings.SOCKET_TRANSPORT;

    RemoteConnection remoteConnection =
        new RemoteConnection(useSockets, "127.0.0.1", String.valueOf(DEFAULT_ADDRESS), serverMode);

    String launchCommandLine = remoteConnection.getLaunchCommandLine();

    launchCommandLine = StringUtil.replace(launchCommandLine, RemoteConnection.ONTHROW, "");
    launchCommandLine = StringUtil.replace(launchCommandLine, RemoteConnection.ONUNCAUGHT, "");

    launchCommandLine = StringUtil.replace(launchCommandLine, "suspend=n", "suspend=y");

    println(launchCommandLine, ProcessOutputTypes.SYSTEM);

    for (StringTokenizer tokenizer = new StringTokenizer(launchCommandLine);
        tokenizer.hasMoreTokens(); ) {
      String token = tokenizer.nextToken();
      javaParameters.getVMParametersList().add(token);
    }

    GeneralCommandLine commandLine = CommandLineBuilder.createFromJavaParameters(javaParameters);

    DebuggerSession debuggerSession;

    if (serverMode) {
      debuggerSession = attachVM(remoteConnection, false);
      commandLine.createProcess();
    } else {
      commandLine.createProcess();
      debuggerSession = attachVM(remoteConnection, true);
    }

    ProcessHandler processHandler = debuggerSession.getProcess().getProcessHandler();
    DebugProcessImpl process =
        (DebugProcessImpl)
            DebuggerManagerEx.getInstanceEx(myProject).getDebugProcess(processHandler);

    assertNotNull(process);
    return debuggerSession;
  }
 @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);
   }
 }
  private void saveNodeHistory(final StackFrameProxyImpl frameProxy) {
    myJavaSession
        .getProcess()
        .getManagerThread()
        .invoke(
            new DebuggerCommandImpl() {
              @Override
              protected void action() throws Exception {
                myNodeManager.setHistoryByContext(frameProxy);
              }

              @Override
              public Priority getPriority() {
                return Priority.NORMAL;
              }
            });
  }
Beispiel #10
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);
    }
  }
 private DebuggerStateManager getDebuggerStateManager() {
   return myJavaSession.getContextManager();
 }
 @Override
 public DebuggerContextImpl getContext() {
   return myDebuggerSession == null
       ? DebuggerContextImpl.EMPTY_CONTEXT
       : myDebuggerSession.getContextManager().getContext();
 }
 @Override
 public void startStepOver() {
   myJavaSession.stepOver(false);
 }
  @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;
  }
 @Override
 public void startStepOut() {
   myJavaSession.stepOut();
 }
  protected JavaDebugProcess(
      @NotNull final XDebugSession session, final DebuggerSession javaSession) {
    super(session);
    myJavaSession = javaSession;
    myEditorsProvider = new JavaDebuggerEditorsProvider();
    final DebugProcessImpl process = javaSession.getProcess();

    List<XBreakpointHandler> handlers = new ArrayList<XBreakpointHandler>();
    handlers.add(new JavaBreakpointHandler.JavaLineBreakpointHandler(process));
    handlers.add(new JavaBreakpointHandler.JavaExceptionBreakpointHandler(process));
    handlers.add(new JavaBreakpointHandler.JavaFieldBreakpointHandler(process));
    handlers.add(new JavaBreakpointHandler.JavaMethodBreakpointHandler(process));
    handlers.add(new JavaBreakpointHandler.JavaWildcardBreakpointHandler(process));

    for (JavaBreakpointHandlerFactory factory :
        Extensions.getExtensions(JavaBreakpointHandlerFactory.EP_NAME)) {
      handlers.add(factory.createHandler(process));
    }

    myBreakpointHandlers = handlers.toArray(new XBreakpointHandler[handlers.size()]);

    myJavaSession
        .getContextManager()
        .addListener(
            new DebuggerContextListener() {
              @Override
              public void changeEvent(
                  @NotNull final DebuggerContextImpl newContext, DebuggerSession.Event event) {
                if (event == DebuggerSession.Event.PAUSE
                    || event == DebuggerSession.Event.CONTEXT
                    || event == DebuggerSession.Event.REFRESH && myJavaSession.isPaused()) {
                  final SuspendContextImpl newSuspendContext = newContext.getSuspendContext();
                  if (newSuspendContext != null && shouldApplyContext(newContext)) {
                    process
                        .getManagerThread()
                        .schedule(
                            new SuspendContextCommandImpl(newSuspendContext) {
                              @Override
                              public void contextAction() throws Exception {
                                newSuspendContext.initExecutionStacks(newContext.getThreadProxy());

                                List<Pair<Breakpoint, Event>> descriptors =
                                    DebuggerUtilsEx.getEventDescriptors(newSuspendContext);
                                if (!descriptors.isEmpty()) {
                                  Breakpoint breakpoint = descriptors.get(0).getFirst();
                                  XBreakpoint xBreakpoint = breakpoint.getXBreakpoint();
                                  if (xBreakpoint != null) {
                                    ((XDebugSessionImpl) getSession())
                                        .breakpointReachedNoProcessing(
                                            xBreakpoint, newSuspendContext);
                                    unsetPausedIfNeeded(newContext);
                                    return;
                                  }
                                }
                                getSession().positionReached(newSuspendContext);
                                unsetPausedIfNeeded(newContext);
                              }
                            });
                  }
                } else if (event == DebuggerSession.Event.ATTACHED) {
                  getSession().rebuildViews(); // to refresh variables views message
                }
              }
            });

    myNodeManager =
        new NodeManagerImpl(session.getProject(), null) {
          @Override
          public DebuggerTreeNodeImpl createNode(
              final NodeDescriptor descriptor, EvaluationContext evaluationContext) {
            return new DebuggerTreeNodeImpl(null, descriptor);
          }

          @Override
          public DebuggerTreeNodeImpl createMessageNode(MessageDescriptor descriptor) {
            return new DebuggerTreeNodeImpl(null, descriptor);
          }

          @Override
          public DebuggerTreeNodeImpl createMessageNode(String message) {
            return new DebuggerTreeNodeImpl(null, new MessageDescriptor(message));
          }
        };
    session.addSessionListener(
        new XDebugSessionAdapter() {
          @Override
          public void sessionPaused() {
            saveNodeHistory();
            showAlternativeNotification(session.getCurrentStackFrame());
          }

          @Override
          public void stackFrameChanged() {
            XStackFrame frame = session.getCurrentStackFrame();
            if (frame instanceof JavaStackFrame) {
              showAlternativeNotification(frame);
              StackFrameProxyImpl frameProxy = ((JavaStackFrame) frame).getStackFrameProxy();
              DebuggerContextUtil.setStackFrame(javaSession.getContextManager(), frameProxy);
              saveNodeHistory(frameProxy);
            }
          }

          private void showAlternativeNotification(@Nullable XStackFrame frame) {
            if (frame != null) {
              XSourcePosition position = frame.getSourcePosition();
              if (position != null) {
                VirtualFile file = position.getFile();
                if (!AlternativeSourceNotificationProvider.fileProcessed(file)) {
                  EditorNotifications.getInstance(session.getProject()).updateNotifications(file);
                }
              }
            }
          }
        });
  }
 @Override
 public void startStepInto() {
   myJavaSession.stepInto(false, null);
 }
 @Override
 protected DebugProcessImpl getDebugProcess() {
   return myDebuggerSession != null ? myDebuggerSession.getProcess() : null;
 }
 @Override
 public void runToPosition(@NotNull XSourcePosition position) {
   myJavaSession.runToCursor(position, false);
 }
 @Nullable
 @Override
 protected ProcessHandler doGetProcessHandler() {
   return myJavaSession.getProcess().getProcessHandler();
 }
  protected DebuggerSession createLocalSession(final JavaParameters javaParameters)
      throws ExecutionException, InterruptedException {
    createBreakpoints(javaParameters.getMainClass());
    DebuggerSettings.getInstance().DEBUGGER_TRANSPORT = DebuggerSettings.SOCKET_TRANSPORT;

    GenericDebuggerRunnerSettings debuggerRunnerSettings = new GenericDebuggerRunnerSettings();
    debuggerRunnerSettings.LOCAL = true;

    final RemoteConnection debugParameters =
        DebuggerManagerImpl.createDebugParameters(javaParameters, debuggerRunnerSettings, false);

    ExecutionEnvironment environment =
        new ExecutionEnvironmentBuilder(myProject, DefaultDebugExecutor.getDebugExecutorInstance())
            .runnerSettings(debuggerRunnerSettings)
            .runProfile(new MockConfiguration())
            .build();
    final JavaCommandLineState javaCommandLineState =
        new JavaCommandLineState(environment) {
          @Override
          protected JavaParameters createJavaParameters() {
            return javaParameters;
          }

          @Override
          protected GeneralCommandLine createCommandLine() throws ExecutionException {
            return CommandLineBuilder.createFromJavaParameters(getJavaParameters());
          }
        };

    ApplicationManager.getApplication()
        .invokeAndWait(
            () -> {
              try {
                myDebuggerSession =
                    DebuggerManagerEx.getInstanceEx(myProject)
                        .attachVirtualMachine(
                            new DefaultDebugEnvironment(
                                new ExecutionEnvironmentBuilder(
                                        myProject, DefaultDebugExecutor.getDebugExecutorInstance())
                                    .runProfile(new MockConfiguration())
                                    .build(),
                                javaCommandLineState,
                                debugParameters,
                                false));
                XDebuggerManager.getInstance(myProject)
                    .startSession(
                        javaCommandLineState.getEnvironment(),
                        new XDebugProcessStarter() {
                          @Override
                          @NotNull
                          public XDebugProcess start(@NotNull XDebugSession session) {
                            return JavaDebugProcess.create(session, myDebuggerSession);
                          }
                        });
              } catch (ExecutionException e) {
                LOG.error(e);
              }
            });
    myDebugProcess = myDebuggerSession.getProcess();

    myDebugProcess.addProcessListener(
        new ProcessAdapter() {
          @Override
          public void onTextAvailable(ProcessEvent event, Key outputType) {
            print(event.getText(), outputType);
          }
        });

    assertNotNull(myDebuggerSession);
    assertNotNull(myDebugProcess);

    return myDebuggerSession;
  }
 @Override
 public void startPausing() {
   myJavaSession.pause();
 }
 @Override
 public void stop() {
   myJavaSession.dispose();
   myNodeManager.dispose();
 }
 private DebugProcessImpl getDebugProcess() {
   return myDebuggerSession.getProcess();
 }
 @Override
 public String getCurrentStateMessage() {
   String description = myJavaSession.getStateDescription();
   return description != null ? description : super.getCurrentStateMessage();
 }
  public void reloadClasses(final Map<String, HotSwapFile> modifiedClasses) {
    DebuggerManagerThreadImpl.assertIsManagerThread();

    if (modifiedClasses == null || modifiedClasses.size() == 0) {
      myProgress.addMessage(
          myDebuggerSession,
          MessageCategory.INFORMATION,
          DebuggerBundle.message("status.hotswap.loaded.classes.up.to.date"));
      return;
    }

    final DebugProcessImpl debugProcess = getDebugProcess();
    final VirtualMachineProxyImpl virtualMachineProxy = debugProcess.getVirtualMachineProxy();

    final Project project = debugProcess.getProject();
    final BreakpointManager breakpointManager =
        (DebuggerManagerEx.getInstanceEx(project)).getBreakpointManager();
    breakpointManager.disableBreakpoints(debugProcess);

    // virtualMachineProxy.suspend();

    try {
      RedefineProcessor redefineProcessor = new RedefineProcessor(virtualMachineProxy);

      int processedEntriesCount = 0;
      for (final Map.Entry<String, HotSwapFile> entry : modifiedClasses.entrySet()) {
        // stop if process is finished already
        if (debugProcess.isDetached() || debugProcess.isDetaching()) {
          break;
        }
        if (redefineProcessor.getProcessedClassesCount() == 0 && myProgress.isCancelled()) {
          // once at least one class has been actually reloaded, do not interrupt the whole process
          break;
        }
        processedEntriesCount++;
        final String qualifiedName = entry.getKey();
        if (qualifiedName != null) {
          myProgress.setText(qualifiedName);
          myProgress.setFraction(processedEntriesCount / (double) modifiedClasses.size());
        }
        try {
          redefineProcessor.processClass(qualifiedName, entry.getValue().file);
        } catch (IOException e) {
          reportProblem(qualifiedName, e);
        }
      }

      if (redefineProcessor.getProcessedClassesCount() == 0 && myProgress.isCancelled()) {
        // once at least one class has been actually reloaded, do not interrupt the whole process
        return;
      }

      redefineProcessor.processPending();
      myProgress.setFraction(1);

      final int partiallyRedefinedClassesCount =
          redefineProcessor.getPartiallyRedefinedClassesCount();
      if (partiallyRedefinedClassesCount == 0) {
        myProgress.addMessage(
            myDebuggerSession,
            MessageCategory.INFORMATION,
            DebuggerBundle.message(
                "status.classes.reloaded", redefineProcessor.getProcessedClassesCount()));
      } else {
        final String message =
            DebuggerBundle.message(
                "status.classes.not.all.versions.reloaded",
                partiallyRedefinedClassesCount,
                redefineProcessor.getProcessedClassesCount());
        myProgress.addMessage(myDebuggerSession, MessageCategory.WARNING, message);
      }

      LOG.debug("classes reloaded");
    } catch (Throwable e) {
      processException(e);
    }

    debugProcess.getPositionManager().clearCache();

    DebuggerContextImpl context = myDebuggerSession.getContextManager().getContext();
    SuspendContextImpl suspendContext = context.getSuspendContext();
    if (suspendContext != null) {
      XExecutionStack stack = suspendContext.getActiveExecutionStack();
      if (stack != null) {
        ((JavaExecutionStack) stack).initTopFrame();
      }
    }

    final Semaphore waitSemaphore = new Semaphore();
    waitSemaphore.down();
    //noinspection SSBasedInspection
    SwingUtilities.invokeLater(
        () -> {
          try {
            if (!project.isDisposed()) {
              breakpointManager.reloadBreakpoints();
              debugProcess.getRequestsManager().clearWarnings();
              if (LOG.isDebugEnabled()) {
                LOG.debug("requests updated");
                LOG.debug("time stamp set");
              }
              myDebuggerSession.refresh(false);

              XDebugSession session = myDebuggerSession.getXDebugSession();
              if (session != null) {
                session.rebuildViews();
              }
            }
          } catch (Throwable e) {
            LOG.error(e);
          } finally {
            waitSemaphore.up();
          }
        });

    waitSemaphore.waitFor();

    if (!project.isDisposed()) {
      try {
        breakpointManager.enableBreakpoints(debugProcess);
      } catch (Exception e) {
        processException(e);
      }
    }
  }
 public static JavaDebugProcess create(
     @NotNull final XDebugSession session, final DebuggerSession javaSession) {
   JavaDebugProcess res = new JavaDebugProcess(session, javaSession);
   javaSession.getProcess().setXDebugProcess(res);
   return res;
 }
 @Override
 public void resume() {
   myJavaSession.resume();
 }
 @Override
 public void startForceStepInto() {
   myJavaSession.stepInto(true, null);
 }