From 31aeb7bca9456e2aedbbfb1f1ea1feced4d9303e Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 12 Sep 2008 15:17:54 +0000 Subject: [PATCH] Bug 245749 Avoid race condition by filling thread to group map of IMIProcesses service directly using new addThreadId() and removeThreadId() methods --- .../provisional/service/GDBProcesses.java | 17 +++- .../provisional/service/GDBProcesses_7_0.java | 29 ++---- .../service/command/GDBControl.java | 9 -- .../service/command/GDBControl_7_0.java | 9 -- .../service/command/IGDBControl.java | 3 - .../eclipse/dd/mi/service/IMIProcesses.java | 23 +++++ .../eclipse/dd/mi/service/MIProcesses.java | 16 +++- .../command/CLIEventProcessor_7_0.java | 3 + .../MIRunControlEventProcessor_7_0.java | 21 +++-- .../dd/tests/gdb/GDBProcessesTest.java | 13 +-- .../dd/tests/gdb/MIRunControlTest.java | 88 ++++++------------- 11 files changed, 103 insertions(+), 128 deletions(-) diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBProcesses.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBProcesses.java index 905a750f6cf..b8cac79885b 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBProcesses.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBProcesses.java @@ -182,8 +182,10 @@ public class GDBProcesses extends MIProcesses { // This service version only handles a single process to debug, therefore, we can simply // create the context describing this process ourselves. ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, ICommandControlDMContext.class); - IProcessDMContext procDmc = createProcessContext(controlDmc, inferiorProcess.getPid()); - IMIExecutionGroupDMContext newGroupDmc = createExecutionGroupContext(procDmc, inferiorProcess.getPid()); + // Get the groupId properly for the case of an attach + String groupId = getExecutionGroupIdFromThread(null); + IProcessDMContext procDmc = createProcessContext(controlDmc, groupId); + IMIExecutionGroupDMContext newGroupDmc = createExecutionGroupContext(procDmc, groupId); rm.setData(new IContainerDMContext[] {newGroupDmc}); rm.done(); } else { @@ -263,11 +265,18 @@ public class GDBProcesses extends MIProcesses { @Override public String getExecutionGroupIdFromThread(String threadId) { + // We need to properly return the groupId based on the pid + // to properly handle the case of an attach. See bug 244749 + String groupId = null; MIInferiorProcess inferiorProcess = fGdb.getInferiorProcess(); if (inferiorProcess != null) { - return inferiorProcess.getPid(); + groupId = inferiorProcess.getPid(); + } + if (groupId != null) { + return groupId; + } else { + return super.getExecutionGroupIdFromThread(threadId); } - return null; } } diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBProcesses_7_0.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBProcesses_7_0.java index 78682855d73..dbe9e7b3d24 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBProcesses_7_0.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBProcesses_7_0.java @@ -49,8 +49,6 @@ import org.eclipse.dd.mi.service.command.commands.MIListThreadGroups; import org.eclipse.dd.mi.service.command.commands.MITargetAttach; import org.eclipse.dd.mi.service.command.commands.MITargetDetach; import org.eclipse.dd.mi.service.command.commands.MIThreadInfo; -import org.eclipse.dd.mi.service.command.events.IMIDMEvent; -import org.eclipse.dd.mi.service.command.events.MIThreadCreatedEvent; import org.eclipse.dd.mi.service.command.events.MIThreadGroupCreatedEvent; import org.eclipse.dd.mi.service.command.events.MIThreadGroupExitedEvent; import org.eclipse.dd.mi.service.command.output.IThreadInfo; @@ -736,17 +734,6 @@ public class GDBProcesses_7_0 extends AbstractDsfService implements IMIProcesses if (e instanceof ExecutionGroupStartedDMEvent) { fContainerCommandCache.reset(); } else { - // HACK figure out the thread and the group ids - // I had to HACK GDB for this - if (e instanceof IMIDMEvent) { - String threadId = ((MIThreadCreatedEvent)((IMIDMEvent)e).getMIEvent()).getStrId(); - IContainerDMContext ctx = ((MIThreadCreatedEvent)((IMIDMEvent)e).getMIEvent()).getDMContext(); - if (ctx instanceof IMIExecutionGroupDMContext) { - String groupId = ((IMIExecutionGroupDMContext)ctx).getGroupId(); - fGroupIdMap.put(threadId, groupId); - } - } - // END HACK fThreadCommandCache.reset(); } } @@ -757,14 +744,6 @@ public class GDBProcesses_7_0 extends AbstractDsfService implements IMIProcesses if (e instanceof ExecutionGroupExitedDMEvent) { fContainerCommandCache.reset(); } else { - // HACK figure out the thread and the group ids - // I had to HACK GDB for this - if (e instanceof IMIDMEvent) { - String threadId = ((MIThreadCreatedEvent)((IMIDMEvent)e).getMIEvent()).getStrId(); - fGroupIdMap.remove(threadId); - } - // END HACK - fThreadCommandCache.reset(); } } @@ -773,5 +752,13 @@ public class GDBProcesses_7_0 extends AbstractDsfService implements IMIProcesses fContainerCommandCache.reset(context); fThreadCommandCache.reset(context); } + + public void addThreadId(String threadId, String groupId) { + fGroupIdMap.put(threadId, groupId); + } + + public void removeThreadId(String threadId) { + fGroupIdMap.remove(threadId); + } } diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java index b25d5957473..3a91c05ded5 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java @@ -432,15 +432,6 @@ public class GDBControl extends AbstractMIControl implements IGDBControl { public IPath getExecutablePath() { return fExecPath; } - public void getInferiorProcessId(DataRequestMonitor rm) { - String pid = null; - if (fInferiorProcess != null) { - pid = fInferiorProcess.getPid(); - } - rm.setData(pid); - rm.done(); - } - @DsfServiceEventHandler public void eventDispatched(ICommandControlShutdownDMEvent e) { // Handle our "GDB Exited" event and stop processing commands. diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl_7_0.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl_7_0.java index 1cf8c4529a8..f3f061e190b 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl_7_0.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl_7_0.java @@ -433,15 +433,6 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl { public IPath getExecutablePath() { return fExecPath; } - public void getInferiorProcessId(DataRequestMonitor rm) { - String pid = null; - if (fInferiorProcess != null) { - pid = fInferiorProcess.getPid(); - } - rm.setData(pid); - rm.done(); - } - @DsfServiceEventHandler public void eventDispatched(ICommandControlShutdownDMEvent e) { // Handle our "GDB Exited" event and stop processing commands. diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/IGDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/IGDBControl.java index c93d6202a53..a95e3b94eb7 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/IGDBControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/IGDBControl.java @@ -11,7 +11,6 @@ package org.eclipse.dd.gdb.internal.provisional.service.command; import org.eclipse.core.runtime.IPath; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.debug.service.command.ICommandControlService; import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch; @@ -55,6 +54,4 @@ public interface IGDBControl extends ICommandControlService { int getGDBExitCode(); IPath getExecutablePath(); - - void getInferiorProcessId(DataRequestMonitor rm); } \ No newline at end of file diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/IMIProcesses.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/IMIProcesses.java index 6262fb23317..7ee308a93f7 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/IMIProcesses.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/IMIProcesses.java @@ -54,6 +54,29 @@ public interface IMIProcesses extends IProcesses IMIExecutionGroupDMContext createExecutionGroupContext(IProcessDMContext processDmc, String groupId); + /** + * Retrieve the groupId to which this threadId belongs + * + * @param threadId The ID of the thread + * @return The ID of the group to which the specified thread belongs + */ String getExecutionGroupIdFromThread(String threadId); + + /** + * This method should be called when a new thread is created. It allows + * to keep track of the thread to group relationship. + * + * @param threadId The ID of the new thread + * @param groupId The ID of the group to which the new thread belongs + */ + void addThreadId(String threadId, String groupId); + + /** + * This method should be called when a thread exits. It is meant + * to remove the thread to group entry. + * + * @param threadId The ID of the thread that exited + */ + void removeThreadId(String threadId); } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIProcesses.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIProcesses.java index 9986ff7f9d5..2acf212f56a 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIProcesses.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIProcesses.java @@ -553,8 +553,10 @@ public class MIProcesses extends AbstractDsfService implements IMIProcesses, ICa // This service version only handles a single process to debug, therefore, we can simply // create the context describing this process ourselves. ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, ICommandControlDMContext.class); - IProcessDMContext procDmc = createProcessContext(controlDmc, UNIQUE_GROUP_ID); - IMIExecutionGroupDMContext newGroupDmc = createExecutionGroupContext(procDmc, UNIQUE_GROUP_ID); + // Get the groupId properly for the case of an attach + String groupId = getExecutionGroupIdFromThread(null); + IProcessDMContext procDmc = createProcessContext(controlDmc, groupId); + IMIExecutionGroupDMContext newGroupDmc = createExecutionGroupContext(procDmc, groupId); rm.setData(new IContainerDMContext[] {newGroupDmc}); rm.done(); } @@ -647,4 +649,14 @@ public class MIProcesses extends AbstractDsfService implements IMIProcesses, ICa fContainerCommandCache.reset(context); } + public void addThreadId(String threadId, String groupId) { + // This version of the service does not support multiple + // processes, so there is nothing to do here + } + + public void removeThreadId(String threadId) { + // This version of the service does not support multiple + // processes, so there is nothing to do here + } + } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor_7_0.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor_7_0.java index 701cb003233..45b9f000c71 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor_7_0.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor_7_0.java @@ -106,6 +106,9 @@ public class CLIEventProcessor_7_0 if (rr != null) { // Check if the state changed. String state = rr.getResultClass(); + + // This is not handled properly yet + // see bug 247161 if (fInferior != null && "error".equals(state)) { //$NON-NLS-1$ if (fInferior.getState() == MIInferiorProcess.State.RUNNING) { fInferior.setState(MIInferiorProcess.State.STOPPED); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor_7_0.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor_7_0.java index f136177ef08..5ab125ce22c 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor_7_0.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor_7_0.java @@ -180,8 +180,15 @@ public class MIRunControlEventProcessor_7_0 IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class); - if (groupId == null) { - groupId = procService.getExecutionGroupIdFromThread(threadId); + if ("thread-created".equals(miEvent)) { //$NON-NLS-1$ + // Update the thread to groupId map with the new groupId + procService.addThreadId(threadId, groupId); + } else { + // It was not clear if MI would specify the groupId in the event + if (groupId == null) { + groupId = procService.getExecutionGroupIdFromThread(threadId); + } + procService.removeThreadId(threadId); } IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, groupId); IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, groupId); @@ -193,9 +200,7 @@ public class MIRunControlEventProcessor_7_0 event = new MIThreadExitEvent(processContainerDmc, exec.getToken(), threadId); } - if (event != null) { - fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); - } + fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); } else if ("thread-group-created".equals(miEvent) || "thread-group-exited".equals(miEvent)) { //$NON-NLS-1$ //$NON-NLS-2$ String groupId = null; @@ -222,9 +227,7 @@ public class MIRunControlEventProcessor_7_0 event = new MIThreadGroupExitedEvent(procDmc, exec.getToken(), groupId); } - if (event != null) { - fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); - } + fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); } } } @@ -253,6 +256,7 @@ public class MIRunControlEventProcessor_7_0 IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class); + // MI does not currently provide the group-id in these events if (groupId == null) { groupId = procService.getExecutionGroupIdFromThread(threadId); } @@ -319,7 +323,6 @@ public class MIRunControlEventProcessor_7_0 MIOutput output = cmdResult.getMIOutput(); MIResultRecord rr = output.getMIResultRecord(); if (rr != null) { - int id = rr.getToken(); // Check if the state changed. String state = rr.getResultClass(); if ("running".equals(state)) { //$NON-NLS-1$ diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java index 00f2903b060..222bd4a7824 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java @@ -108,15 +108,10 @@ public class GDBProcessesTest extends BaseTestCase { */ fSession.getExecutor().submit(new Runnable() { public void run() { - fGdbCtrl.getInferiorProcessId( - new DataRequestMonitor(fSession.getExecutor(), rm) { - @Override - protected void handleSuccess() { - String pid = getData(); - IProcessDMContext procDmc = fProcService.createProcessContext(fGdbCtrl.getContext(), pid); - fProcService.getExecutionData(procDmc, rm); - } - }); + String pid = fProcService.getExecutionGroupIdFromThread(null); + + IProcessDMContext procDmc = fProcService.createProcessContext(fGdbCtrl.getContext(), pid); + fProcService.getExecutionData(procDmc, rm); } }); /* diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java index 92f159a02d0..d8371ea6110 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java @@ -115,16 +115,10 @@ public class MIRunControlTest extends BaseTestCase { */ fRunCtrl.getExecutor().submit(new Runnable() { public void run() { - fGDBCtrl.getInferiorProcessId( - new DataRequestMonitor(fRunCtrl.getExecutor(), rm) { - @Override - protected void handleSuccess() { - String pid = getData(); - IProcessDMContext procDmc = fProcService.createProcessContext(fGDBCtrl.getContext(), pid); - IContainerDMContext groupDmc = fProcService.createExecutionGroupContext(procDmc, pid); - fRunCtrl.getExecutionContexts(groupDmc, rm); - } - }); + String pid = fProcService.getExecutionGroupIdFromThread(null); + IProcessDMContext procDmc = fProcService.createProcessContext(fGDBCtrl.getContext(), pid); + IContainerDMContext groupDmc = fProcService.createExecutionGroupContext(procDmc, pid); + fRunCtrl.getExecutionContexts(groupDmc, rm); } }); wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); @@ -207,16 +201,10 @@ public class MIRunControlTest extends BaseTestCase { */ fRunCtrl.getExecutor().submit(new Runnable() { public void run() { - fGDBCtrl.getInferiorProcessId( - new DataRequestMonitor(fRunCtrl.getExecutor(), rmExecutionCtxts) { - @Override - protected void handleSuccess() { - String pid = getData(); - IProcessDMContext procDmc = fProcService.createProcessContext(fGDBCtrl.getContext(), pid); - IContainerDMContext groupDmc = fProcService.createExecutionGroupContext(procDmc, pid); - fRunCtrl.getExecutionContexts(groupDmc, rmExecutionCtxts); - } - }); + String pid = fProcService.getExecutionGroupIdFromThread(null); + IProcessDMContext procDmc = fProcService.createProcessContext(fGDBCtrl.getContext(), pid); + IContainerDMContext groupDmc = fProcService.createExecutionGroupContext(procDmc, pid); + fRunCtrl.getExecutionContexts(groupDmc, rmExecutionCtxts); } }); wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); @@ -265,16 +253,10 @@ public class MIRunControlTest extends BaseTestCase { */ fRunCtrl.getExecutor().submit(new Runnable() { public void run() { - fGDBCtrl.getInferiorProcessId( - new DataRequestMonitor(fRunCtrl.getExecutor(), rm) { - @Override - protected void handleSuccess() { - String pid = getData(); - IProcessDMContext procDmc = fProcService.createProcessContext(fGDBCtrl.getContext(), pid); - IContainerDMContext groupDmc = fProcService.createExecutionGroupContext(procDmc, pid); - fRunCtrl.getExecutionData(fRunCtrl.createMIExecutionContext(groupDmc, 1), rm); - } - }); + String pid = fProcService.getExecutionGroupIdFromThread(null); + IProcessDMContext procDmc = fProcService.createProcessContext(fGDBCtrl.getContext(), pid); + IContainerDMContext groupDmc = fProcService.createExecutionGroupContext(procDmc, pid); + fRunCtrl.getExecutionData(fRunCtrl.createMIExecutionContext(groupDmc, 1), rm); } }); wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); @@ -490,16 +472,10 @@ public class MIRunControlTest extends BaseTestCase { fRunCtrl.getExecutor().submit(new Runnable() { public void run() { - fGDBCtrl.getInferiorProcessId( - new DataRequestMonitor(fRunCtrl.getExecutor(), rm) { - @Override - protected void handleSuccess() { - String pid = getData(); - IProcessDMContext procDmc = fProcService.createProcessContext(fGDBCtrl.getContext(), pid); - IContainerDMContext groupDmc = fProcService.createExecutionGroupContext(procDmc, pid); - fRunCtrl.resume(groupDmc, rm); - } - }); + String pid = fProcService.getExecutionGroupIdFromThread(null); + IProcessDMContext procDmc = fProcService.createProcessContext(fGDBCtrl.getContext(), pid); + IContainerDMContext groupDmc = fProcService.createExecutionGroupContext(procDmc, pid); + fRunCtrl.resume(groupDmc, rm); } }); wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); @@ -516,18 +492,12 @@ public class MIRunControlTest extends BaseTestCase { wait.waitReset(); fRunCtrl.getExecutor().submit(new Runnable() { public void run() { - fGDBCtrl.getInferiorProcessId( - new DataRequestMonitor(fRunCtrl.getExecutor(), null) { - @Override - protected void handleCompleted() { - String pid = getData(); - IProcessDMContext procDmc = fProcService.createProcessContext(fGDBCtrl.getContext(), pid); - IContainerDMContext groupDmc = fProcService.createExecutionGroupContext(procDmc, pid); + String pid = fProcService.getExecutionGroupIdFromThread(null); + IProcessDMContext procDmc = fProcService.createProcessContext(fGDBCtrl.getContext(), pid); + IContainerDMContext groupDmc = fProcService.createExecutionGroupContext(procDmc, pid); - wait.setReturnInfo(fRunCtrl.isSuspended(groupDmc)); - wait.waitFinished(); - } - }); + wait.setReturnInfo(fRunCtrl.isSuspended(groupDmc)); + wait.waitFinished(); } }); @@ -577,18 +547,12 @@ public class MIRunControlTest extends BaseTestCase { wait.waitReset(); fRunCtrl.getExecutor().submit(new Runnable() { public void run() { - fGDBCtrl.getInferiorProcessId( - new DataRequestMonitor(fRunCtrl.getExecutor(), null) { - @Override - protected void handleCompleted() { - String pid = getData(); - IProcessDMContext procDmc = fProcService.createProcessContext(fGDBCtrl.getContext(), pid); - IContainerDMContext groupDmc = fProcService.createExecutionGroupContext(procDmc, pid); + String pid = fProcService.getExecutionGroupIdFromThread(null); + IProcessDMContext procDmc = fProcService.createProcessContext(fGDBCtrl.getContext(), pid); + IContainerDMContext groupDmc = fProcService.createExecutionGroupContext(procDmc, pid); - wait.setReturnInfo(fRunCtrl.isSuspended(groupDmc)); - wait.waitFinished(); - } - }); + wait.setReturnInfo(fRunCtrl.isSuspended(groupDmc)); + wait.waitFinished(); } });