PageRenderTime 44ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java

https://bitbucket.org/nbargnesi/idea
Java | 577 lines | 469 code | 71 blank | 37 comment | 117 complexity | 81c6ae25291061f3f47353c7c8ad0667 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, MPL-2.0-no-copyleft-exception, AGPL-1.0
  1. /*
  2. * Copyright 2000-2009 JetBrains s.r.o.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.intellij.debugger.impl;
  17. import com.intellij.debugger.*;
  18. import com.intellij.debugger.apiAdapters.TransportServiceWrapper;
  19. import com.intellij.debugger.engine.*;
  20. import com.intellij.debugger.settings.DebuggerSettings;
  21. import com.intellij.debugger.ui.GetJPDADialog;
  22. import com.intellij.debugger.ui.breakpoints.BreakpointManager;
  23. import com.intellij.execution.ExecutionException;
  24. import com.intellij.execution.ExecutionResult;
  25. import com.intellij.execution.Executor;
  26. import com.intellij.execution.configurations.JavaParameters;
  27. import com.intellij.execution.configurations.ModuleRunProfile;
  28. import com.intellij.execution.configurations.RemoteConnection;
  29. import com.intellij.execution.configurations.RunProfileState;
  30. import com.intellij.execution.process.ProcessAdapter;
  31. import com.intellij.execution.process.ProcessEvent;
  32. import com.intellij.execution.process.ProcessHandler;
  33. import com.intellij.execution.runners.ProgramRunner;
  34. import com.intellij.openapi.Disposable;
  35. import com.intellij.openapi.application.ApplicationManager;
  36. import com.intellij.openapi.diagnostic.Logger;
  37. import com.intellij.openapi.editor.colors.EditorColorsListener;
  38. import com.intellij.openapi.editor.colors.EditorColorsManager;
  39. import com.intellij.openapi.editor.colors.EditorColorsScheme;
  40. import com.intellij.openapi.extensions.Extensions;
  41. import com.intellij.openapi.project.Project;
  42. import com.intellij.openapi.projectRoots.JavaSdk;
  43. import com.intellij.openapi.projectRoots.JavaSdkVersion;
  44. import com.intellij.openapi.projectRoots.JdkUtil;
  45. import com.intellij.openapi.projectRoots.Sdk;
  46. import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
  47. import com.intellij.openapi.startup.StartupManager;
  48. import com.intellij.openapi.util.Disposer;
  49. import com.intellij.openapi.util.InvalidDataException;
  50. import com.intellij.openapi.util.SystemInfo;
  51. import com.intellij.openapi.util.WriteExternalException;
  52. import com.intellij.openapi.vfs.VirtualFile;
  53. import com.intellij.psi.PsiClass;
  54. import com.intellij.util.EventDispatcher;
  55. import com.intellij.util.Function;
  56. import com.intellij.util.containers.ContainerUtil;
  57. import org.jdom.Element;
  58. import org.jetbrains.annotations.NonNls;
  59. import org.jetbrains.annotations.NotNull;
  60. import org.jetbrains.annotations.Nullable;
  61. import java.io.File;
  62. import java.util.*;
  63. import java.util.jar.Attributes;
  64. public class DebuggerManagerImpl extends DebuggerManagerEx {
  65. private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.DebuggerManagerImpl");
  66. private final Project myProject;
  67. private final HashMap<ProcessHandler, DebuggerSession> mySessions = new HashMap<ProcessHandler, DebuggerSession>();
  68. private final BreakpointManager myBreakpointManager;
  69. private final List<NameMapper> myNameMappers = ContainerUtil.createEmptyCOWList();
  70. private final List<Function<DebugProcess, PositionManager>> myCustomPositionManagerFactories = new ArrayList<Function<DebugProcess, PositionManager>>();
  71. private final EventDispatcher<DebuggerManagerListener> myDispatcher = EventDispatcher.create(DebuggerManagerListener.class);
  72. private final MyDebuggerStateManager myDebuggerStateManager = new MyDebuggerStateManager();
  73. private final DebuggerContextListener mySessionListener = new DebuggerContextListener() {
  74. public void changeEvent(DebuggerContextImpl newContext, int event) {
  75. final DebuggerSession session = newContext.getDebuggerSession();
  76. if (event == DebuggerSession.EVENT_PAUSE && myDebuggerStateManager.myDebuggerSession != session) {
  77. // if paused in non-active session; switch current session
  78. myDebuggerStateManager.setState(newContext, session.getState(), event, null);
  79. return;
  80. }
  81. if(myDebuggerStateManager.myDebuggerSession == session) {
  82. myDebuggerStateManager.fireStateChanged(newContext, event);
  83. }
  84. if (event == DebuggerSession.EVENT_ATTACHED) {
  85. myDispatcher.getMulticaster().sessionAttached(session);
  86. }
  87. else if (event == DebuggerSession.EVENT_DETACHED) {
  88. myDispatcher.getMulticaster().sessionDetached(session);
  89. }
  90. else if(event == DebuggerSession.EVENT_DISPOSE) {
  91. dispose(session);
  92. if(myDebuggerStateManager.myDebuggerSession == session) {
  93. myDebuggerStateManager.setState(DebuggerContextImpl.EMPTY_CONTEXT, DebuggerSession.STATE_DISPOSED, DebuggerSession.EVENT_DISPOSE, null);
  94. }
  95. }
  96. }
  97. };
  98. @NonNls private static final String DEBUG_KEY_NAME = "idea.xdebug.key";
  99. public void addClassNameMapper(final NameMapper mapper) {
  100. myNameMappers.add(mapper);
  101. }
  102. public void removeClassNameMapper(final NameMapper mapper) {
  103. myNameMappers.remove(mapper);
  104. }
  105. public String getVMClassQualifiedName(@NotNull final PsiClass aClass) {
  106. for (NameMapper nameMapper : myNameMappers) {
  107. final String qName = nameMapper.getQualifiedName(aClass);
  108. if (qName != null) {
  109. return qName;
  110. }
  111. }
  112. return aClass.getQualifiedName();
  113. }
  114. public void addDebuggerManagerListener(DebuggerManagerListener listener) {
  115. myDispatcher.addListener(listener);
  116. }
  117. public void removeDebuggerManagerListener(DebuggerManagerListener listener) {
  118. myDispatcher.removeListener(listener);
  119. }
  120. public DebuggerManagerImpl(Project project, StartupManager startupManager, final EditorColorsManager colorsManager) {
  121. myProject = project;
  122. myBreakpointManager = new BreakpointManager(myProject, startupManager, this);
  123. final EditorColorsListener myColorsListener = new EditorColorsListener() {
  124. public void globalSchemeChange(EditorColorsScheme scheme) {
  125. getBreakpointManager().updateBreakpointsUI();
  126. }
  127. };
  128. colorsManager.addEditorColorsListener(myColorsListener);
  129. Disposer.register(project, new Disposable() {
  130. public void dispose() {
  131. colorsManager.removeEditorColorsListener(myColorsListener);
  132. }
  133. });
  134. }
  135. public DebuggerSession getSession(DebugProcess process) {
  136. ApplicationManager.getApplication().assertIsDispatchThread();
  137. for (final DebuggerSession debuggerSession : getSessions()) {
  138. if (process == debuggerSession.getProcess()) return debuggerSession;
  139. }
  140. return null;
  141. }
  142. public Collection<DebuggerSession> getSessions() {
  143. synchronized (mySessions) {
  144. final Collection<DebuggerSession> values = mySessions.values();
  145. return values.isEmpty() ? Collections.<DebuggerSession>emptyList() : new ArrayList<DebuggerSession>(values);
  146. }
  147. }
  148. public void disposeComponent() {
  149. }
  150. public void initComponent() {
  151. }
  152. public void projectClosed() {
  153. }
  154. public void projectOpened() {
  155. myBreakpointManager.init();
  156. }
  157. public void readExternal(Element element) throws InvalidDataException {
  158. myBreakpointManager.readExternal(element);
  159. }
  160. public void writeExternal(Element element) throws WriteExternalException {
  161. myBreakpointManager.writeExternal(element);
  162. }
  163. public DebuggerSession attachVirtualMachine(Executor executor,
  164. ProgramRunner runner,
  165. ModuleRunProfile profile,
  166. RunProfileState state,
  167. RemoteConnection remoteConnection,
  168. boolean pollConnection
  169. ) throws ExecutionException {
  170. return attachVirtualMachine(new DefaultDebugEnvironment(myProject,
  171. executor,
  172. runner,
  173. profile,
  174. state,
  175. remoteConnection,
  176. pollConnection));
  177. }
  178. public DebuggerSession attachVirtualMachine(DebugEnvironment environment) throws ExecutionException {
  179. ApplicationManager.getApplication().assertIsDispatchThread();
  180. final DebugProcessEvents debugProcess = new DebugProcessEvents(myProject);
  181. debugProcess.addDebugProcessListener(new DebugProcessAdapter() {
  182. public void processAttached(final DebugProcess process) {
  183. process.removeDebugProcessListener(this);
  184. for (Function<DebugProcess, PositionManager> factory : myCustomPositionManagerFactories) {
  185. final PositionManager positionManager = factory.fun(process);
  186. if (positionManager != null) {
  187. process.appendPositionManager(positionManager);
  188. }
  189. }
  190. for(PositionManagerFactory factory: Extensions.getExtensions(PositionManagerFactory.EP_NAME, myProject)) {
  191. final PositionManager manager = factory.createPositionManager(debugProcess);
  192. if (manager != null) {
  193. process.appendPositionManager(manager);
  194. }
  195. }
  196. }
  197. public void processDetached(final DebugProcess process, final boolean closedByUser) {
  198. debugProcess.removeDebugProcessListener(this);
  199. }
  200. public void attachException(final RunProfileState state, final ExecutionException exception, final RemoteConnection remoteConnection) {
  201. debugProcess.removeDebugProcessListener(this);
  202. }
  203. });
  204. final DebuggerSession session = new DebuggerSession(environment.getSessionName(), debugProcess);
  205. final ExecutionResult executionResult = session.attach(environment);
  206. if (executionResult == null) {
  207. return null;
  208. }
  209. session.getContextManager().addListener(mySessionListener);
  210. getContextManager().setState(DebuggerContextUtil.createDebuggerContext(session, session.getContextManager().getContext().getSuspendContext()), session.getState(), DebuggerSession.EVENT_CONTEXT, null);
  211. final ProcessHandler processHandler = executionResult.getProcessHandler();
  212. synchronized (mySessions) {
  213. mySessions.put(processHandler, session);
  214. }
  215. if (!(processHandler instanceof RemoteDebugProcessHandler)) {
  216. // add listener only to non-remote process handler:
  217. // on Unix systems destroying process does not cause VMDeathEvent to be generated,
  218. // so we need to call debugProcess.stop() explicitly for graceful termination.
  219. // RemoteProcessHandler on the other hand will call debugProcess.stop() as a part of destroyProcess() and detachProcess() implementation,
  220. // so we shouldn't add the listener to avoid calling stop() twice
  221. processHandler.addProcessListener(new ProcessAdapter() {
  222. public void processWillTerminate(ProcessEvent event, boolean willBeDestroyed) {
  223. final DebugProcessImpl debugProcess = getDebugProcess(event.getProcessHandler());
  224. if (debugProcess != null) {
  225. // if current thread is a "debugger manager thread", stop will execute synchronously
  226. debugProcess.stop(willBeDestroyed);
  227. // wait at most 10 seconds: the problem is that debugProcess.stop() can hang if there are troubles in the debuggee
  228. // if processWillTerminate() is called from AWT thread debugProcess.waitFor() will block it and the whole app will hang
  229. if (!DebuggerManagerThreadImpl.isManagerThread()) {
  230. debugProcess.waitFor(10000);
  231. }
  232. }
  233. }
  234. });
  235. }
  236. myDispatcher.getMulticaster().sessionCreated(session);
  237. return session;
  238. }
  239. public DebugProcessImpl getDebugProcess(final ProcessHandler processHandler) {
  240. synchronized (mySessions) {
  241. DebuggerSession session = mySessions.get(processHandler);
  242. return session != null ? session.getProcess() : null;
  243. }
  244. }
  245. @Nullable
  246. public DebuggerSession getDebugSession(final ProcessHandler processHandler) {
  247. synchronized (mySessions) {
  248. return mySessions.get(processHandler);
  249. }
  250. }
  251. public void addDebugProcessListener(final ProcessHandler processHandler, final DebugProcessListener listener) {
  252. DebugProcessImpl debugProcess = getDebugProcess(processHandler);
  253. if (debugProcess != null) {
  254. debugProcess.addDebugProcessListener(listener);
  255. }
  256. else {
  257. processHandler.addProcessListener(new ProcessAdapter() {
  258. public void startNotified(ProcessEvent event) {
  259. DebugProcessImpl debugProcess = getDebugProcess(processHandler);
  260. if (debugProcess != null) {
  261. debugProcess.addDebugProcessListener(listener);
  262. }
  263. processHandler.removeProcessListener(this);
  264. }
  265. });
  266. }
  267. }
  268. public void removeDebugProcessListener(final ProcessHandler processHandler, final DebugProcessListener listener) {
  269. DebugProcessImpl debugProcess = getDebugProcess(processHandler);
  270. if (debugProcess != null) {
  271. debugProcess.removeDebugProcessListener(listener);
  272. }
  273. else {
  274. processHandler.addProcessListener(new ProcessAdapter() {
  275. public void startNotified(ProcessEvent event) {
  276. DebugProcessImpl debugProcess = getDebugProcess(processHandler);
  277. if (debugProcess != null) {
  278. debugProcess.removeDebugProcessListener(listener);
  279. }
  280. processHandler.removeProcessListener(this);
  281. }
  282. });
  283. }
  284. }
  285. public boolean isDebuggerManagerThread() {
  286. return DebuggerManagerThreadImpl.isManagerThread();
  287. }
  288. @NotNull
  289. public String getComponentName() {
  290. return "DebuggerManager";
  291. }
  292. public BreakpointManager getBreakpointManager() {
  293. return myBreakpointManager;
  294. }
  295. public DebuggerContextImpl getContext() { return getContextManager().getContext(); }
  296. public DebuggerStateManager getContextManager() { return myDebuggerStateManager;}
  297. public void registerPositionManagerFactory(final Function<DebugProcess,PositionManager> factory) {
  298. myCustomPositionManagerFactories.add(factory);
  299. }
  300. public void unregisterPositionManagerFactory(final Function<DebugProcess, PositionManager> factory) {
  301. myCustomPositionManagerFactories.remove(factory);
  302. }
  303. private static boolean hasWhitespace(String string) {
  304. int length = string.length();
  305. for (int i = 0; i < length; i++) {
  306. if (Character.isWhitespace(string.charAt(i))) {
  307. return true;
  308. }
  309. }
  310. return false;
  311. }
  312. /* Remoting */
  313. private static void checkTargetJPDAInstalled(JavaParameters parameters) throws ExecutionException {
  314. final Sdk jdk = parameters.getJdk();
  315. if (jdk == null) {
  316. throw new ExecutionException(DebuggerBundle.message("error.jdk.not.specified"));
  317. }
  318. final JavaSdkVersion version = JavaSdk.getInstance().getVersion(jdk);
  319. String versionString = jdk.getVersionString();
  320. if (version == JavaSdkVersion.JDK_1_0 || version == JavaSdkVersion.JDK_1_1) {
  321. throw new ExecutionException(DebuggerBundle.message("error.unsupported.jdk.version", versionString));
  322. }
  323. if (SystemInfo.isWindows && version == JavaSdkVersion.JDK_1_2) {
  324. final VirtualFile homeDirectory = jdk.getHomeDirectory();
  325. if (homeDirectory == null || !homeDirectory.isValid()) {
  326. throw new ExecutionException(DebuggerBundle.message("error.invalid.jdk.home", versionString));
  327. }
  328. //noinspection HardCodedStringLiteral
  329. File dllFile = new File(
  330. homeDirectory.getPath().replace('/', File.separatorChar) + File.separator + "bin" + File.separator + "jdwp.dll"
  331. );
  332. if (!dllFile.exists()) {
  333. GetJPDADialog dialog = new GetJPDADialog();
  334. dialog.show();
  335. throw new ExecutionException(DebuggerBundle.message("error.debug.libraries.missing"));
  336. }
  337. }
  338. }
  339. /**
  340. * for Target JDKs versions 1.2.x - 1.3.0 the Classic VM should be used for debugging
  341. */
  342. private static boolean shouldForceClassicVM(Sdk jdk) {
  343. if (SystemInfo.isMac) {
  344. return false;
  345. }
  346. if (jdk == null) return false;
  347. String version = JdkUtil.getJdkMainAttribute(jdk, Attributes.Name.IMPLEMENTATION_VERSION);
  348. if (version != null) {
  349. if (version.compareTo("1.4") >= 0) {
  350. return false;
  351. }
  352. if (version.startsWith("1.2") && SystemInfo.isWindows) {
  353. return true;
  354. }
  355. version += ".0";
  356. if (version.startsWith("1.3.0") && SystemInfo.isWindows) {
  357. return true;
  358. }
  359. if ((version.startsWith("1.3.1_07") || version.startsWith("1.3.1_08")) && SystemInfo.isWindows) {
  360. return false; // fixes bug for these JDKs that it cannot start with -classic option
  361. }
  362. }
  363. return DebuggerSettings.getInstance().FORCE_CLASSIC_VM;
  364. }
  365. @SuppressWarnings({"HardCodedStringLiteral"})
  366. public static RemoteConnection createDebugParameters(final JavaParameters parameters,
  367. final boolean debuggerInServerMode,
  368. int transport, final String debugPort,
  369. boolean checkValidity)
  370. throws ExecutionException {
  371. if (checkValidity) {
  372. checkTargetJPDAInstalled(parameters);
  373. }
  374. final boolean useSockets = transport == DebuggerSettings.SOCKET_TRANSPORT;
  375. String address = "";
  376. if (debugPort == null || "".equals(debugPort)) {
  377. try {
  378. address = DebuggerUtils.getInstance().findAvailableDebugAddress(useSockets);
  379. }
  380. catch (ExecutionException e) {
  381. if (checkValidity) {
  382. throw e;
  383. }
  384. }
  385. }
  386. else {
  387. address = debugPort;
  388. }
  389. final TransportServiceWrapper transportService = TransportServiceWrapper.getTransportService(useSockets);
  390. final String debugAddress = debuggerInServerMode && useSockets ? "127.0.0.1:" + address : address;
  391. String debuggeeRunProperties = "transport=" + transportService.transportId() + ",address=" + debugAddress;
  392. if(debuggerInServerMode) {
  393. debuggeeRunProperties += ",suspend=y,server=n";
  394. }
  395. else {
  396. debuggeeRunProperties += ",suspend=n,server=y";
  397. }
  398. if (hasWhitespace(debuggeeRunProperties)) {
  399. debuggeeRunProperties = "\"" + debuggeeRunProperties + "\"";
  400. }
  401. final String _debuggeeRunProperties = debuggeeRunProperties;
  402. ApplicationManager.getApplication().runReadAction(new Runnable() {
  403. @SuppressWarnings({"HardCodedStringLiteral"})
  404. public void run() {
  405. JavaSdkUtil.addRtJar(parameters.getClassPath());
  406. final Sdk jdk = parameters.getJdk();
  407. final boolean forceClassicVM = shouldForceClassicVM(jdk);
  408. final boolean forceNoJIT = shouldForceNoJIT(jdk);
  409. final String debugKey = System.getProperty(DEBUG_KEY_NAME, "-Xdebug");
  410. final boolean needDebugKey = shouldAddXdebugKey(jdk) || !"-Xdebug".equals(debugKey) /*the key is non-standard*/;
  411. if (forceClassicVM || forceNoJIT || needDebugKey || !isJVMTIAvailable(jdk)) {
  412. parameters.getVMParametersList().replaceOrPrepend("-Xrunjdwp:", "-Xrunjdwp:" + _debuggeeRunProperties);
  413. }
  414. else {
  415. // use newer JVMTI if available
  416. parameters.getVMParametersList().replaceOrPrepend("-Xrunjdwp:", "");
  417. parameters.getVMParametersList().replaceOrPrepend("-agentlib:jdwp=", "-agentlib:jdwp=" + _debuggeeRunProperties);
  418. }
  419. if (forceNoJIT) {
  420. parameters.getVMParametersList().replaceOrPrepend("-Djava.compiler=", "-Djava.compiler=NONE");
  421. parameters.getVMParametersList().replaceOrPrepend("-Xnoagent", "-Xnoagent");
  422. }
  423. if (needDebugKey) {
  424. parameters.getVMParametersList().replaceOrPrepend(debugKey, debugKey);
  425. }
  426. else {
  427. // deliberately skip outdated parameter because it can disable full-speed debugging for some jdk builds
  428. // see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6272174
  429. parameters.getVMParametersList().replaceOrPrepend("-Xdebug", "");
  430. }
  431. parameters.getVMParametersList().replaceOrPrepend("-classic", forceClassicVM ? "-classic" : "");
  432. }
  433. });
  434. return new RemoteConnection(useSockets, "127.0.0.1", address, debuggerInServerMode);
  435. }
  436. private static boolean shouldForceNoJIT(Sdk jdk) {
  437. if (DebuggerSettings.getInstance().DISABLE_JIT) {
  438. return true;
  439. }
  440. if (jdk != null) {
  441. final String version = JdkUtil.getJdkMainAttribute(jdk, Attributes.Name.IMPLEMENTATION_VERSION);
  442. if (version != null && (version.startsWith("1.2") || version.startsWith("1.3"))) {
  443. return true;
  444. }
  445. }
  446. return false;
  447. }
  448. private static boolean shouldAddXdebugKey(Sdk jdk) {
  449. if (jdk == null) {
  450. return true; // conservative choice
  451. }
  452. if (DebuggerSettings.getInstance().DISABLE_JIT) {
  453. return true;
  454. }
  455. //if (ApplicationManager.getApplication().isUnitTestMode()) {
  456. // need this in unit tests to avoid false alarms when comparing actual output with expected output
  457. //return true;
  458. //}
  459. final String version = JdkUtil.getJdkMainAttribute(jdk, Attributes.Name.IMPLEMENTATION_VERSION);
  460. return version == null ||
  461. //version.startsWith("1.5") ||
  462. version.startsWith("1.4") ||
  463. version.startsWith("1.3") ||
  464. version.startsWith("1.2") ||
  465. version.startsWith("1.1") ||
  466. version.startsWith("1.0");
  467. }
  468. private static boolean isJVMTIAvailable(Sdk jdk) {
  469. if (jdk == null) {
  470. return false; // conservative choice
  471. }
  472. final String version = JdkUtil.getJdkMainAttribute(jdk, Attributes.Name.IMPLEMENTATION_VERSION);
  473. if (version == null) {
  474. return false;
  475. }
  476. return !(version.startsWith("1.4") || version.startsWith("1.3") || version.startsWith("1.2") || version.startsWith("1.1") || version.startsWith("1.0"));
  477. }
  478. public static RemoteConnection createDebugParameters(final JavaParameters parameters, GenericDebuggerRunnerSettings settings, boolean checkValidity)
  479. throws ExecutionException {
  480. return createDebugParameters(parameters, settings.LOCAL, settings.getTransport(), settings.DEBUG_PORT, checkValidity);
  481. }
  482. private static class MyDebuggerStateManager extends DebuggerStateManager {
  483. private DebuggerSession myDebuggerSession;
  484. public DebuggerContextImpl getContext() {
  485. return myDebuggerSession == null ? DebuggerContextImpl.EMPTY_CONTEXT : myDebuggerSession.getContextManager().getContext();
  486. }
  487. public void setState(final DebuggerContextImpl context, int state, int event, String description) {
  488. ApplicationManager.getApplication().assertIsDispatchThread();
  489. myDebuggerSession = context.getDebuggerSession();
  490. if (myDebuggerSession != null) {
  491. myDebuggerSession.getContextManager().setState(context, state, event, description);
  492. }
  493. else {
  494. fireStateChanged(context, event);
  495. }
  496. }
  497. }
  498. private void dispose(DebuggerSession session) {
  499. ProcessHandler processHandler = session.getProcess().getExecutionResult().getProcessHandler();
  500. synchronized (mySessions) {
  501. DebuggerSession removed = mySessions.remove(processHandler);
  502. LOG.assertTrue(removed != null);
  503. myDispatcher.getMulticaster().sessionRemoved(session);
  504. }
  505. }
  506. }