diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/breakpoints/GdbBreakpointVMProvider.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/breakpoints/GdbBreakpointVMProvider.java index b6b20dc5618..734a9b32c31 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/breakpoints/GdbBreakpointVMProvider.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/breakpoints/GdbBreakpointVMProvider.java @@ -14,18 +14,22 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.RejectedExecutionException; -import org.eclipse.cdt.debug.core.CDebugCorePlugin; -import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DsfRunnable; import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor; import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.debug.service.IBreakpoints; +import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext; +import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; import org.eclipse.cdt.dsf.debug.service.IBreakpointsExtension; import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints.BreakpointVMProvider; import org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints.RawBreakpointVMNode; import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; +import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; +import org.eclipse.cdt.dsf.mi.service.MIBreakpointDMData; import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager; import org.eclipse.cdt.dsf.service.DsfServicesTracker; import org.eclipse.cdt.dsf.service.DsfSession; @@ -34,12 +38,15 @@ import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode; import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.DebugUITools; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; /** * @since 3.0 @@ -63,20 +70,35 @@ public class GdbBreakpointVMProvider extends BreakpointVMProvider { } @Override - protected void calcFileteredBreakpoints(DataRequestMonitor rm) { - if (Boolean.TRUE.equals(getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION))) { - IBreakpoint[] allBreakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(); - List filteredBPs = new ArrayList(allBreakpoints.length); - for (IBreakpoint bp : allBreakpoints) { - if (bp instanceof ICBreakpoint && bp.getModelIdentifier().equals(CDebugCorePlugin.PLUGIN_ID)) { - filteredBPs.add(bp); - } - } - rm.setData( filteredBPs.toArray(new IBreakpoint[filteredBPs.size()]) ); - rm.done(); - } else { - super.calcFileteredBreakpoints(rm); - } + protected void calcFileteredBreakpoints( final DataRequestMonitor rm ) { + if ( Boolean.TRUE.equals( getPresentationContext().getProperty( IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION ) ) ) { + IBreakpointsTargetDMContext bpContext = null; + IMIExecutionDMContext threadContext = null; + ISelection debugContext = getDebugContext(); + if ( debugContext instanceof IStructuredSelection ) { + Object element = ((IStructuredSelection)debugContext).getFirstElement(); + if ( element instanceof IDMVMContext ) { + bpContext = DMContexts.getAncestorOfType( ((IDMVMContext)element).getDMContext(), IBreakpointsTargetDMContext.class ); + threadContext = DMContexts.getAncestorOfType( ((IDMVMContext)element).getDMContext(), IMIExecutionDMContext.class ); + } + } + + if ( bpContext == null || !fSession.getId().equals( bpContext.getSessionId() ) ) { + rm.setStatus( new Status( + IStatus.ERROR, + GdbUIPlugin.PLUGIN_ID, + IDsfStatusConstants.INVALID_HANDLE, + "Debug context doesn't contain a thread", //$NON-NLS-1$ + null ) ); + rm.done(); + return; + } + + getInstalledBreakpoints( bpContext, threadContext, rm ); + } + else { + super.calcFileteredBreakpoints( rm ); + } } @Override @@ -146,4 +168,118 @@ public class GdbBreakpointVMProvider extends BreakpointVMProvider { rm.done(); } } + + private ISelection getDebugContext() { + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if ( window != null ) { + return DebugUITools.getDebugContextManager().getContextService( window ).getActiveContext(); + } + return StructuredSelection.EMPTY; + } + + void getInstalledBreakpoints( final IBreakpointsTargetDMContext targetContext, final IMIExecutionDMContext threadContext, final DataRequestMonitor rm ) { + + try { + fSession.getExecutor().execute( new DsfRunnable() { + public void run() { + final IBreakpointsExtension bpService = fServicesTracker.getService( IBreakpointsExtension.class ); + if ( bpService == null ) { + rm.setStatus( new Status( + IStatus.ERROR, + GdbUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, + "Breakpoints service not available", //$NON-NLS-1$ + null ) ); + rm.done(); + return; + } + bpService.getBreakpoints( targetContext, new DataRequestMonitor( fSession.getExecutor(), rm ) { + + @Override + protected void handleSuccess() { + final MIBreakpointsManager bpManager = fServicesTracker.getService( MIBreakpointsManager.class ); + if ( bpManager == null ) { + rm.setStatus( new Status( + IStatus.ERROR, + GdbUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, + "Breakpoints service not available", //$NON-NLS-1$ + null ) ); + rm.done(); + return; + } + + if ( getData().length > 0 ) { + final List bps = new ArrayList( getData().length ); + final CountingRequestMonitor crm = new CountingRequestMonitor( ImmediateExecutor.getInstance(), rm ) { + + @Override + protected void handleSuccess() { + rm.setData( bps.toArray( new IBreakpoint[bps.size()] ) ); + rm.done(); + } + }; + crm.setDoneCount( getData().length ); + + for ( final IBreakpointDMContext bpCtx : getData() ) { + bpService.getBreakpointDMData( + bpCtx, + new DataRequestMonitor( ImmediateExecutor.getInstance(), crm ) { + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.RequestMonitor#handleSuccess() + */ + @Override + protected void handleSuccess() { + if ( getData() instanceof MIBreakpointDMData ) { + MIBreakpointDMData data = (MIBreakpointDMData)getData(); + if ( !data.isPending() && isThreadBreakpoint( threadContext, data )) { + IBreakpoint bp = bpManager.findPlatformBreakpoint( bpCtx ); + if ( bp != null ) + bps.add( bp ); + } + crm.done(); + } + } + } ); + } + } + else { + rm.setData( new IBreakpoint[0] ); + rm.done(); + } + } + } ); + } + } ); + } + catch( RejectedExecutionException e ) { + rm.setStatus( new Status( + IStatus.ERROR, + GdbUIPlugin.PLUGIN_ID, + IDsfStatusConstants.INVALID_STATE, + "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", e ) ); //$NON-NLS-1$ //$NON-NLS-2$); + rm.done(); + } + } + + private boolean isThreadBreakpoint( IMIExecutionDMContext threadContext, MIBreakpointDMData data ) { + if ( threadContext == null || data.getThreadId() == null || data.getThreadId().length() == 0 ) { + // Ignore threads + return true; + } + + int threadId = threadContext.getThreadId(); + try { + int bpThreadId = Integer.parseInt( data.getThreadId() ); + if ( bpThreadId == 0 ) + return true; + return ( threadId == bpThreadId ); + } + catch( NumberFormatException e ) { + GdbUIPlugin.getDefault().getLog().log( new Status( + IStatus.ERROR, + GdbUIPlugin.getUniqueIdentifier(), + "Invalid breakpoint thread id" ) ); //$NON-NLS-1$ + } + return true; + } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java index 010b5d70bcc..65b26f7d2c0 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java @@ -1408,7 +1408,12 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo */ public IBreakpoint findPlatformBreakpoint(IBreakpointDMContext bpContext) { if (bpContext instanceof MIBreakpointDMContext) { - return findPlatformBreakpoint(((MIBreakpointDMContext)bpContext).getReference()); + IBreakpointsTargetDMContext targetCtx = DMContexts.getAncestorOfType(bpContext, IBreakpointsTargetDMContext.class); + if (targetCtx != null) { + Map bps = fTargetBPs.get(targetCtx); + if (bps != null) + return bps.get(bpContext); + } } return null; }