Community
Participate
Working Groups
Terminating a debug session when its initialization sequence is still running produces the "Connection is shut down" error message which is confusing for users. This issue is difficult to reproduce on the standard CDT because the launching time is too short, but it is easily reproduced in our products. I think the termination in this case should be handled by canceling the running initialization sequence.
Created attachment 212412 [details] Proposed fix.
Any suggestions on how to test this?
(In reply to comment #2) > Any suggestions on how to test this? I'll try to find a way to reproduce it on the standard CDT.
(In reply to comment #2) > Any suggestions on how to test this? I can reproduce this randomly with the remote launch configuration type but it is not easy because many other errors can pop up and in many cases gdbserver stays alive. A few times I got the following NPE which should be fixed separately. java.lang.ClassCastException: java.lang.NullPointerException cannot be cast to org.eclipse.core.runtime.CoreException at org.eclipse.cdt.dsf.gdb.launching.GdbLaunch.initializeControl(GdbLaunch.java:156) at org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.launchDebugSession(GdbLaunchDelegate.java:182) at org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.launchDebugger(GdbLaunchDelegate.java:102) at org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.launch(GdbLaunchDelegate.java:91) at org.eclipse.cdt.launch.remote.launching.RemoteGdbLaunchDelegate.launch(RemoteGdbLaunchDelegate.java:219) at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:855) at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:704) at org.eclipse.debug.internal.ui.DebugUIPlugin.buildAndLaunch(DebugUIPlugin.java:951) at org.eclipse.debug.internal.ui.DebugUIPlugin$8.run(DebugUIPlugin.java:1155) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54) In our case, when 'Terminate' is pressed it usually happens during one of 'list-thread-groups' commands that are issued by the Debug view. 'AbstractMIControl.stopCommandProcessing()' marks all commands in 'fRxCommands' list as failed, the error message is 'Connection is shut down'. If the session type is 'local' DSF/GDB tries to get around these errors and acquire the list of processes directly. In case of 'remote' sessions a 'CoreException' is thrown which results in the above error message. In general, assuming that I can find a way to reproduce this issue consistently what is the best way to deal with the problem? I can think of two options. One is to enable 'Terminate' and 'Disconnect' only when the initialization sequence is done. In this case the only way to stop the session is to cancel the launch. It is not very convenient but at least logical. The second solution is to change the logic of 'terminate' as it is done in the patch. What do you think?
I'll reply to comment 4 tonight (I have to leave now). I wanted to ask if the following is a way to reproduce: running a manual remote launch without starting gdbserver, and then pressing terminate while GDB is waiting to connect to the remote. Is that the case you are trying to fix?
(In reply to comment #4) > In general, assuming that I can find a way to reproduce this issue consistently > what is the best way to deal with the problem? I can think of two options. One > is to enable 'Terminate' and 'Disconnect' only when the initialization sequence > is done. In this case the only way to stop the session is to cancel the launch. > It is not very convenient but at least logical. Since you are dealing with a case where the initialization sequence takes some time, I think it would not be user-friendly to prevent terminating during that period. I think the user should be allowed to quickly cancel a launch that was maybe chosen by mistake. > The second solution is to change the logic of 'terminate' as it is done in the > patch. I've been trying this out by using a manual remote launch without a gdbserver running. The proposed path does not seem to work for that case. I get a dialog popup which says "Terminate failed". How about using this in terminate() instead: // If the initialization sequence is still running cancel it. if (fInitializationSequence != null) { fInitializationSequence.getRequestMonitor().cancel(); } This seems to work for my test. Does it fit your case? Also, fInitializationSequence should also be set to null in the case: if (rm instanceof RequestMonitorWithProgress) { I noticed that with DSF-GDB, it is never set to null, because that case is not taken care of.
(In reply to comment #6) > > The second solution is to change the logic of 'terminate' as it is done in the > > patch. > > I've been trying this out by using a manual remote launch without a gdbserver > running. > > The proposed path does not seem to work for that case. I get a dialog popup > which says "Terminate failed". > I have been trying a remote launch that starts gdbserver automatically. It gives all sorts of errors including "Terminate failed" and "Connection is shut down". > How about using this in terminate() instead: > > // If the initialization sequence is still running cancel it. > if (fInitializationSequence != null) { > fInitializationSequence.getRequestMonitor().cancel(); > } > That's what I did first but for some reason I was getting errors. Now I tried it again and it worked fine. > This seems to work for my test. Does it fit your case? > > Also, fInitializationSequence should also be set to null in the case: > if (rm instanceof RequestMonitorWithProgress) { > I noticed that with DSF-GDB, it is never set to null, because that case is not > taken care of. You're right, my internal patch handles this correctly, but just submitted the wrong one. Sorry, my brain hasn't been functioning well lately because of my illness.
Created attachment 212566 [details] Modified patch.
(In reply to comment #8) > Created attachment 212566 [details] > Modified patch. Why do you put a return after cancelling the initalSequence monitor? In my case it makes the terminate fail. I think we should continue with the terminate operation to kill GDB after the 2 second timeout, which cleans up everything. I'm also getting this assertion. Uncaught exception in session executor thread: java.lang.AssertionError at org.eclipse.cdt.dsf.concurrent.RequestMonitor.setStatus(RequestMonitor.java:175) at org.eclipse.cdt.dsf.gdb.service.command.GDBControl$5.handleCompleted(GDBControl.java:309) I think we need to check if the status has a severity of IStatus.CANCEL and not set the status in that case. Also, I noticed that without the two changes above, the Progress View keeps showing the launch forever.
(In reply to comment #9) > Why do you put a return after cancelling the initalSequence monitor? In my > case it makes the terminate fail. I think we should continue with the > terminate operation to kill GDB after the 2 second timeout, which cleans up > everything. > The idea is that cancelling the initial sequence will take of GDB. Isn't it a correct assumption? > I'm also getting this assertion. > > Uncaught exception in session executor thread: java.lang.AssertionError > at > org.eclipse.cdt.dsf.concurrent.RequestMonitor.setStatus(RequestMonitor.java:175) > at > org.eclipse.cdt.dsf.gdb.service.command.GDBControl$5.handleCompleted(GDBControl.java:309) > > I think we need to check if the status has a severity of IStatus.CANCEL and not > set the status in that case. > I believe this assertion was the reason that I switched to cancelling the progress monitor instead of just cancelling the sequence. I switched back when you pointed to it and haven't got the assertion anymore. > Also, I noticed that without the two changes above, the Progress View keeps > showing the launch forever. I suspect the cancellation of the launch sequence for remote launches is not handled correctly. Besides the error messages, the launch sometimes stays in the view, sometimes gdbserver remains running and I have to kill it manually. I will investigate more.
(In reply to comment #10) > The idea is that cancelling the initial sequence will take of GDB. Isn't it a > correct assumption? Does not seem to happen with the proposed patch. Maybe you have to do something special in the handleCompleted() call for the initialization sequence?
(In reply to comment #11) > (In reply to comment #10) > > The idea is that cancelling the initial sequence will take of GDB. Isn't it a > > correct assumption? > > Does not seem to happen with the proposed patch. Maybe you have to do > something special in the handleCompleted() call for the initialization > sequence? My logic is that it should work in the same way as if the launch is cancelled from the Progress view. If it doesn't then there is a bug in the launch sequence. I suspect the cancellation fails because of the assertion. Can you please try (if you have time of course) switching back to cancelling the progress monitor? Meanwhile I'll investigate what's going on with the remote launch.
(In reply to comment #12) > My logic is that it should work in the same way as if the launch is cancelled > from the Progress view. If it doesn't then there is a bug in the launch > sequence. I suspect the cancellation fails because of the assertion. Can you > please try (if you have time of course) switching back to cancelling the > progress monitor? Meanwhile I'll investigate what's going on with the remote > launch. With the Manual remote launch and the master branch (not your patch), I cannot cancel the launch using the progress monitor during the initialization sequence. I think this needs to be fixed first if you want to re-use that approach.
(In reply to comment #13) > I think this needs to be fixed first if you want to re-use that approach. Marc, this is a bug in the remote launch configuration type. The cancellation is not handled properly. We need to create a separate bugzilla entry for it. I don't understand why is it related to a more common problem - how to terminate a session when it is still in the initialization stage. Is it because there is no other way to reproduce the original issue?
(In reply to comment #14) > (In reply to comment #13) > > I think this needs to be fixed first if you want to re-use that approach. > > Marc, this is a bug in the remote launch configuration type. The cancellation > is not handled properly. We need to create a separate bugzilla entry for it. I > don't understand why is it related to a more common problem - how to terminate > a session when it is still in the initialization stage. Is it because there is > no other way to reproduce the original issue? I didn't realize this was only a remote launch bug. I'm using that scenario because that is what I found to reproduce the issue. What else can I do? Maybe not return a reply for a command in the init sequence, by hacking AbstractMIControl?
(In reply to comment #15) > Maybe not return a reply for a command in the init sequence, by hacking > AbstractMIControl? I've done this and it makes the initialization hang as I wished. I do a local launch, which 'hangs' during the initialization. If I then try to terminate the launch I see, as expected: Error in final launch sequence Connection is shut down but if I try to cancel the launch in the progress view, nothing happens. This is a local launch. Have you been able to cancel with the progress view? How do you do it?
(In reply to comment #16) > I do a local launch, which 'hangs' during the initialization. If I then try to > terminate the launch I see, as expected: > Error in final launch sequence > Connection is shut down > > but if I try to cancel the launch in the progress view, nothing happens. This > is a local launch. > > Have you been able to cancel with the progress view? How do you do it? I added 'Thread.sleep(1000)' at the beginning of 'Sequence.executeNextStep()' to slow down the launching. I start a local launch, wait for 'Terminate()' to become enabled and then cancel the session from the progress view. This works fine. When I terminate a local session when the initialization sequence is running I get "Connection is shut down" error. You say this is expected but we have complains that it is confusing. In fact if there is no errors the session should be terminated silently. Using my patch I get "Terminate failed" error and GDB process remains active. This shouldn't happen, my patch works fine with our launchers. I don't understand it but will look at it tomorrow.
(In reply to comment #17) > (In reply to comment #16) > > I do a local launch, which 'hangs' during the initialization. If I then try to > > terminate the launch I see, as expected: > > Error in final launch sequence > > Connection is shut down > > > > but if I try to cancel the launch in the progress view, nothing happens. This > > is a local launch. > > > > Have you been able to cancel with the progress view? How do you do it? > > I added 'Thread.sleep(1000)' at the beginning of 'Sequence.executeNextStep()' > to slow down the launching. I tried this. I slows it down a _lot_ :) > I start a local launch, wait for 'Terminate()' to become enabled and then > cancel the session from the progress view. This works fine. That case works for me too. Depending on the timing of when I cancel the launch, I sometimes get the gdb process never being killed (you have to do a ps on a shell to see it). > When I terminate a local session when the initialization sequence is running I > get "Connection is shut down" error. You say this is expected but we have > complains that it is confusing. In fact if there is no errors the session > should be terminated silently. Sorry. When I said it was "expected" I meant that it fit what you had reported in comment 0. I agree with you that it is not user-friendly, and I think you wanting to fix it is a good thing. Thanks for that. > Using my patch I get "Terminate failed" error and GDB process remains active. That is why I thought we needed to remove the 'return' from your patch. But maybe there is something else broken that should be killing GDB... > This shouldn't happen, my patch works fine with our launchers. I don't > understand it but will look at it tomorrow.
(In reply to comment #16) > (In reply to comment #15) > > > Maybe not return a reply for a command in the init sequence, by hacking > > AbstractMIControl? > > I've done this and it makes the initialization hang as I wished. > > I do a local launch, which 'hangs' during the initialization. If I then try to > terminate the launch I see, as expected: > Error in final launch sequence > Connection is shut down > > but if I try to cancel the launch in the progress view, nothing happens. This > is a local launch. I understand why this does not work with the progress view. In my case, or in the case of the remote launch, the initialization sequence is completely stopped, waiting for an answer from GDB. The progressMonitor is not checked, until the answer from GDB arrives. Using Terminate does work as it forcibly kills GDB and frees up the sequence.
(In reply to comment #19) > (In reply to comment #16) > > (In reply to comment #15) > > > > > Maybe not return a reply for a command in the init sequence, by hacking > > > AbstractMIControl? > > > > I've done this and it makes the initialization hang as I wished. > > > > I do a local launch, which 'hangs' during the initialization. If I then try to > > terminate the launch I see, as expected: > > Error in final launch sequence > > Connection is shut down > > > > but if I try to cancel the launch in the progress view, nothing happens. This > > is a local launch. > > I understand why this does not work with the progress view. In my case, or in > the case of the remote launch, the initialization sequence is completely > stopped, waiting for an answer from GDB. The progressMonitor is not checked, > until the answer from GDB arrives. I suspected that would be the case but didn't have a chance to check it.
I have figured out why we get "Terminate failed" message when using my patch (the one that cancels the progress monitor of the initialization sequence). Pressing the "Terminate" button results in calling 'Launch.terminate()' which calls 'GDBPRocess.destroy()' and then waits for the process' exit value, see 'RuntimeProcess.terminate()'. 'GDBProcess.destroy()' calls 'IGDBControl.terminate()' which cancels the initialization sequence and starts the shutdown sequence. Because we have a long delay added to each step of any sequence, executing the shutdown sequence takes longer than the wait time in 'RuntimeProcess.terminate()'. 'RuntimeProcess.terminate()' exhausts all attempts to get the exit value and throws an exception with "Terminate failed" message. The exception doesn't mean anything - the session is still canceled properly. This shouldn't happen in the real life, because the execution of the shutdown sequence doesn't take much time. I guess that is the reason why my patch works fine with our launchers. I don't really know what to do with this patch. We can use it in our fork of CDT but I think it would be good to have it in the standard CDT.
(In reply to comment #21) > I have figured out why we get "Terminate failed" message when using my patch > (the one that cancels the progress monitor of the initialization sequence). > Pressing the "Terminate" button results in calling 'Launch.terminate()' which > calls 'GDBPRocess.destroy()' and then waits for the process' exit value, see > 'RuntimeProcess.terminate()'. 'GDBProcess.destroy()' calls > 'IGDBControl.terminate()' which cancels the initialization sequence Ok, this all makes sense. > and starts the shutdown sequence. How does this happen? The launch calls GDBProcess.destroy() which calls IGDBControl.terminate(). But because of the return statement after cancelling the init sequence, the gdb process is not killed, and the shutdown sequence is not called for me. In fact, although the launch says 'terminated', GDB is still running when I do a ps. > Because we have a long delay added to each step of any > sequence, executing the shutdown sequence takes longer than the wait time in > 'RuntimeProcess.terminate()'. 'RuntimeProcess.terminate()' exhausts all > attempts to get the exit value and throws an exception with "Terminate failed" > message. The exception doesn't mean anything - the session is still canceled > properly. Agreed. > This shouldn't happen in the real life, because the execution of the shutdown > sequence doesn't take much time. I guess that is the reason why my patch works > fine with our launchers. > I don't really know what to do with this patch. We can use it in our fork of > CDT but I think it would be good to have it in the standard CDT. Yes, I think the patch should be in CDT, but I think the 'return' statement should be removed, no? And I'm still seeing the assertion of comment 9. You don't get the assertion?
(In reply to comment #22) > (In reply to comment #21) > > I have figured out why we get "Terminate failed" message when using my patch > > (the one that cancels the progress monitor of the initialization sequence). > > Pressing the "Terminate" button results in calling 'Launch.terminate()' which > > calls 'GDBPRocess.destroy()' and then waits for the process' exit value, see > > 'RuntimeProcess.terminate()'. 'GDBProcess.destroy()' calls > > 'IGDBControl.terminate()' which cancels the initialization sequence > > Ok, this all makes sense. > > > and starts the shutdown sequence. > > How does this happen? The launch calls GDBProcess.destroy() which calls > IGDBControl.terminate(). But because of the return statement after cancelling > the init sequence, the gdb process is not killed, and the shutdown sequence is > not called for me. In fact, although the launch says 'terminated', GDB is > still running when I do a ps. > When I cancel or terminate (which is the same with my patch) a session the gdb process is gone. I see the process with ps but then it's gone. It takes some time because of the delay I added to 'Sequence'. I don't really understand how it is killed, haven't been able to find the code that does it. Is the gdb processs killed when you cancel a session from the progress view? > Yes, I think the patch should be in CDT, but I think the 'return' statement > should be removed, no? > And I'm still seeing the assertion of comment 9. You don't get the assertion? I replaced fInitializationSequence.getRequestMonitor().cancel() by my old code ((RequestMonitorWithProgess)fInitializationSequence.getRequestMonitor()).getProgressMonitor().setCanceled(true) and don't get the assertion anymore. This code does is programmatic equivalent of pressing the "Cancel" button in the progress view. If the gdb process is not killed we rather need to fix the cancellation code.
(In reply to comment #23) > When I cancel or terminate (which is the same with my patch) a session the gdb > process is gone. I see the process with ps but then it's gone. It takes some > time because of the delay I added to 'Sequence'. Mine remains every time. I have to kill it from a shell. > I don't really understand how > it is killed, haven't been able to find the code that does it. > Is the gdb processs killed when you cancel a session from the progress view? > This code does is programmatic equivalent of pressing the "Cancel" button in > the progress view. If the gdb process is not killed we rather need to fix the > cancellation code. I looked into it and I think I found the problem. The GdbLaunchDelegate used to shutdown the launch when it got a cancellationException. However, I broke that when I made it go through IGDBControl.completeInitialization() since the CancellationException does not make it the GdbDelegate anymore. I've opened Bug 374374 and am looking at how to fix it. Do you use IGDBControl.completeInitialization() in your launch delegate?
(In reply to comment #24) > I looked into it and I think I found the problem. The GdbLaunchDelegate used > to shutdown the launch when it got a cancellationException. However, I broke > that when I made it go through IGDBControl.completeInitialization() since the > CancellationException does not make it the GdbDelegate anymore. I think I didn't get all the story here. I'm looking at it again.
(In reply to comment #25) > (In reply to comment #24) > > > I looked into it and I think I found the problem. The GdbLaunchDelegate used > > to shutdown the launch when it got a cancellationException. However, I broke > > that when I made it go through IGDBControl.completeInitialization() since the > > CancellationException does not make it the GdbDelegate anymore. > > I think I didn't get all the story here. I'm looking at it again. Please see details in Bug 374374.
(In reply to comment #23) > I replaced > > fInitializationSequence.getRequestMonitor().cancel() > > by my old code > > ((RequestMonitorWithProgess)fInitializationSequence.getRequestMonitor()).getProgressMonitor().setCanceled(true) > > and don't get the assertion anymore. > This code does is programmatic equivalent of pressing the "Cancel" button in > the progress view. If the gdb process is not killed we rather need to fix the > cancellation code. With the fix to Bug 374374, it looks like the above solution works properly when slowing down Sequences. However, for MI commands that 'hang' for a while, like "-target-select remote", it does not work because the Sequence is not progressing at all, so the ProgressMonitor being cancelled is never noticed. I've even seen Eclipse deadlock sometimes when testing that scenario. I think the case of a long-running "-target-select remote" can happen in the real world, so we need to have a solution that works for it (or at least, does not make it worse than currently). Thinking about this, I am also leaning towards the fact that if the user presses Terminate, we should see the launch remain in the Debug view and show <terminated>, instead of disappearing completely. So, if possible, can we handle 'terminate' as terminate and 'cancel' as cancel?
Marc, after all I don't think my patch is correct. At least the cancellation of the initialization sequence can not be done in IGDBControl.terminate() because it is called in GDBBackendCLIProcess.destroy(). We can still use cancel as terminate at the higher level by overriding Launch.terminate() but this would require a new API. What do you think we should do with this issue?
(In reply to comment #27) > Thinking about this, I am also leaning towards the fact that if the user > presses Terminate, we should see the launch remain in the Debug view and show > <terminated>, instead of disappearing completely. So, if possible, can we > handle 'terminate' as terminate and 'cancel' as cancel? Can we get rid of the "Connection is shut down" errors?
(In reply to comment #29) > (In reply to comment #27) > > > Thinking about this, I am also leaning towards the fact that if the user > > presses Terminate, we should see the launch remain in the Debug view and show > > <terminated>, instead of disappearing completely. So, if possible, can we > > handle 'terminate' as terminate and 'cancel' as cancel? > > Can we get rid of the "Connection is shut down" errors? :) I wasn't clear in what I meant. I think that if the user presses Terminate, we should terminate the launch cleanly. The "Connection is shut down" errors are not nice and we should get rid of them. I still thought you patch was a good way forward, except that we should let the terminate complete, instead of relying on the cancel to work. (In reply to comment #28) > Marc, after all I don't think my patch is correct. At least the > cancellation of the initialization sequence can not be done in > IGDBControl.terminate() because it is called in > GDBBackendCLIProcess.destroy(). Can you explain the problem? > We can still use cancel as terminate at the higher level by overriding > Launch.terminate() but this would require a new API. What do you think we > should do with this issue? Hopefully we can use terminate instead of cancel to make this happen cleanly.
(In reply to comment #30) > (In reply to comment #28) > > Marc, after all I don't think my patch is correct. At least the > > cancellation of the initialization sequence can not be done in > > IGDBControl.terminate() because it is called in > > GDBBackendCLIProcess.destroy(). > > Can you explain the problem? My patch produces the following loop: Cancellation -> shutdown of 'GDBBackend' -> GDBBackendCLIProcess.destroy() -> GDBControl.terminate() -> Cancellation It is not happening because the gdb process is killed by GDBControl which closes the std streams. If we can rely on it for all platforms why do we need the code that kills the gdb process explicitly? Also GDBBackendCLIProcess.destroy() will always cancel the initialization sequence. This is probably the right thing to do but I am not 100% sure.
(In reply to comment #31) > My patch produces the following loop: > > Cancellation -> shutdown of 'GDBBackend' -> GDBBackendCLIProcess.destroy() -> > GDBControl.terminate() -> Cancellation I have to admit that I don't have a good grasp on all the different things happening, so I could be wrong about this, but I believe it is: Cancellation -> shutdown of 'GDBBackend' -> Process.destroy() The process that is killed in GDBBackend is the actual GDB process and no the RuntimeProcess that represents it (i.e., GDBBackendCLIProcess) > It is not happening because the gdb process is killed by GDBControl which > closes the std streams. If we can rely on it for all platforms why do we need > the code that kills the gdb process explicitly? Just to be sure, I removed the call to stopCommandProcessing() from GDBControl.CommandMonitoringStep, and things still worked ok with your patch. > Also GDBBackendCLIProcess.destroy() will always cancel the initialization > sequence. This is probably the right thing to do but I am not 100% sure. Hm... That is tricky. Can this be called when there is an error instead of when the user presses Terminate?
Created attachment 212755 [details] Suggested minor change to Mikhail's patch I've been trying out this fix and it seems ok. It is your patch with three minor changes: 1- Cancel the requestMonitor and not the ProgressMonitor. This is way for us to know later on that errors should be ignored because the sequence was cancelled. 2- remove the return statement when cancelling the initialization sequence. This will allow the forceQuitTask to be created, which will forcibly kill GDB if needed. For a hanging MI command (-target-select remote), we need this. It also gives us a safety that GDB will be killed for sure. 3- In completeInitialization(), check if the initSequence rm has been cancelled. This tells us that we should not report an error. So, we don't set the status(). This avoids the assertion to. Again, I have to admit that there are so many scenarios that I can't wrap my head around all of them. What do you think? (In reply to comment #32) > > Also GDBBackendCLIProcess.destroy() will always cancel the initialization > > sequence. This is probably the right thing to do but I am not 100% sure. > > Hm... That is tricky. Can this be called when there is an error instead of > when the user presses Terminate? I think we are ok for this. I believe GDBBackendCLIProcess.destroy() would either get called by a user request, so cancelling the initSeq is ok, or it could get called if there was an error in one of the steps of the initSeq, but by that time, the initSeq will already have been aborted by that failed step.
Marc, I've tried the patch with the standard CDT and with our launchers and it works fine. I think it is OK to commit it. Do you want me to do it?
(In reply to comment #34) > Marc, > I've tried the patch with the standard CDT and with our launchers and it works > fine. I think it is OK to commit it. > Do you want me to do it? It really is your solution. I only added minor tweaks. Go ahead a commit. Thanks.
Checked in.
Thanks for you patience Mikhail.
*** cdt git genie on behalf of Mikhail Khodjaiants *** Bug 373845 - Terminate should cancel the initialization sequence if it is still running [*] http://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/?id=d64f97835e7d948910eaee9577b778c9e94004a6