protected void createLocalProcess(String className) throws ExecutionException, InterruptedException, InvocationTargetException { LOG.assertTrue(myDebugProcess == null); myDebuggerSession = createLocalProcess(DebuggerSettings.SOCKET_TRANSPORT, createJavaParameters(className)); myDebugProcess = myDebuggerSession.getProcess(); }
@Override public DebugProcessImpl getDebugProcess(final ProcessHandler processHandler) { synchronized (mySessions) { DebuggerSession session = mySessions.get(processHandler); return session != null ? session.getProcess() : 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 DebuggerSession getSession(DebugProcess process) { ApplicationManager.getApplication().assertIsDispatchThread(); for (final DebuggerSession debuggerSession : getSessions()) { if (process == debuggerSession.getProcess()) return debuggerSession; } return null; }
@NotNull @Override public ExecutionConsole createConsole() { ExecutionConsole console = myJavaSession.getProcess().getExecutionResult().getExecutionConsole(); if (console != null) return console; return super.createConsole(); }
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; } }); }
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 @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; }
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); } } } } }); }
public static JavaDebugProcess create( @NotNull final XDebugSession session, final DebuggerSession javaSession) { JavaDebugProcess res = new JavaDebugProcess(session, javaSession); javaSession.getProcess().setXDebugProcess(res); return res; }
@Nullable @Override protected ProcessHandler doGetProcessHandler() { return myJavaSession.getProcess().getProcessHandler(); }
private DebugProcessImpl getDebugProcess() { return myDebuggerSession.getProcess(); }
@Override protected DebugProcessImpl getDebugProcess() { return myDebuggerSession != null ? myDebuggerSession.getProcess() : null; }
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; }