void (final DebugEnvironment environment) { final String sessionName = environment.getSessionName(); final long pollTimeout = environment.getPollTimeout(); final Semaphore semaphore = new Semaphore(); semaphore.down(); final AtomicBoolean connectorIsReady = new AtomicBoolean(false); myDebugProcessDispatcher.addListener(new DebugProcessListener() { @Override public void connectorIsReady() { connectorIsReady.set(true); semaphore.up(); myDebugProcessDispatcher.removeListener(this); } }); getManagerThread().schedule(new DebuggerCommandImpl() { @Override protected void action() { VirtualMachine vm = null; try { final long time = System.currentTimeMillis(); do { try { vm = createVirtualMachineInt(); break; } catch (final ExecutionException e) { if (pollTimeout > 0 && !myConnection.isServerMode() && e.getCause() instanceof IOException) { synchronized (this) { try { wait(500); } catch (InterruptedException ignored) { break; } } } else { ProcessHandler processHandler = getProcessHandler(); boolean terminated = processHandler != null && (processHandler.isProcessTerminating() || processHandler.isProcessTerminated()); fail(); DebuggerInvocationUtil.swingInvokeLater(myProject, () -> { // propagate exception only in case we succeeded to obtain execution result, // otherwise if the error is induced by the fact that there is nothing to debug, and there is no need to show // this problem to the user if (((myExecutionResult != null && !terminated) || !connectorIsReady.get()) && !ApplicationManager.getApplication().isHeadlessEnvironment()) { ExecutionUtil.handleExecutionError(myProject, ToolWindowId.DEBUG, sessionName, e); } }); break; } } } while (System.currentTimeMillis() - time < pollTimeout); } finally { semaphore.up(); } if (vm != null) { final VirtualMachine vm1 = vm; afterProcessStarted(() -> getManagerThread().schedule(new DebuggerCommandImpl() { @Override protected void action() { try { commitVM(vm1); } catch (VMDisconnectedException e) { fail(); } } })); } else { fail(); } } @Override protected void commandCancelled() { try { super.commandCancelled(); } finally { semaphore.up(); } } }); semaphore.waitFor(); }