/******************************************************************************* * Copyright (c) 2016 Ericsson AB 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.sync; import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor; import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.cdt.dsf.gdb.internal.service.IGDBFocusSynchronizer; import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext; import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; import org.eclipse.cdt.dsf.service.DsfServicesTracker; import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.contexts.DebugContextEvent; import org.eclipse.debug.ui.contexts.IDebugContextListener; /** * This instance propagates the selection of debug context elements e.g. Thread to the back end GDB */ public class GdbDebugContextSyncManager implements IDebugContextListener { public void startup() { DebugUITools.getDebugContextManager().addDebugContextListener(this); } public void shutdown() { DebugUITools.getDebugContextManager().removeDebugContextListener(this); } @Override public void debugContextChanged(DebugContextEvent event) { // Make sure that it's a change of selection that caused the event if ((event.getFlags() != DebugContextEvent.ACTIVATED)) { return; } // Get selected element in the Debug View IAdaptable context = DebugUITools.getDebugContext(); if (context != null) { final IDMContext dmc = context.getAdapter(IDMContext.class); if (dmc instanceof IMIContainerDMContext || dmc instanceof IMIExecutionDMContext || dmc instanceof IFrameDMContext) { // A process, thread or stack frame was selected. In each case, have GDB switch to the new // corresponding thread, if required. // Resolve the debug session String eventSessionId = dmc.getSessionId(); if (!(DsfSession.isSessionActive(eventSessionId))) { return; } DsfSession session = DsfSession.getSession(eventSessionId); // order GDB to switch thread session.getExecutor().execute(new Runnable() { @Override public void run() { DsfServicesTracker tracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), eventSessionId); IGDBFocusSynchronizer gdbSync = tracker.getService(IGDBFocusSynchronizer.class); tracker.dispose(); if (gdbSync != null) { gdbSync.setFocus(new IDMContext[] {dmc}, new ImmediateRequestMonitor() { @Override protected void handleFailure() { // do not set error - it's normal in some cases to fail to switch thread // for example in a remote session with the inferior running and in all-stop mode } }); } } }); } } } }