diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/DsfTerminateCommand.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/DsfTerminateCommand.java
index 4850e0781d1..904611a4b3b 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/DsfTerminateCommand.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/DsfTerminateCommand.java
@@ -12,6 +12,10 @@
 package org.eclipse.cdt.dsf.gdb.internal.ui.actions;
 
 import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 
 import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
 import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
@@ -21,18 +25,84 @@ import org.eclipse.cdt.dsf.datamodel.DMContexts;
 import org.eclipse.cdt.dsf.debug.service.IProcesses;
 import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
 import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
+import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
+import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
 import org.eclipse.cdt.dsf.service.DsfServicesTracker;
 import org.eclipse.cdt.dsf.service.DsfSession;
+import org.eclipse.cdt.dsf.service.DsfSession.SessionEndedListener;
 import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.debug.core.commands.IDebugCommandRequest;
 import org.eclipse.debug.core.commands.IEnabledStateRequest;
 import org.eclipse.debug.core.commands.ITerminateHandler;
 
 public class DsfTerminateCommand implements ITerminateHandler {
-    private final DsfExecutor fExecutor;
+
+	private class WaitForTerminationJob extends Job implements SessionEndedListener {
+
+		final private IDebugCommandRequest fRequest;
+		final private String fSessionId;
+		final private Lock fLock = new ReentrantLock();
+		final private Condition fTerminated = fLock.newCondition();
+
+		public WaitForTerminationJob(String sessionId, IDebugCommandRequest request) {
+			super("Wait for termination job"); //$NON-NLS-1$
+			setUser(false);
+			setSystem(true);
+			fSessionId = sessionId;
+			fRequest = request;
+			DsfSession.addSessionEndedListener(WaitForTerminationJob.this);
+		}
+
+		@Override
+		protected IStatus run(IProgressMonitor monitor) {
+			// Wait for all processes associated with the launch 
+			// and the shutdown sequence to be completed.
+			// The wait time is restricted to stop the job in case  
+			// of termination error.
+			boolean result = !DsfSession.isSessionActive(fSessionId);
+			if (!result) {
+				fLock.lock();
+				try {
+					result = fTerminated.await(1, TimeUnit.MINUTES);
+				}
+				catch(InterruptedException e) {
+				}
+				finally {
+					fLock.unlock();
+				}
+			}
+			// Marking the request as cancelled will prevent the removal of 
+			// the launch from the Debug view in case of "Terminate and Remove". 
+			fRequest.setStatus(result ? Status.OK_STATUS : Status.CANCEL_STATUS);
+			fRequest.done();
+			DsfSession.removeSessionEndedListener(WaitForTerminationJob.this);
+			return Status.OK_STATUS;
+		}
+
+		@Override
+		public void sessionEnded(DsfSession session) {
+			if (fSessionId.equals(session.getId())) {
+				fLock.lock();
+				try {
+					fTerminated.signal();
+				}
+				finally {
+					fLock.unlock();
+				}
+			}
+		}
+	}
+
+	private final DsfSession fSession;
+	private final DsfExecutor fExecutor;
     private final DsfServicesTracker fTracker;
     
     public DsfTerminateCommand(DsfSession session) {
+    	fSession = session;
         fExecutor = session.getExecutor();
         fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId());
     }    
@@ -41,17 +111,22 @@ public class DsfTerminateCommand implements ITerminateHandler {
         fTracker.dispose();
     }
 
-    // Run control may not be avilable after a connection is terminated and shut down.
+    // Run control may not be available after a connection is terminated and shut down.
     @Override
     public void canExecute(final IEnabledStateRequest request) {
         if (request.getElements().length != 1 || 
-            !(request.getElements()[0] instanceof IDMVMContext) ) 
-        {
+            !(request.getElements()[0] instanceof IDMVMContext || 
+              request.getElements()[0] instanceof GdbLaunch)) {
             request.setEnabled(false);
             request.done();
             return;
         }
 
+        if (request.getElements()[0] instanceof GdbLaunch) {
+        	canExecute(((GdbLaunch)request.getElements()[0]), request);
+        	return;
+        }
+
         IDMVMContext vmc = (IDMVMContext)request.getElements()[0];
         
         // First check if there is an ancestor process to terminate.  This is the smallest entity we can terminate
@@ -61,7 +136,72 @@ public class DsfTerminateCommand implements ITerminateHandler {
             request.done();
             return;
         }
-        
+
+        canExecute(processDmc, request);
+    }
+
+    @Override
+    public boolean execute(final IDebugCommandRequest request) {
+        if (request.getElements().length != 1 || 
+        	!(request.getElements()[0] instanceof IDMVMContext || 
+              request.getElements()[0] instanceof GdbLaunch)) {
+        	request.done();
+        	return false;
+        }
+
+        if (request.getElements()[0] instanceof GdbLaunch) {
+        	return execute(((GdbLaunch)request.getElements()[0]), request);
+        }
+
+        IDMVMContext vmc = (IDMVMContext)request.getElements()[0];
+
+        // First check if there is an ancestor process to terminate.  This is the smallest entity we can terminate
+        final IProcessDMContext processDmc = DMContexts.getAncestorOfType(vmc.getDMContext(), IProcessDMContext.class);
+        if (processDmc == null) {
+        	request.done();
+        	return false;
+        }
+
+        return execute(processDmc, request);
+    }
+
+    private void canExecute(GdbLaunch launch, IEnabledStateRequest request) {
+    	request.setEnabled(launch.canTerminate());
+    	request.done();
+    }
+
+    private boolean execute(GdbLaunch launch, final IDebugCommandRequest request) {    	
+        try {
+            fExecutor.execute(new DsfRunnable() { 
+                @Override
+                public void run() {
+                	final IGDBControl commandControl = fTracker.getService(IGDBControl.class);
+                    if (commandControl != null) {
+                    	commandControl.terminate(new ImmediateRequestMonitor() {
+                            @Override
+                            protected void handleCompleted() {
+                            	if (!isSuccess()) {
+                            		request.setStatus(getStatus());
+                            		request.done();
+                            	}
+                            	else {
+	                            	WaitForTerminationJob job = new WaitForTerminationJob(fSession.getId(), request);
+	                            	job.schedule();
+                            	}
+                            };
+                        });
+                    } else {
+                    	request.done();
+                    }
+                 }
+            });
+        } catch (RejectedExecutionException e) {
+            request.done();
+        }
+        return false;
+    }
+
+    private void canExecute(final IProcessDMContext processDmc, final IEnabledStateRequest request) {
         try {
             fExecutor.execute(
                 new DsfRunnable() { 
@@ -90,23 +230,7 @@ public class DsfTerminateCommand implements ITerminateHandler {
         }
     }
 
-    @Override
-    public boolean execute(final IDebugCommandRequest request) {
-        if (request.getElements().length != 1 || 
-        	!(request.getElements()[0] instanceof IDMVMContext)) {
-        	request.done();
-        	return false;
-        }
-
-        IDMVMContext vmc = (IDMVMContext)request.getElements()[0];
-
-        // First check if there is an ancestor process to terminate.  This is the smallest entity we can terminate
-        final IProcessDMContext processDmc = DMContexts.getAncestorOfType(vmc.getDMContext(), IProcessDMContext.class);
-        if (processDmc == null) {
-        	request.done();
-        	return false;
-        }
-
+    private boolean execute(final IProcessDMContext processDmc, final IDebugCommandRequest request) {
         try {
             fExecutor.execute(new DsfRunnable() { 
                 @Override
@@ -116,8 +240,14 @@ public class DsfTerminateCommand implements ITerminateHandler {
                     	procService.terminate(processDmc, new ImmediateRequestMonitor() {
                             @Override
                             protected void handleCompleted() {
-                                request.setStatus(getStatus());
-                                request.done();
+                            	if (!isSuccess()) {
+                            		request.setStatus(getStatus());
+                            		request.done();
+                            	}
+                            	else {
+	                            	WaitForTerminationJob job = new WaitForTerminationJob(fSession.getId(), request);
+	                            	job.schedule();
+                            	}
                             };
                         });
                     } else {
@@ -130,5 +260,4 @@ public class DsfTerminateCommand implements ITerminateHandler {
         }
         return false;
     }
-    
 }
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java
index 70d33d94110..c65e8f9404e 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java
@@ -56,6 +56,7 @@ import org.eclipse.debug.core.DebugException;
 import org.eclipse.debug.core.DebugPlugin;
 import org.eclipse.debug.core.ILaunch;
 import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.commands.ITerminateHandler;
 import org.eclipse.debug.core.model.IDisconnect;
 import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
 import org.eclipse.debug.core.model.ISourceLocator;
@@ -300,6 +301,10 @@ public class GdbLaunch extends DsfLaunch
     @SuppressWarnings("rawtypes")
     @Override
     public Object getAdapter(Class adapter) {
+    	// We replace the standard terminate handler by DsfTerminateHandler
+    	// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=377447.
+    	if (adapter.equals(ITerminateHandler.class))
+    		return getSession().getModelAdapter(adapter);
         // Must force adapters to be loaded.
         Platform.getAdapterManager().loadAdapter(this, adapter.getName());
         return super.getAdapter(adapter);