cdt/cdt_6_0_x/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpoints.java
changeset 117 09f3d307f081
parent 37 c2bce6dd59e7
child 122 d94b9ba55bed
equal deleted inserted replaced
116:05ea843f7d56 117:09f3d307f081
    13 
    13 
    14 import java.util.HashMap;
    14 import java.util.HashMap;
    15 import java.util.Hashtable;
    15 import java.util.Hashtable;
    16 import java.util.Map;
    16 import java.util.Map;
    17 
    17 
       
    18 import org.eclipse.cdt.debug.core.CDebugCorePlugin;
       
    19 import org.eclipse.cdt.debug.core.model.ICBreakpoint;
    18 import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
    20 import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
    19 import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
    21 import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
    20 import org.eclipse.cdt.dsf.concurrent.Immutable;
    22 import org.eclipse.cdt.dsf.concurrent.Immutable;
    21 import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
    23 import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
    22 import org.eclipse.cdt.dsf.datamodel.AbstractDMContext;
    24 import org.eclipse.cdt.dsf.datamodel.AbstractDMContext;
    25 import org.eclipse.cdt.dsf.datamodel.IDMContext;
    27 import org.eclipse.cdt.dsf.datamodel.IDMContext;
    26 import org.eclipse.cdt.dsf.debug.service.IBreakpoints;
    28 import org.eclipse.cdt.dsf.debug.service.IBreakpoints;
    27 import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
    29 import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
    28 import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent;
    30 import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent;
    29 import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
    31 import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
       
    32 import org.eclipse.cdt.dsf.mi.service.MIRunControl.SuspendedEvent;
       
    33 import org.eclipse.cdt.dsf.mi.service.breakpoint.actions.BreakpointActionAdapter;
    30 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakAfter;
    34 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakAfter;
    31 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakCondition;
    35 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakCondition;
    32 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakDelete;
    36 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakDelete;
    33 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakDisable;
    37 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakDisable;
    34 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakEnable;
    38 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakEnable;
    35 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakInsert;
    39 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakInsert;
    36 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakList;
    40 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakList;
    37 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakWatch;
    41 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakWatch;
       
    42 import org.eclipse.cdt.dsf.mi.service.command.events.MIBreakpointHitEvent;
    38 import org.eclipse.cdt.dsf.mi.service.command.events.MIWatchpointScopeEvent;
    43 import org.eclipse.cdt.dsf.mi.service.command.events.MIWatchpointScopeEvent;
       
    44 import org.eclipse.cdt.dsf.mi.service.command.events.MIWatchpointTriggerEvent;
    39 import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
    45 import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
    40 import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakListInfo;
    46 import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakListInfo;
    41 import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint;
    47 import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint;
    42 import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
    48 import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
    43 import org.eclipse.cdt.dsf.service.AbstractDsfService;
    49 import org.eclipse.cdt.dsf.service.AbstractDsfService;
    44 import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
    50 import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
    45 import org.eclipse.cdt.dsf.service.DsfSession;
    51 import org.eclipse.cdt.dsf.service.DsfSession;
       
    52 import org.eclipse.core.runtime.CoreException;
       
    53 import org.eclipse.core.runtime.IProgressMonitor;
    46 import org.eclipse.core.runtime.IStatus;
    54 import org.eclipse.core.runtime.IStatus;
    47 import org.eclipse.core.runtime.Status;
    55 import org.eclipse.core.runtime.Status;
       
    56 import org.eclipse.core.runtime.jobs.Job;
    48 import org.osgi.framework.BundleContext;
    57 import org.osgi.framework.BundleContext;
    49 
    58 
    50 /**
    59 /**
    51  * Initial breakpoint service implementation.
    60  * Initial breakpoint service implementation.
    52  * Implements the IBreakpoints interface.
    61  * Implements the IBreakpoints interface.
   279      */
   288      */
   280     @DsfServiceEventHandler
   289     @DsfServiceEventHandler
   281     public void eventDispatched(ICommandControlShutdownDMEvent e) {
   290     public void eventDispatched(ICommandControlShutdownDMEvent e) {
   282     }
   291     }
   283 
   292 
       
   293 	@DsfServiceEventHandler 
       
   294     public void eventDispatched(SuspendedEvent e) {
       
   295 
       
   296 		if (e.getMIEvent() instanceof MIBreakpointHitEvent) {
       
   297 			MIBreakpointHitEvent evt = (MIBreakpointHitEvent) e.getMIEvent();
       
   298 	        performBreakpointAction(evt.getDMContext(), evt.getNumber());
       
   299 	        return;
       
   300 		}
       
   301 
       
   302 		if (e.getMIEvent() instanceof MIWatchpointTriggerEvent) {
       
   303 			MIWatchpointTriggerEvent evt = (MIWatchpointTriggerEvent) e.getMIEvent();
       
   304 	        performBreakpointAction(evt.getDMContext(), evt.getNumber());
       
   305 	        return;
       
   306 		}
       
   307 	}
       
   308 
       
   309     private void performBreakpointAction(final IDMContext context, int number) {
       
   310         // Identify the platform breakpoint
       
   311         final ICBreakpoint breakpoint = findPlatformBreakpoint(context, number);
       
   312 
       
   313         // Perform the actions asynchronously (otherwise we can have a deadlock...)
       
   314         new Job("Breakpoint action") { //$NON-NLS-1$
       
   315             { setSystem(true); }
       
   316             @Override
       
   317             protected IStatus run(IProgressMonitor monitor) {
       
   318             	CDebugCorePlugin.getDefault().getBreakpointActionManager().executeActions(breakpoint, new BreakpointActionAdapter(getExecutor(), getServicesTracker(), context));
       
   319                 return Status.OK_STATUS;
       
   320             };
       
   321         }.schedule();
       
   322     }
       
   323 
       
   324     // Helper function to locate the platform breakpoint corresponding
       
   325     // to the target breakpoint/watchpoint that was just hit
       
   326 
       
   327     // FIXME: (Bug228703) Need a way to identify the correct context where the BP was hit
       
   328     private ICBreakpoint findPlatformBreakpoint(IDMContext context, int targetBreakpointID) {
       
   329     	// Hmm, the service has no tracking of MIBreakpointDMContext. So this workaround.
       
   330     	IBreakpointsTargetDMContext btDMC = DMContexts.getAncestorOfType(context, IBreakpointsTargetDMContext.class);
       
   331     	assert btDMC != null;
       
   332     	IBreakpointDMContext dmc = new MIBreakpointDMContext(MIBreakpoints.this, new IDMContext[] { btDMC }, targetBreakpointID);
       
   333 
       
   334 		MIBreakpointsManager bpMediator = getServicesTracker().getService(MIBreakpointsManager.class);
       
   335 		ICBreakpoint cdtBP = (ICBreakpoint)bpMediator.getPlatformBreakpoint(btDMC, dmc);
       
   336     	
       
   337         return cdtBP;
       
   338     }
       
   339     
   284 	///////////////////////////////////////////////////////////////////////////
   340 	///////////////////////////////////////////////////////////////////////////
   285 	// IBreakpoints interface
   341 	// IBreakpoints interface
   286 	///////////////////////////////////////////////////////////////////////////
   342 	///////////////////////////////////////////////////////////////////////////
   287 
   343 
   288 	//-------------------------------------------------------------------------
   344 	//-------------------------------------------------------------------------
   761 		Map<String, Object> properties = new HashMap<String, Object>(attributes);
   817 		Map<String, Object> properties = new HashMap<String, Object>(attributes);
   762 		
   818 		
   763 		// Retrieve the breakpoint parameters
   819 		// Retrieve the breakpoint parameters
   764 		// At this point, we know their are OK so there is no need to re-validate
   820 		// At this point, we know their are OK so there is no need to re-validate
   765 		MIBreakpointDMContext breakpointCtx = (MIBreakpointDMContext) dmc;
   821 		MIBreakpointDMContext breakpointCtx = (MIBreakpointDMContext) dmc;
   766         IBreakpointsTargetDMContext context = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class);
   822         final IBreakpointsTargetDMContext context = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class);
   767 		final Map<Integer, MIBreakpointDMData> contextBreakpoints = fBreakpoints.get(context);
   823 		final Map<Integer, MIBreakpointDMData> contextBreakpoints = fBreakpoints.get(context);
   768 		final int reference = breakpointCtx.getReference();
   824 		final int reference = breakpointCtx.getReference();
   769 		MIBreakpointDMData breakpoint = contextBreakpoints.get(reference);
   825 		MIBreakpointDMData breakpoint = contextBreakpoints.get(reference);
   770 
   826 
   771 		// Track the number of change requests
   827 		// Track the number of change requests
   780         };
   836         };
   781 
   837 
   782         // Determine if the breakpoint condition changed
   838         // Determine if the breakpoint condition changed
   783 		String conditionAttribute = CONDITION;
   839 		String conditionAttribute = CONDITION;
   784 		if (properties.containsKey(conditionAttribute)) {
   840 		if (properties.containsKey(conditionAttribute)) {
   785 			String oldValue = breakpoint.getCondition();
   841 			final String oldValue = breakpoint.getCondition();
   786 			String newValue = (String) properties.get(conditionAttribute);
   842 			String newValue = (String) properties.get(conditionAttribute);
   787 			if (newValue == null) newValue = NULL_STRING;
   843 			if (newValue == null) newValue = NULL_STRING;
   788 	        if (!oldValue.equals(newValue)) {
   844 	        if (!oldValue.equals(newValue)) {
   789 	        	changeCondition(context, reference, newValue, countingRm);
   845 	        	changeCondition(context, reference, newValue, new RequestMonitor(getExecutor(), countingRm){
       
   846 
       
   847 					@Override
       
   848 					protected void handleError() {
       
   849 						// Failed to change the condition, restore the old condition.
       
   850 						// See comment in changeCondition() for more.
       
   851 						MIBreakpointsManager bpMediator = getServicesTracker().getService(MIBreakpointsManager.class);
       
   852 						final ICBreakpoint cdtBP = (ICBreakpoint)bpMediator.getPlatformBreakpoint(context, dmc);
       
   853 						rollbackCondition(cdtBP, oldValue);
       
   854 
       
   855 						countingRm.done();
       
   856 					}});
   790 	        	numberOfChanges++;
   857 	        	numberOfChanges++;
   791 	        }
   858 	        }
   792 			properties.remove(conditionAttribute);
   859 			properties.remove(conditionAttribute);
   793 		}
   860 		}
   794 
   861 
   821 			properties.remove(enableAttribute);
   888 			properties.remove(enableAttribute);
   822 		}
   889 		}
   823 
   890 
   824 		// Set the number of completions required
   891 		// Set the number of completions required
   825         countingRm.setDoneCount(numberOfChanges);
   892         countingRm.setDoneCount(numberOfChanges);
       
   893 	}
       
   894 
       
   895 	private void rollbackCondition(final ICBreakpoint cdtBP, final String oldValue) {
       
   896 		if (cdtBP == null)
       
   897 			return;
       
   898 		
       
   899 		new Job("rollback breakpont condition") { //$NON-NLS-1$
       
   900 			{ setSystem(true); }
       
   901 			@Override
       
   902 			protected IStatus run(IProgressMonitor monitor) {
       
   903 				try {
       
   904 					if (oldValue != null)
       
   905 						cdtBP.setCondition(oldValue);
       
   906 					else
       
   907 						cdtBP.setCondition(NULL_STRING);
       
   908 				} catch (CoreException e) {
       
   909 					// ignore
       
   910 				}
       
   911 				return Status.OK_STATUS;
       
   912 			}}.schedule(); 
   826 	}
   913 	}
   827 
   914 
   828 	/**
   915 	/**
   829 	 * Update the breakpoint condition
   916 	 * Update the breakpoint condition
   830 	 * 
   917 	 *