diff --git a/debug/org.eclipse.cdt.debug.application.product/debug.product b/debug/org.eclipse.cdt.debug.application.product/debug.product
index fe8724b97ea..cab34794d25 100644
--- a/debug/org.eclipse.cdt.debug.application.product/debug.product
+++ b/debug/org.eclipse.cdt.debug.application.product/debug.product
@@ -347,6 +347,9 @@ Java and all Java-based trademarks are trademarks of Oracle Corporation in the U
       <plugin id="org.eclipse.swt.win32.win32.x86_64" fragment="true"/>
       <plugin id="org.eclipse.team.core"/>
       <plugin id="org.eclipse.team.ui"/>
+      <plugin id="org.eclipse.tm.terminal.control"/>
+      <plugin id="org.eclipse.tm.terminal.view.core"/>
+      <plugin id="org.eclipse.tm.terminal.view.ui"/>
       <plugin id="org.eclipse.text"/>
       <plugin id="org.eclipse.tools.templates.core"/>
       <plugin id="org.eclipse.tools.templates.ui"/>
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF
index c60bc3436ba..35449285435 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF
@@ -25,7 +25,10 @@ Require-Bundle: org.eclipse.ui,
  org.eclipse.core.filesystem;bundle-version="1.2.0",
  org.eclipse.cdt.launch;bundle-version="6.1.0",
  org.eclipse.debug.core,
- org.eclipse.core.resources
+ org.eclipse.core.resources,
+ org.eclipse.tm.terminal.control;bundle-version="4.0.0",
+ org.eclipse.tm.terminal.view.core;bundle-version="4.0.0",
+ org.eclipse.tm.terminal.view.ui;bundle-version="4.1.0"
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Export-Package: org.eclipse.cdt.dsf.gdb.internal.ui;x-friends:="org.eclipse.cdt.docker.launcher",
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml
index 2afc82dc711..7d0180058cb 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml
@@ -515,9 +515,10 @@
             class="org.eclipse.cdt.dsf.gdb.internal.ui.console.ConsolePageParticipant"
             id="org.eclipse.cdt.dsf.gdb.ui.dsfGdbConsolePageParticipant">
          <enablement>
-            <instanceof
-                  value="org.eclipse.ui.console.IOConsole">
-            </instanceof>
+            <or>
+               <instanceof value="org.eclipse.ui.console.IOConsole"/>
+               <instanceof value="org.eclipse.cdt.dsf.gdb.internal.ui.console.GdbCliConsole"/>
+            </or>
          </enablement>
       </consolePageParticipant>
    </extension>
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbUIPlugin.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbUIPlugin.java
index 1bea161ab4a..5468fa6045c 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbUIPlugin.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbUIPlugin.java
@@ -12,6 +12,7 @@
 package org.eclipse.cdt.dsf.gdb.internal.ui;
 
 import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
+import org.eclipse.cdt.dsf.gdb.internal.ui.console.GdbCliConsoleManager;
 import org.eclipse.cdt.dsf.gdb.internal.ui.console.TracingConsoleManager;
 import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
 import org.eclipse.cdt.dsf.gdb.launching.LaunchMessages;
@@ -46,6 +47,7 @@ public class GdbUIPlugin extends AbstractUIPlugin {
     private static BundleContext fgBundleContext; 
 
     private static TracingConsoleManager fTracingConsoleManager;
+    private static GdbCliConsoleManager fGdbConsoleManager;
     
     private static IPreferenceStore fCorePreferenceStore;
     
@@ -67,6 +69,9 @@ public class GdbUIPlugin extends AbstractUIPlugin {
 		
 		fTracingConsoleManager = new TracingConsoleManager();
 		fTracingConsoleManager.startup();
+		
+		fGdbConsoleManager = new GdbCliConsoleManager();
+		fGdbConsoleManager.startup();
 	}
 
 	/*
@@ -76,6 +81,7 @@ public class GdbUIPlugin extends AbstractUIPlugin {
 	@Override
     public void stop(BundleContext context) throws Exception {
 		fTracingConsoleManager.shutdown();
+		fGdbConsoleManager.shutdown();
 
 		disposeAdapterSets();
 		plugin = null;
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsoleMessages.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsoleMessages.java
index 059e39b039b..d9e294d7130 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsoleMessages.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsoleMessages.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2010 Marc-Andre Laperle and others.
+ * Copyright (c) 2010, 2016 Marc-Andre Laperle and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -17,7 +17,7 @@ import org.eclipse.osgi.util.NLS;
  */
 public class ConsoleMessages extends NLS {
 	public static String ConsoleMessages_trace_console_name;
-	public static String ConsoleMessages_trace_console_terminated;
+	public static String ConsoleMessages_console_terminated;
 
 	public static String ConsoleMessages_save_action_tooltip;
 	public static String ConsoleMessages_save_confirm_overwrite_title;
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsoleMessages.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsoleMessages.properties
index 5aafada28d0..7d098d352f9 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsoleMessages.properties
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsoleMessages.properties
@@ -1,5 +1,5 @@
 ##########################################################################
-# Copyright (c) 2010 Marc-Andre Laperle and others.
+# Copyright (c) 2010, 2016 Marc-Andre Laperle and others.
 # All rights reserved. This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
@@ -10,7 +10,7 @@
 ##########################################################################
  
 ConsoleMessages_trace_console_name=gdb traces
-ConsoleMessages_trace_console_terminated=<terminated> 
+ConsoleMessages_console_terminated=<terminated> 
  
 ConsoleMessages_save_action_tooltip=Save console content
 ConsoleMessages_save_confirm_overwrite_title=Confirm overwrite
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsolePageParticipant.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsolePageParticipant.java
index a8ff90be11a..73b3dfa60db 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsolePageParticipant.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsolePageParticipant.java
@@ -57,7 +57,8 @@ public class ConsolePageParticipant implements IConsolePageParticipant, IDebugCo
         	DebugUITools.getDebugContextManager().getContextService(fPage.getSite().getWorkbenchWindow()).addDebugContextListener(this);
         }
 
-		if(console instanceof TracingConsole || isConsoleGdbCli(console)) {
+		if (console instanceof TracingConsole || 
+				(isConsoleGdbCli(console) && console instanceof TextConsole)) {
 			TextConsole textConsole = (TextConsole) console;
 
 			// Add the save console action
@@ -81,6 +82,9 @@ public class ConsolePageParticipant implements IConsolePageParticipant, IDebugCo
 			org.eclipse.debug.ui.console.IConsole debugConsole  = (org.eclipse.debug.ui.console.IConsole)console;
 			return (debugConsole.getProcess() instanceof GDBProcess);
 		}
+		if (console instanceof GdbCliConsole) {
+			return true;
+		}
 		return false;
 	}
 
@@ -152,6 +156,10 @@ public class ConsolePageParticipant implements IConsolePageParticipant, IDebugCo
         	return null;
         }
 
+        if (context instanceof GDBProcess) {
+        	return (GDBProcess)context;
+        }
+        
 		if (context != null) {
 			// Look for the process that this context refers to, so we can select its console
 			IDMContext dmc = context.getAdapter(IDMContext.class);
@@ -187,12 +195,18 @@ public class ConsolePageParticipant implements IConsolePageParticipant, IDebugCo
 		return null;
 	}
 	
-	/* (non-Javadoc)
-	 * @see org.eclipse.debug.internal.ui.contexts.provisional.IDebugContextListener#contextEvent(org.eclipse.debug.internal.ui.contexts.provisional.DebugContextEvent)
-	 */
     @Override
 	public void debugContextChanged(DebugContextEvent event) {
 		if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) {
+			if (fView != null && fConsole instanceof GdbCliConsole) {
+				IProcess currentProcess = getCurrentProcess();
+				if (currentProcess instanceof GDBProcess && 
+						((GdbCliConsole)fConsole).getLaunch().equals(currentProcess.getLaunch())) {
+					fView.display(fConsole);
+				}
+				return;
+			}
+			
 			IProcess consoleProcess = getConsoleProcess();
 			if (fView != null && consoleProcess != null && consoleProcess.equals(getCurrentProcess())) {
 	            fView.display(fConsole);
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsole.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsole.java
new file mode 100644
index 00000000000..68f1e820803
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsole.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal.ui.console;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.console.AbstractConsole;
+import org.eclipse.ui.console.IConsoleView;
+import org.eclipse.ui.part.IPageBookViewPage;
+
+/**
+ * A GDB CLI console.
+ * This console actually runs a GDB process in CLI mode to achieve a 
+ * full-featured CLI interface.  This is only supported with GDB >= 7.12
+ * and if IGDBBackend.isFullGdbConsoleSupported() returns true.
+ */
+public class GdbCliConsole extends AbstractConsole {
+	private final ILaunch fLaunch;
+	private String fLabel;
+	
+	public GdbCliConsole(ILaunch launch, String label) {
+		super(label, null);
+		fLaunch = launch;
+        fLabel = label;
+        
+        resetName();
+	}
+    
+	public ILaunch getLaunch() { return fLaunch; }
+    
+    public void resetName() {
+    	String newName = computeName();
+    	String name = getName();
+    	if (!name.equals(newName)) {
+    		PlatformUI.getWorkbench().getDisplay().asyncExec(() -> setName(newName));
+    	}
+    }
+	
+    protected String computeName() {
+        String label = fLabel;
+
+        ILaunchConfiguration config = fLaunch.getLaunchConfiguration();
+        if (config != null && !DebugUITools.isPrivate(config)) {
+        	String type = null;
+        	try {
+        		type = config.getType().getName();
+        	} catch (CoreException e) {
+        	}
+        	StringBuffer buffer = new StringBuffer();
+        	buffer.append(config.getName());
+        	if (type != null) {
+        		buffer.append(" ["); //$NON-NLS-1$
+        		buffer.append(type);
+        		buffer.append("] "); //$NON-NLS-1$
+        	}
+        	buffer.append(label);
+        	label = buffer.toString();
+        }
+
+        if (fLaunch.isTerminated()) {
+        	return ConsoleMessages.ConsoleMessages_console_terminated + label; 
+        }
+        
+        return label;
+    }
+
+    @Override
+	public IPageBookViewPage createPage(IConsoleView view) {
+		view.setFocus();
+		return new GdbCliConsolePage(this);
+    }
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsoleManager.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsoleManager.java
new file mode 100644
index 00000000000..b61a7b194e4
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsoleManager.java
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2015 Ericsson and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Ericsson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal.ui.console;
+
+import java.util.concurrent.RejectedExecutionException;
+
+import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
+import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
+import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
+import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
+import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
+import org.eclipse.cdt.dsf.mi.service.IMIBackend;
+import org.eclipse.cdt.dsf.mi.service.IMIBackend.BackendStateChangedEvent;
+import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
+import org.eclipse.cdt.dsf.service.DsfServicesTracker;
+import org.eclipse.cdt.dsf.service.DsfSession;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchesListener2;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleManager;
+
+/**
+ * A console manager for GDB sessions which adds and removes
+ * gdb cli consoles.
+ * 
+ * There is a single such console per debug session.
+ * This console interacts directly with the GDB process using
+ * the standard GDB CLI interface.
+ * These consoles cannot be enabled/disabled by the user.
+ * However, they are only supported by GDB >= 7.12;
+ * to handle this limitation, the console manager will use the DSF Backend
+ * service to establish if it should start a gdb cli console or not.
+ */
+public class GdbCliConsoleManager implements ILaunchesListener2 {
+
+	/**
+	 * Start the tracing console.  We don't do this in a constructor, because
+	 * we need to use <code>this</code>.
+	 */
+	public void startup() {
+		// Listen to launch events
+		DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
+	}
+
+	public void shutdown() {
+		DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
+		removeAllCliConsoles();
+	}
+
+	protected void removeAllCliConsoles() {
+		ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager().getLaunches();
+		for (ILaunch launch : launches) {
+			removeCliConsole(launch);
+		}
+	}
+
+    @Override
+	public void launchesAdded(ILaunch[] launches) {
+		for (ILaunch launch : launches) {
+			addCliConsole(launch);
+		}
+	}
+
+    @Override
+	public void launchesChanged(ILaunch[] launches) {
+	}
+
+    @Override
+	public void launchesRemoved(ILaunch[] launches) {
+		for (ILaunch launch : launches) {
+			removeCliConsole(launch);
+		}
+	}
+	
+    @Override
+	public void launchesTerminated(ILaunch[] launches) {
+		for (ILaunch launch : launches) {
+			renameCliConsole(launch);
+		}
+	}
+	
+	protected void addCliConsole(ILaunch launch) {
+		// Full CLI GDB consoles are only added for GdbLaunches
+		if (launch instanceof GdbLaunch) {
+			new GdbCliConsoleCreator((GdbLaunch)launch).init();
+		}
+	}
+
+	protected void removeCliConsole(ILaunch launch) {
+		GdbCliConsole console = getCliConsole(launch);
+		if (console != null) {
+			ConsolePlugin.getDefault().getConsoleManager().removeConsoles(new IConsole[]{console});
+		}
+	}
+
+	protected void renameCliConsole(ILaunch launch) {
+		GdbCliConsole console = getCliConsole(launch);
+		if (console != null) {
+			console.resetName();
+		}		
+	}
+
+	private GdbCliConsole getCliConsole(ILaunch launch) {
+		ConsolePlugin plugin = ConsolePlugin.getDefault();
+		if (plugin != null) {
+			// This plugin can be null when running headless JUnit tests
+			IConsoleManager manager = plugin.getConsoleManager(); 
+			IConsole[] consoles = manager.getConsoles();
+			for (IConsole console : consoles) {
+				if (console instanceof GdbCliConsole) {
+					GdbCliConsole gdbConsole = (GdbCliConsole)console;
+					if (gdbConsole.getLaunch().equals(launch)) {
+						return gdbConsole;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Class that determines if a GdbCliConsole should be created for
+	 * this particular Gdblaunch.  It figures this out by asking the
+	 * Backend service.
+	 */
+	private class GdbCliConsoleCreator {
+		private GdbLaunch fLaunch;
+		private DsfSession fSession;
+		
+		public GdbCliConsoleCreator(GdbLaunch launch) {
+			fLaunch = launch;
+			fSession = launch.getSession();
+		}
+		
+		public void init() {
+			try {
+				fSession.getExecutor().submit(new DsfRunnable() {
+		        	@Override
+		        	public void run() {
+		        		// Look for backend service right away.  It probably 
+		        		// won't be available yet but we must make sure.
+		            	DsfServicesTracker tracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), fSession.getId());
+		            	IGDBBackend backend = tracker.getService(IGDBBackend.class);
+		            	tracker.dispose();
+		            	
+		            	if (backend != null) {
+		            		// Backend service already available, us it!
+		            		verifyAndCreateCliConsole(backend);
+		            	} else {
+		            		// Backend service not available yet, let's wait for it to start.
+		            		fSession.addServiceEventListener(new GdbBackendStartedListener(GdbCliConsoleCreator.this, fSession), null);
+		            	}
+		        	}
+		        });
+			} catch (RejectedExecutionException e) {
+			}
+		}
+		
+		@ConfinedToDsfExecutor("fSession.getExecutor()")
+		private void verifyAndCreateCliConsole(IGDBBackend backend) {
+			if (backend != null && backend.isFullGdbConsoleSupported()) {
+				// Create an new Cli console .
+				String gdbVersion;
+				try {
+					gdbVersion = fLaunch.getGDBVersion();
+				} catch (CoreException e) {
+					assert false : "Should not happen since the gdb version is cached"; //$NON-NLS-1$
+					gdbVersion = "???"; //$NON-NLS-1$
+				}
+				String consoleTitle = fLaunch.getGDBPath().toOSString().trim() + " (" + gdbVersion +")"; //$NON-NLS-1$ //$NON-NLS-2$
+
+				GdbCliConsole console = new GdbCliConsole(fLaunch, consoleTitle);
+
+				// Register this console
+				ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[]{console});
+
+				// Very important to make sure the console view is open or else things will not work
+				ConsolePlugin.getDefault().getConsoleManager().showConsoleView(console);
+			}
+    		// Else, not the right type of backend service, or the service said not to start a GdbCliConsole
+		}
+		
+		@ConfinedToDsfExecutor("fSession.getExecutor()")
+		private void backendStarted() {
+        	DsfServicesTracker tracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), fSession.getId());
+        	IGDBBackend backend = tracker.getService(IGDBBackend.class);
+        	tracker.dispose();
+
+    		verifyAndCreateCliConsole(backend);
+		}
+	}
+	
+	/**
+	 * Class used to listen for Backend started event which indicate
+	 * the DSF-GDB backend service can be used.
+	 * This class must be public to receive the event.
+	 */
+	public class GdbBackendStartedListener {
+		private DsfSession fSession;
+		private GdbCliConsoleCreator fCreator;
+		
+		public GdbBackendStartedListener(GdbCliConsoleCreator creator, DsfSession session) {
+			fCreator = creator;
+			fSession = session;
+		}
+		
+		@DsfServiceEventHandler
+	    public void eventDispatched(BackendStateChangedEvent event) {
+	        if (event.getState() == IMIBackend.State.STARTED &&
+	        		event.getSessionId().equals(fSession.getId())) 
+	        {
+	        	fCreator.backendStarted();
+	        	// No longer need to receive events.
+	        	fSession.removeServiceEventListener(this);
+	        }
+	    }
+	}
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsolePage.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsolePage.java
new file mode 100644
index 00000000000..c3600129d85
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsolePage.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2016 Ericsson and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal.ui.console;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.RejectedExecutionException;
+
+import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
+import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
+import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
+import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
+import org.eclipse.cdt.dsf.service.DsfServicesTracker;
+import org.eclipse.cdt.dsf.service.DsfSession;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.tm.internal.terminal.control.ITerminalListener;
+import org.eclipse.tm.internal.terminal.control.ITerminalViewControl;
+import org.eclipse.tm.internal.terminal.control.TerminalViewControlFactory;
+import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector;
+import org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl;
+import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
+import org.eclipse.tm.terminal.view.core.interfaces.ITerminalServiceOutputStreamMonitorListener;
+import org.eclipse.tm.terminal.view.core.interfaces.constants.ITerminalsConnectorConstants;
+import org.eclipse.tm.terminal.view.ui.interfaces.ILauncherDelegate;
+import org.eclipse.tm.terminal.view.ui.launcher.LauncherDelegateManager;
+import org.eclipse.ui.part.Page;
+
+public class GdbCliConsolePage extends Page {
+
+	private DsfSession fSession;
+	private Composite fMainComposite;
+	
+	/** The control for the terminal widget embedded in the console */
+	private ITerminalViewControl fTerminalControl;
+
+	public GdbCliConsolePage(GdbCliConsole gdbConsole) {
+		ILaunch launch = gdbConsole.getLaunch();
+		if (launch instanceof GdbLaunch) {
+			fSession = ((GdbLaunch)launch).getSession();
+		} else {
+			assert false;
+		}
+	}
+
+	@Override
+	public void dispose() {
+		super.dispose();
+		fTerminalControl.disposeTerminal();
+	}
+	
+	@Override
+	public void createControl(Composite parent) {
+		fMainComposite = new Composite(parent, SWT.NONE);
+		fMainComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+		fMainComposite.setLayout(new FillLayout());
+
+		// Create the terminal control that will be used to interact with GDB
+		fTerminalControl = TerminalViewControlFactory.makeControl(
+				new ITerminalListener() {
+					@Override public void setState(TerminalState state) {}
+					@Override public void setTerminalTitle(final String title) {}
+		        },
+				fMainComposite,
+				new ITerminalConnector[] {}, 
+				true);
+		
+		try {
+			fTerminalControl.setEncoding(Charset.defaultCharset().name());
+		} catch (UnsupportedEncodingException e) {
+		}
+		
+		// Hook the terminal control to the GDB process
+		attachTerminalToGdbProcess();
+	}
+
+	@Override
+	public Control getControl() {
+		return fMainComposite;
+	}
+
+	@Override
+	public void setFocus() {
+		fTerminalControl.setFocus();
+	}
+	
+	protected void attachTerminalToGdbProcess() {
+		if (fSession == null) {
+			return;
+		}
+
+		try {
+			fSession.getExecutor().submit(new DsfRunnable() {
+	        	@Override
+	        	public void run() {
+	            	DsfServicesTracker tracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), fSession.getId());
+	            	IGDBBackend backend = tracker.getService(IGDBBackend.class);
+	            	tracker.dispose();
+
+	            	if (backend != null) {
+	            		if (backend.getProcess() != null) {
+	            			attachTerminal(backend.getProcess());
+	            		}
+	            	}
+	        	}
+	        });
+		} catch (RejectedExecutionException e) {
+		}
+    }
+	
+	protected void attachTerminal(Process process) {
+		ILauncherDelegate delegate = 
+				LauncherDelegateManager.getInstance().getLauncherDelegate("org.eclipse.tm.terminal.connector.streams.launcher.streams", false); //$NON-NLS-1$
+		if (delegate != null) {
+			Map<String, Object> properties = createNewSettings(process);
+			
+			ITerminalConnector connector = delegate.createTerminalConnector(properties);
+			fTerminalControl.setConnector(connector);
+			if (fTerminalControl instanceof ITerminalControl) {
+				((ITerminalControl)fTerminalControl).setConnectOnEnterIfClosed(false);
+				((ITerminalControl)fTerminalControl).setVT100LineWrapping(true);
+			}
+
+			// Must use syncExec because the logic within must complete before the rest
+			// of the class methods (specifically getProcess()) is called
+			fMainComposite.getDisplay().syncExec(new Runnable() {
+				@Override
+				public void run() {
+					if (fTerminalControl != null && !fTerminalControl.isDisposed()) {
+						fTerminalControl.clearTerminal();
+						fTerminalControl.connectTerminal();
+					}
+				}
+			});
+		}
+	}
+	
+	protected Map<String, Object> createNewSettings(Process process) {
+		
+		// Create the terminal connector
+		Map<String, Object> properties = new HashMap<String, Object>();
+		properties.put(ITerminalsConnectorConstants.PROP_LOCAL_ECHO, Boolean.FALSE);
+		properties.put(ITerminalsConnectorConstants.PROP_STREAMS_STDIN, process.getOutputStream());
+		properties.put(ITerminalsConnectorConstants.PROP_STREAMS_STDOUT, process.getInputStream());
+		properties.put(ITerminalsConnectorConstants.PROP_STREAMS_STDERR, process.getErrorStream());
+		properties.put(ITerminalsConnectorConstants.PROP_STDOUT_LISTENERS, 
+				new ITerminalServiceOutputStreamMonitorListener[0]);
+		properties.put(ITerminalsConnectorConstants.PROP_STDERR_LISTENERS, 
+				new ITerminalServiceOutputStreamMonitorListener[0]);
+		return properties;
+	}
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/TracingConsole.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/TracingConsole.java
index e65bff0c98f..a60cab216f5 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/TracingConsole.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/TracingConsole.java
@@ -138,7 +138,7 @@ public class TracingConsole extends IOConsole {
         }
 
         if (fLaunch.isTerminated()) {
-        	return ConsoleMessages.ConsoleMessages_trace_console_terminated + label; 
+        	return ConsoleMessages.ConsoleMessages_console_terminated + label; 
         }
         
         return label;
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GDBProcess.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GDBProcess.java
index b36c99f117f..22cf639c5fd 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GDBProcess.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GDBProcess.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2010 Marc-Andre Laperle and others.
+ * Copyright (c) 2010, 2016 Marc-Andre Laperle and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -10,13 +10,21 @@
  *******************************************************************************/
 package org.eclipse.cdt.dsf.gdb.launching;
 
+import java.io.IOException;
 import java.util.Map;
 
+import org.eclipse.cdt.dsf.gdb.service.command.IGDBBackendProcessWithoutIO;
 import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.model.IStreamMonitor;
+import org.eclipse.debug.core.model.IStreamsProxy;
 import org.eclipse.debug.core.model.RuntimeProcess;
 
 /**
- * A process for the gdb backend to differentiate it from the inferior
+ * A process for the gdb backend to differentiate it from the inferior.
+ * 
+ * This process disables the base class handling of IO streams if we
+ * are using the full GDB console, which is handled by the
+ * GdbConsoleManager instead.
  * 
  * @since 3.0
  */
@@ -27,4 +35,56 @@ public class GDBProcess extends RuntimeProcess {
 		super(launch, process, name, attributes);
 	}
 
+	@Override
+	public IStreamsProxy getStreamsProxy() {
+		IStreamsProxy proxy = super.getStreamsProxy();
+		// If our proxy is the one that ignores the streams,
+		// this method should return null.
+		// Returning null insures that there will not be a
+		// text console automatically created for this process
+		// see ProcessConsoleManager#launchChanged()
+		return proxy instanceof NoStreamsProxy ? null : proxy;
+	}
+
+	@Override
+	protected IStreamsProxy createStreamsProxy() {
+		// TRICKY.  This method is called by the constructor of
+		// the super class.  This means we don't have time to
+		// set any fields in this class by then.  Therefore,
+		// we can only use what was set by the base class constructor
+		// to figure out how to behave.
+		// We can call getSystemProcess() as it is set earlier
+		// in the constructor then when this method is called.
+		if (getSystemProcess() instanceof IGDBBackendProcessWithoutIO) {
+			// If the GDB process used does not handle I/O, we return a proxy
+			// that ignores the streams.
+			return new NoStreamsProxy();
+		}
+		return super.createStreamsProxy();
+	}
+
+	/** 
+	 * Class that provides a streams proxy that actually
+	 * ignores the I/O streams.  We use this in the case
+	 * of the full GDB console where the GDB CLI is used directly,
+	 * without us needing to do anything with the I/O ourselves.
+	 * 
+	 * This is different than NullStreamsProxy which would
+	 * still read but discard the IO, which is not what we want.
+	 */
+	private class NoStreamsProxy implements IStreamsProxy {
+		@Override
+		public IStreamMonitor getErrorStreamMonitor() {
+			return null;
+		}
+
+		@Override
+		public IStreamMonitor getOutputStreamMonitor() {
+			return null;
+		}
+
+		@Override
+		public void write(String input) throws IOException {			
+		}
+	}
 }
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 6abe37d0eef..48ec7751db1 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
@@ -64,7 +64,6 @@ import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
 import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
 import org.eclipse.cdt.dsf.gdb.internal.memory.GdbMemoryBlockRetrievalManager;
 import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
-import org.eclipse.cdt.dsf.mi.service.command.AbstractCLIProcess;
 import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
 import org.eclipse.cdt.dsf.service.DsfServicesTracker;
 import org.eclipse.cdt.dsf.service.DsfSession;
@@ -202,13 +201,13 @@ public class GdbLaunch extends DsfLaunch implements ITerminate, IDisconnect, ITr
 	@ThreadSafeAndProhibitedFromDsfExecutor("getDsfExecutor()")
 	public void addCLIProcess(String label) throws CoreException {
 		try {
-			// Add the CLI process object to the launch.
-			AbstractCLIProcess cliProc = getDsfExecutor().submit(new Callable<AbstractCLIProcess>() {
+			// Add the GDB process object to the launch.
+			Process gdbProc = getDsfExecutor().submit(new Callable<Process>() {
 				@Override
-				public AbstractCLIProcess call() throws CoreException {
+				public Process call() throws CoreException {
 					IGDBControl gdb = fTracker.getService(IGDBControl.class);
 					if (gdb != null) {
-						return gdb.getCLIProcess();
+						return gdb.getGDBBackendProcess();
 					}
 					return null;
 				}
@@ -221,7 +220,7 @@ public class GdbLaunch extends DsfLaunch implements ITerminate, IDisconnect, ITr
 			Map<String, String> attributes = new HashMap<String, String>();
 			attributes.put(IGdbDebugConstants.PROCESS_TYPE_CREATION_ATTR,
 					IGdbDebugConstants.GDB_PROCESS_CREATION_VALUE);
-			DebugPlugin.newProcess(this, cliProc, label, attributes);
+			DebugPlugin.newProcess(this, gdbProc, label, attributes);
 		} catch (InterruptedException e) {
 			throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0,
 					"Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java
index 94ebb852dbe..d2fa6815355 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java
@@ -157,7 +157,8 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend, IMIBa
 		};
 	}
 
-	private GdbLaunch getGDBLaunch() {
+	/** @since 5.1 */
+	protected GdbLaunch getGDBLaunch() {
 		return (GdbLaunch) getSession().getModelAdapter(ILaunch.class);
 	}
 
@@ -171,7 +172,9 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend, IMIBa
 	 * array. Allow subclass to override.
 	 * 
 	 * @since 4.6
+	 * @deprecated Replaced by getDebuggerCommandLine()
 	 */
+    @Deprecated
 	protected String[] getGDBCommandLineArray() {
 		// The goal here is to keep options to an absolute minimum.
 		// All configuration should be done in the final launch sequence
@@ -189,6 +192,39 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend, IMIBa
 		return CommandLineUtil.argumentsToArray(cmd);
 	}
 
+	/**
+	 * Returns the GDB command and its arguments as an array.
+	 * Allow subclass to override.
+	 * @since 5.1
+	 */
+    // This method replaces getGDBCommandLineArray() because we need
+    // to override it for GDB 7.12 even if an extender has overridden
+    // getGDBCommandLineArray().
+    // Here is the scenario:
+    //   An extender has overridden getGDBCommandLineArray() to launch
+    //   GDB in MI mode but with extra parameters.  Once GDBBackend_7_12
+    //   is released, the extender may likely point their extension to
+    //   GDBBackend_7_12 instead of GDBBackend (which will even happen
+    //   automatically if the extender extends GDBBackend_HEAD).
+    //   In such a case, they would override the changes in 
+    //   GDBBackend_7_12.getGDBCommandLineArray() and the debug session
+    //   is likely to fail since with GDBBackend_7_12, we launch GDB
+    //   in CLI mode.
+    //
+    //   Instead, we use getDebuggerCommandLine() and override that method in
+    //   GDBBackend_7_12.  That way an extender will not override it
+    //   without noticing (since it didn't exist before).  Then we can call
+    //   the overridden getGDBCommandLineArray() and work with that to
+    //   make it work with the new way to launch GDB of GDBBackend_7_12
+    //
+    // Note that we didn't name this method getGDBCommandLine() because
+    // this name had been used in CDT 8.8 and could still be part of
+    // extenders' code.
+	protected String[] getDebuggerCommandLine() {
+		// Call the old method in case it was overridden
+		return getGDBCommandLineArray();
+	}
+
 	@Override
 	public String getGDBInitFile() throws CoreException {
 		return getGDBLaunch().getGDBInitFile();
@@ -236,12 +272,35 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend, IMIBa
 		return getGDBLaunch().getUpdateThreadListOnSuspend();
 	}
 
+	/**
+	 * Launch GDB process. Allow subclass to override.
+	 * 
+	 * @since 5.1
+	 */
+	// Again, we create a new method that we know has not been already
+	// overridden.  That way, even if extenders have overridden the
+	// original launchGDBProcess(String[]), we will instead use
+	// the GDBBackend_7_12#launchGDBProcess() method when appropriate.
+	// This is important because if we didn't, the new console would
+	// not work properly.
+	//
+	// Of course, in that case, we won't call the extenders overridden
+	// launchGDBProcess(String[]) and therefore will not get their
+	// specialized code.  I feel this is still a lower risk than
+	// not starting the full GDB console properly.
+	protected Process launchGDBProcess() throws CoreException {
+		// Call the old method in case it was overridden
+		return launchGDBProcess(getDebuggerCommandLine());
+	}
+
 	/**
 	 * Launch GDB process with command and arguments. Allow subclass to
 	 * override.
 	 * 
 	 * @since 4.6
+	 * @deprecated Replace by launchGDBProcess()
 	 */
+	@Deprecated
 	protected Process launchGDBProcess(String[] commandLine) throws CoreException {
 		Process proc = null;
 		try {
@@ -254,6 +313,7 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend, IMIBa
 		return proc;
 	}
 
+	@Override
 	public Process getProcess() {
 		return fProcess;
 	}
@@ -466,7 +526,8 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend, IMIBa
 				}
 
 				try {
-					fProcess = launchGDBProcess(getGDBCommandLineArray());
+                    fProcess = launchGDBProcess();
+
 					// Need to do this on the executor for thread-safety
 					getExecutor().submit(new DsfRunnable() {
 						@Override
@@ -488,8 +549,12 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend, IMIBa
 				BufferedReader errorReader = null;
 				boolean success = false;
 				try {
+					// Must call getMIInputStream() because we always want to read from the MI stream,
+					// which is not always the same as the input stream of fProcess.  They are
+					// different when we use the full GDB console
+					InputStream inputStream = getMIInputStream();
 					// Read initial GDB prompt
-					inputReader = new BufferedReader(new InputStreamReader(getMIInputStream()));
+					inputReader = new BufferedReader(new InputStreamReader(inputStream));
 					String line;
 					while ((line = inputReader.readLine()) != null) {
 						line = line.trim();
@@ -501,7 +566,11 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend, IMIBa
 
 					// Failed to read initial prompt, check for error
 					if (!success) {
-						errorReader = new BufferedReader(new InputStreamReader(getMIErrorStream()));
+						// Don't call getMIErrorStream() because it can be overridden with a
+						// dummy stream in the case of the full GDB console.
+						// Instead, make sure we read the error from the process itself.
+						InputStream errorStream = fProcess.getErrorStream();
+						errorReader = new BufferedReader(new InputStreamReader(errorStream));
 						String errorInfo = errorReader.readLine();
 						if (errorInfo == null) {
 							errorInfo = "GDB prompt not read"; //$NON-NLS-1$
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend_7_12.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend_7_12.java
new file mode 100644
index 00000000000..edb881e87ca
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend_7_12.java
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.service;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.eclipse.cdt.core.parser.util.StringUtil;
+import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
+import org.eclipse.cdt.dsf.service.DsfSession;
+import org.eclipse.cdt.utils.pty.PTY;
+import org.eclipse.cdt.utils.pty.PTY.Mode;
+import org.eclipse.cdt.utils.spawner.ProcessFactory;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Implementation of {@link IGDBBackend} using GDB 7.12. This version provides
+ * full GDB console support.  It achieves this by launching GDB in CLI mode
+ * in a special console widget and then connecting to GDB via MI by telling GDB to
+ * open a new MI console.  The rest of the DSF-GDB support then stays the same.
+ * 
+ * If we are unable to create a PTY, we then revert to the previous behavior of
+ * the base class.
+ * 
+ * @since 5.1
+ */
+public class GDBBackend_7_12 extends GDBBackend {
+
+	/** The PTY that is used to enable the full GDB console */
+	private PTY fPty;
+	/** Indicate that we failed to create a PTY. */
+	private boolean fPtyFailure;
+	
+	private InputStream fDummyErrorStream;
+
+	public GDBBackend_7_12(DsfSession session, ILaunchConfiguration lc) {
+		super(session, lc);
+		createPty();
+	}
+
+	@Override
+	public boolean isFullGdbConsoleSupported() {
+		return !Platform.getOS().equals(Platform.OS_WIN32)
+				&& !fPtyFailure;
+	}
+	
+	protected void createPty() {
+		if (!isFullGdbConsoleSupported()) {
+			return;
+		}
+		
+		try {
+			fPty = new PTY();
+			fPty.validateSlaveName();
+
+			// With the PTY the stderr is redirected to the PTY's output stream.
+			// Therefore, return a dummy stream for the error stream.
+			fDummyErrorStream = new InputStream() {
+				@Override
+				public int read() throws IOException {
+					return -1;
+				}
+			};
+		} catch (IOException e) {
+			fPty = null;
+			fPtyFailure = true;
+			GdbPlugin.log(new Status(
+							IStatus.INFO, GdbPlugin.PLUGIN_ID, 
+							NLS.bind(Messages.PTY_Console_not_available, e.getMessage())));
+		}
+	}
+	
+	@Override
+	public OutputStream getMIOutputStream() {
+		if (fPty == null) {
+			return super.getMIOutputStream();
+		}
+		return fPty.getOutputStream();
+	};
+
+	@Override
+	public InputStream getMIInputStream() {
+		if (fPty == null) {
+			return super.getMIInputStream();
+		}
+		return fPty.getInputStream();
+	};
+
+	@Override
+	public InputStream getMIErrorStream() {
+		if (fPty == null) {
+			return super.getMIErrorStream();
+		}
+		return fDummyErrorStream;
+	};
+
+	@Override
+	protected String[] getDebuggerCommandLine() {
+		// Start from the original command line method which
+		// could have been overridden by extenders, and add what we need
+		// to convert it to a command that will launch in CLI mode.
+		// Then trigger the MI console
+		@SuppressWarnings("deprecation")
+		String[] originalCommandLine = getGDBCommandLineArray();
+        
+        if (!isFullGdbConsoleSupported()) {
+            return originalCommandLine;
+        }
+
+        // Below are the parameters we need to add to an existing commandLine,
+        // to trigger a launch with the full CLI.  This would also work
+        // as the only parameters for a full CLI launch (although "--interpreter console"
+        // could be removed in that case)
+		String[] extraArguments = new String[] {
+				// Start with -q option to avoid extra output which may trigger pagination
+				// This is important because if pagination is triggered on the version
+				// printout, we won't be able to send the command to start the MI channel.
+				// Note that we cannot turn off pagination early enough to prevent the
+				// original version output from paginating
+				"-q", //$NON-NLS-1$
+				
+// We don't put --nx at this time because our base class puts it already and if
+// if an extender has removed it, we shouldn't add it again.
+// Once we no longer extends the deprecated getGDBCommandLineArray() and simply
+// create the full commandLine here, we should put it
+//				// Use the --nx option to avoid reading the gdbinit file here. 
+//				// The gdbinit file is read explicitly in the FinalLaunchSequence to make 
+//				// it easier to customize.
+//				"--nx", //$NON-NLS-1$
+				
+				// Force a CLI console since the originalCommandLine
+				// probably specified "-i mi" or "--interpreter mi"
+				// Once we no longer extend the deprecated 
+				// getGDBCommandLineArray() and simply create the full 
+				// commandLine here, we could remove this parameter
+				"--interpreter", "console", //$NON-NLS-1$ //$NON-NLS-2$
+				
+				// Now trigger the new console towards our PTY.
+				"-ex", "new-ui mi " + fPty.getSlaveName(), //$NON-NLS-1$ //$NON-NLS-2$
+								
+				// Now print the version so the user gets that familiar output
+				"-ex", "show version"  //$NON-NLS-1$ //$NON-NLS-2$
+		};
+
+		int oriLength = originalCommandLine.length;
+		int extraLength = extraArguments.length;
+		String[] newCommandLine = new String[oriLength+extraLength];
+		System.arraycopy(originalCommandLine, 0, newCommandLine, 0, oriLength);
+		System.arraycopy(extraArguments, 0, newCommandLine, oriLength, extraLength);
+
+		return newCommandLine;
+	}
+	
+	@Override
+	protected Process launchGDBProcess() throws CoreException {
+		if (!isFullGdbConsoleSupported()) {
+			return super.launchGDBProcess();
+		}
+		
+		// If we are launching the full console, we need to use a PTY in TERMINAL mode
+		// for the GDB CLI to properly display in its view
+		Process proc = null;
+		String[] commandLine = getDebuggerCommandLine();
+		try {
+			IPath path = getGDBWorkingDirectory();
+			proc = ProcessFactory.getFactory().exec(
+					commandLine, 
+					getGDBLaunch().getLaunchEnvironment(),
+					new File(path != null ? path.toOSString() : ""), //$NON-NLS-1$
+					new PTY(Mode.TERMINAL));
+		} catch (IOException e) {
+			String message = "Error while launching command: " + StringUtil.join(commandLine, " "); //$NON-NLS-1$ //$NON-NLS-2$
+			throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, message, e));
+		}
+
+		return proc;
+	}
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java
index e9814b248cc..1968421f67b 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java
@@ -88,6 +88,8 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
 	public static final String GDB_7_7_VERSION = "7.7"; //$NON-NLS-1$
 	/** @since 4.8 */
 	public static final String GDB_7_10_VERSION = "7.10"; //$NON-NLS-1$
+	/** @since 5.1 */
+	public static final String GDB_7_12_VERSION = "7.12"; //$NON-NLS-1$
 
 	private final String fVersion;
 	private final ILaunchConfiguration fConfiguration;
@@ -224,6 +226,11 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
 	}
 
 	protected IMIBackend createBackendGDBService(DsfSession session, ILaunchConfiguration lc) {
+		if (compareVersionWith(GDB_7_12_VERSION) >= 0
+				|| compareVersionWith("7.11.50") >= 0  // TODO remove once GDB 7.12 is released
+				) {
+			return new GDBBackend_7_12(session, lc);
+		}
 		return new GDBBackend(session, lc);
 	}
 
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java
index abbc9844869..4dccacc137d 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java
@@ -156,4 +156,21 @@ public interface IGDBBackend extends IMIBackend {
 	 * @since 3.0
 	 */
 	public boolean getUpdateThreadListOnSuspend() throws CoreException;
+	
+	/**
+	 * @return True if the full GDB console should be used.  False otherwise.
+	 * 
+	 * @since 5.1
+	 */
+	default boolean isFullGdbConsoleSupported() {
+		return false;
+	}
+	
+	/**
+	 * @return The real GDB process that was started for the debug session
+	 * @since 5.1
+	 */
+	default Process getProcess() {
+		throw new RuntimeException();
+	}
 }
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/Messages.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/Messages.java
index da5bc459d7a..a6657cce834 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/Messages.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/Messages.java
@@ -31,6 +31,7 @@ class Messages extends NLS {
 	public static String RegisterGroup_name_used;
 	public static String RegisterGroup_invalid_number_of_registers;
 	public static String GDB_Version_Mismatch;
+	public static String PTY_Console_not_available;
 	
 	static {
 		// initialize resource bundle
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/Messages.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/Messages.properties
index dd6e0eff46e..d2c0fd6f97e 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/Messages.properties
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/Messages.properties
@@ -22,4 +22,5 @@ ErrorNotSupported=Operation not supported with this GDB version
 RegisterGroup_name_reserved=The group name "{0}" is reserved
 RegisterGroup_name_used=The group name "{0}" is already in use
 RegisterGroup_invalid_number_of_registers=A minimum of one register is needed for a Register Group
-GDB_Version_Mismatch=Running older GDB version {0} when service {1} expects version {2} or higher
\ No newline at end of file
+GDB_Version_Mismatch=Running older GDB version {0} when service {1} expects version {2} or higher
+PTY_Console_not_available=PTY not available, cannot use full GDB console: {0}
\ No newline at end of file
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBBackendCLIProcess.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBBackendCLIProcess.java
index 3a07602ea84..0cec1bbc1c4 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBBackendCLIProcess.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBBackendCLIProcess.java
@@ -21,7 +21,12 @@ import org.eclipse.cdt.dsf.mi.service.IMIBackend;
 import org.eclipse.cdt.dsf.mi.service.command.MIBackendCLIProcess;
 import org.eclipse.cdt.dsf.service.DsfSession;
                                                                                                 
-/**                                                                                             
+/**              
+ * Note that starting with GDB 7.12, as long as a PTY is available,
+ * this process is no longer used.  Instead, the real GDB process,
+ * along with its console will be used directly.  A second PTY
+ * will be used to communicate using MI.
+                                                                               
  * @author LWang                                                                                
  * @since 2.0
  *                                                                                              
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBBackendProcessWithoutIO.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBBackendProcessWithoutIO.java
new file mode 100644
index 00000000000..0345b140954
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBBackendProcessWithoutIO.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson and others
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.service.command;
+
+import java.io.IOException;
+
+import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
+import org.eclipse.cdt.dsf.mi.service.IMIBackend;
+
+/**
+ * Note that starting with GDB 7.12, as long as a PTY is available, this process
+ * is used instead of GDBBackendProcess. This is because the GDB CLI is handled
+ * directly by GDB and the current class only needs to handle the life-cycle of
+ * the GDB process.
+ *
+ * This class is therefore a representation of the GDB process that will be
+ * added to the launch. This class is not the real GDB process but simply an
+ * entry for the launch to handle user actions but no IO.
+ * 
+ * This class extends {@link GDBBackendCLIProcess} to re-use its implementation
+ * of the {@link Process} abstract methods, but disables all I/O and
+ * local CLI handling.
+ * 
+ * @since 5.1
+ */
+public class GDBBackendProcessWithoutIO extends GDBBackendCLIProcess implements IGDBBackendProcessWithoutIO {
+
+	public GDBBackendProcessWithoutIO(ICommandControlService commandControl, IMIBackend backend) throws IOException {
+		super(commandControl, backend);
+	}
+
+	@Override
+	public boolean handleIO() {
+		// Streams are handled directly by the real process.
+		// This class is just representation for the launch, without IO.
+		return false;
+	}
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java
index 51d414b572a..1d751cb7b87 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java
@@ -193,7 +193,7 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
     private IEventProcessor fMIEventProcessor;
     private IEventProcessor fCLICommandProcessor;
     private IEventProcessor fControlEventProcessor;
-    private AbstractCLIProcess fCLIProcess;
+    private Process fBackendProcess;
 
     private GdbCommandTimeoutManager fCommandTimeoutManager;
 
@@ -358,11 +358,24 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
         );
     }
 
+	/**
+	 * @deprecated Replaced by {@link #getGDBBackendProcess()}
+	 */
+	@Deprecated
 	@Override
-    public AbstractCLIProcess getCLIProcess() { 
-        return fCLIProcess; 
+    public AbstractCLIProcess getCLIProcess() {
+		if (fBackendProcess instanceof AbstractCLIProcess) {
+			return (AbstractCLIProcess)fBackendProcess;			
+		}
+		return null;
     }
     
+	/** @since 5.1 */
+	@Override
+    public Process getGDBBackendProcess() {
+		return fBackendProcess;
+    }
+
 	/**
 	 * @since 2.0
 	 */
@@ -546,8 +559,8 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
     
     /** @since 5.1 */
     protected void doCommandProcessorsStep(final RequestMonitor requestMonitor) {
-		try {
-            fCLIProcess = new GDBBackendCLIProcess(GDBControl.this, fMIBackend);
+        try {
+            fBackendProcess = createBackendProcess();
         }
         catch(IOException e) {
             requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Failed to create CLI Process", e)); //$NON-NLS-1$
@@ -567,7 +580,9 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
 		fControlEventProcessor.dispose();
     	fCLICommandProcessor.dispose();
         fMIEventProcessor.dispose();
-        fCLIProcess.dispose();
+        if (fBackendProcess instanceof AbstractCLIProcess) {
+        	((AbstractCLIProcess)fBackendProcess).dispose();
+        }
 
         requestMonitor.done();
 	}
@@ -715,6 +730,18 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
 		return new ControlEventProcessor();
 	}
 
+	/** @since 5.1 */
+	protected Process createBackendProcess() throws IOException {
+	   	if (fMIBackend.isFullGdbConsoleSupported()) {
+	   		// If the full GDB console is supported, which uses the GDB process itself,
+	   		// we return a GDBBackendProcess that does not take care of I/O
+    		return new GDBBackendProcessWithoutIO(this, fMIBackend);
+    	}
+	   	// If the full GDB console is not supported according to the backend service,
+	   	// then we create a special GDBBackendProcess that handles the CLI
+		return new GDBBackendCLIProcess(this, fMIBackend);
+	}
+	
 	/**
 	 * @since 4.1
 	 */
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBBackendProcessWithoutIO.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBBackendProcessWithoutIO.java
new file mode 100644
index 00000000000..147e7a08a23
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBBackendProcessWithoutIO.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse  License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.service.command;
+
+/**
+ * Interface used by a process representing the GDB process but for which there
+ * is no IO.
+ * 
+ * When using the full GDB console, this marker can be used for the class that
+ * will represent the GDB process in the launch since the IO should not be
+ * handled by the launch and the console it normally created, but is handled by
+ * the full GDB console itself.
+ * 
+ * @since 5.1
+ */
+public interface IGDBBackendProcessWithoutIO {
+}
\ No newline at end of file
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBControl.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBControl.java
index 2e149156b78..afbdc782304 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBControl.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBControl.java
@@ -17,11 +17,37 @@ import java.util.List;
 import java.util.Properties;
 
 import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
+import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
 import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
 import org.eclipse.cdt.dsf.mi.service.command.AbstractCLIProcess;
 
 public interface IGDBControl extends IMICommandControl {
 
+	/**
+	 * Returns the process that represents GDB.
+	 * This is the process that should be added to the launch.
+	 * Note that this is usually not be the actual GDB process but
+	 * only one that is used to represent it.
+	 * To get the real GDB process use
+	 * {@link IGDBBackend#getProcess()}.
+	 * 
+	 * @since 5.1
+	 */
+	default Process getGDBBackendProcess() {
+		return getCLIProcess();
+	};
+	
+	/**
+	 * @deprecated The return value of this method was too
+	 *             restrictive.  It has been replaced with
+	 *             {@link #getGDBBackendProcess()}
+	 * @return The AbstractCLIProcess that handles the CLI.
+	 *         Will return null if the CLI is not handled
+	 *         by an AbstractCLIProcess; this will sometimes
+	 *         happen for GDB >= 7.12 if the CLI is handled
+	 *         by the GDB process itself.
+	 */
+	@Deprecated
 	AbstractCLIProcess getCLIProcess();
 
 	/**
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/extensions/GDBBackend_HEAD.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/extensions/GDBBackend_HEAD.java
index dbf43752405..75353aafa65 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/extensions/GDBBackend_HEAD.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/extensions/GDBBackend_HEAD.java
@@ -7,7 +7,7 @@
  *******************************************************************************/
 package org.eclipse.cdt.dsf.gdb.service.extensions;
 
-import org.eclipse.cdt.dsf.gdb.service.GDBBackend;
+import org.eclipse.cdt.dsf.gdb.service.GDBBackend_7_12;
 import org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory;
 import org.eclipse.cdt.dsf.mi.service.IMIBackend;
 import org.eclipse.cdt.dsf.service.DsfSession;
@@ -37,13 +37,13 @@ import org.eclipse.debug.core.ILaunchConfiguration;
  * 
  * @since 4.8
  */
-public class GDBBackend_HEAD extends GDBBackend {
+public class GDBBackend_HEAD extends GDBBackend_7_12 {
 	public GDBBackend_HEAD(DsfSession session, ILaunchConfiguration lc) {
 		super(session, lc);
 		validateGdbVersion(session);
 	}
 	
-	protected String getMinGDBVersionSupported() { return GdbDebugServicesFactory.GDB_7_1_VERSION; }
+	protected String getMinGDBVersionSupported() { return GdbDebugServicesFactory.GDB_7_12_VERSION; }
 	
 	protected void validateGdbVersion(DsfSession session) {
 		GdbDebugServicesFactory.validateGdbVersion(session, getMinGDBVersionSupported(), this);
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/AbstractCLIProcess.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/AbstractCLIProcess.java
index eabfcfbac51..adbb1a494f0 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/AbstractCLIProcess.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/AbstractCLIProcess.java
@@ -46,9 +46,14 @@ import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 
 /**
- * This Process implementation tracks the process the GDB process.  This 
- * process object is displayed in Debug view and is used to
- * accept CLI commands and to write their output to the console.   
+ * This Process implementation tracks the GDB process.  This 
+ * process object is displayed in the Debug view and is used to
+ * accept CLI commands and to write their output to the console.
+ * 
+ * Starting with GDB 7.12, as long as a PTY is available,
+ * this process is no longer used.  Instead, the real GDB process,
+ * along with its console will be used directly.  A second PTY
+ * will be used to communicate using MI.
  * 
  * @see org.eclipse.debug.core.model.IProcess 
  */
@@ -64,7 +69,7 @@ public abstract class AbstractCLIProcess extends Process
 
     private final DsfSession fSession;
     private final ICommandControlService fCommandControl;
-	private final OutputStream fOutputStream = new CLIOutputStream();
+	private OutputStream fOutputStream;
     
     // Client process console stream.
     private PipedInputStream fMIInConsolePipe;
@@ -103,34 +108,42 @@ public abstract class AbstractCLIProcess extends Process
         fSession = commandControl.getSession();
         fCommandControl = commandControl;
         
-        commandControl.addEventListener(this);
-        commandControl.addCommandListener(this);
+        if (handleIO()) {
+        	fOutputStream = new CLIOutputStream();
 
-        PipedInputStream miInConsolePipe = null;
-        PipedOutputStream miOutConsolePipe = null;
-        PipedInputStream miInLogPipe = null;
-        PipedOutputStream miOutLogPipe = null;
-        
-        try {
-        	// Using a LargePipedInputStream see https://bugs.eclipse.org/bugs/show_bug.cgi?id=223154
-            miOutConsolePipe = new PipedOutputStream();
-            miInConsolePipe = new LargePipedInputStream(miOutConsolePipe);
-            miOutLogPipe = new PipedOutputStream();
-            miInLogPipe = new LargePipedInputStream(miOutLogPipe);
-        } catch (IOException e) {
-            ILog log = GdbPlugin.getDefault().getLog();
-            if (log != null) {
-                log.log(new Status(
-                    IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Error when creating log pipes", e)); //$NON-NLS-1$
-            }                   
+        	commandControl.addEventListener(this);
+        	commandControl.addCommandListener(this);
+
+        	PipedInputStream miInConsolePipe = null;
+        	PipedOutputStream miOutConsolePipe = null;
+        	PipedInputStream miInLogPipe = null;
+        	PipedOutputStream miOutLogPipe = null;
+
+        	try {
+        		// Using a LargePipedInputStream see https://bugs.eclipse.org/bugs/show_bug.cgi?id=223154
+        		miOutConsolePipe = new PipedOutputStream();
+        		miInConsolePipe = new LargePipedInputStream(miOutConsolePipe);
+        		miOutLogPipe = new PipedOutputStream();
+        		miInLogPipe = new LargePipedInputStream(miOutLogPipe);
+        	} catch (IOException e) {
+        		ILog log = GdbPlugin.getDefault().getLog();
+        		if (log != null) {
+        			log.log(new Status(
+        					IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Error when creating log pipes", e)); //$NON-NLS-1$
+        		}                   
+        	}
+        	fMIOutConsolePipe = miOutConsolePipe;
+        	fMIInConsolePipe = miInConsolePipe;
+        	fMIOutLogPipe = miOutLogPipe;
+        	fMIInLogPipe = miInLogPipe;
         }
-        // Must initialize these outside of the try block because they are final.
-        fMIOutConsolePipe = miOutConsolePipe;
-        fMIInConsolePipe = miInConsolePipe;
-        fMIOutLogPipe = miOutLogPipe;
-        fMIInLogPipe = miInLogPipe; 
 	}
     
+    /**
+	 * @since 5.1
+	 */
+    protected boolean handleIO() { return true; }
+    
     protected DsfSession getSession() { return fSession; }
 
     /**
@@ -165,18 +178,26 @@ public abstract class AbstractCLIProcess extends Process
     }
     
     private void closeIO() {
-        try {
-            fMIOutConsolePipe.close();
-        } catch (IOException e) {}
-        try {
-            fMIInConsolePipe.close();
-        } catch (IOException e) {}
-        try {
-            fMIOutLogPipe.close();
-        } catch (IOException e) {}
-        try {
-            fMIInLogPipe.close();
-        } catch (IOException e) {}
+    	if (fMIOutConsolePipe != null) {
+    		try {
+    			fMIOutConsolePipe.close();
+    		} catch (IOException e) {}
+    	}
+    	if (fMIInConsolePipe != null) {
+    		try {
+    			fMIInConsolePipe.close();
+    		} catch (IOException e) {}
+    	}
+    	if (fMIOutLogPipe != null) {
+    		try {
+    			fMIOutLogPipe.close();
+    		} catch (IOException e) {}
+    	}
+    	if (fMIInLogPipe != null) {
+    		try {
+    			fMIInLogPipe.close();
+    		} catch (IOException e) {}
+    	}
         
     }
     
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIBackendCLIProcess.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIBackendCLIProcess.java
index a7091a0945f..f2dcb01f69c 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIBackendCLIProcess.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIBackendCLIProcess.java
@@ -37,6 +37,11 @@ import org.eclipse.core.runtime.Status;
 /**
  * CLI Process object implementation which uses the {@link IMIBackend} service
  * to monitor and control the underlying process.
+ *
+ * Note that starting with GDB 7.12, as long as a PTY is available,
+ * this process is no longer used.  Instead, the real GDB process,
+ * along with its console will be used directly.  A second PTY
+ * will be used to communicate using MI.
  * 
  * @since 1.1
  */
diff --git a/releng/org.eclipse.cdt.target/cdt.target b/releng/org.eclipse.cdt.target/cdt.target
index 5d2df286e14..b7e1a52c59a 100644
--- a/releng/org.eclipse.cdt.target/cdt.target
+++ b/releng/org.eclipse.cdt.target/cdt.target
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<?pde version="3.8"?><target name="cdt" sequenceNumber="14">
+<?pde version="3.8"?><target name="cdt" sequenceNumber="15">
 <locations>
 <location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="true" type="InstallableUnit">
 <unit id="org.apache.commons.compress" version="0.0.0"/>
@@ -60,6 +60,7 @@
 </location>
 <location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="true" type="InstallableUnit">
 <unit id="org.eclipse.tm.terminal.control" version="0.0.0"/>
+<unit id="org.eclipse.tm.terminal.view.ui" version="0.0.0"/>
 <repository location="http://download.eclipse.org/tm/terminal/builds/development/nightly/"/>
 </location>
 <location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="true" type="InstallableUnit">