入口類 ToggleMethodTracepointAction框架
建立一個FunctionBreakpointeclipse
CDIDebugModel.createFunctionBreakpoint(location, getResource(), function, -1, -1, -1, true, 0, "", true, true, false);
CDIDebugModle中建立。該類時一個debugmodel類,其中大部分是建立方法,在CDT中類型前面以CDI開頭的。都屬於ide
Debug。跟CDT的橋樑類。函數
/** * @param sourceHandle * @param resource * @param function * @param charStart * @param charEnd * @param lineNumber * @param enabled * @param ignoreCount * @param condition * @param register * @param type * @param temporary * @return * @throws CoreException */ public static ICFunctionBreakpoint createFunctionBreakpoint( String sourceHandle, IResource resource, String function, int charStart, int charEnd, int lineNumber, boolean enabled, int ignoreCount, String condition, boolean register, boolean isGlobal, boolean temporary ) throws CoreException { HashMap attributes = new HashMap(10); // attributes.put(IBreakpoint.ID, getPluginIdentifier()); attributes.put(IBreakpoint.ID, getPluginIdentifier()); attributes.put(IMarker.CHAR_START, new Integer(charStart)); attributes.put(IMarker.CHAR_END, new Integer(charEnd)); attributes.put(IMarker.LINE_NUMBER, new Integer(lineNumber)); attributes.put(ICLineBreakpoint.FUNCTION, function); attributes.put(IBreakpoint.ENABLED, Boolean.valueOf(enabled)); attributes.put(ICBreakpoint.IGNORE_COUNT, new Integer(ignoreCount)); attributes.put(ICBreakpoint.CONDITION, condition); attributes.put(ICBreakpoint.SOURCE_HANDLE, sourceHandle); attributes.put(ICBreakpoint.TEMPORARY, new Boolean(temporary)); attributes.put(ICBreakpoint.TEMPORARY, new Boolean(temporary)); attributes.put(ICBreakpoint.TEMPORARY, new Boolean(temporary)); attributes.put(ICFunctionBreakpoint.FUNCTION_BREAKPOINT_ID, getFunctionBreakpointId()); attributes.put(ICBreakpoint.TYPE, isGlobal?ICBreakpoint.GLOBAL_BREAKPOINT:ICBreakpoint.LOCAL_BREAKPOINT); attributes.put(ICBreakpoint.BREAKPOINT_ID, getBreakpointID()); return new CFunctionBreakpoint(resource, attributes, register); }
FunctionBreakpoint就是debug層的斷點對象。其父類爲CBreakpoint對象,在父類的構造函數中中,通知BreakpointManager建立斷點。ui
Class CBreakpoint{ ... public CBreakpoint( final IResource resource, final String markerType, final Map attributes, final boolean add ) throws CoreException { this(); IWorkspaceRunnable wr = new IWorkspaceRunnable() { public void run( IProgressMonitor monitor ) throws CoreException { // create the marker setMarker( resource.createMarker( markerType ) ); // set attributes ensureMarker().setAttributes( attributes ); //set the marker message setAttribute( IMarker.MESSAGE, getMarkerMessage() ); // add to breakpoint manager if requested register( add ); } }; run( wr ); } ** * Add this breakpoint to the breakpoint manager, or sets it as * unregistered. */ public void register( boolean register ) throws CoreException { if ( register ) { DebugPlugin.getDefault().getBreakpointManager().addBreakpoint( this ); } /* * else { setRegistered( false ); } */ } }
通知CDT層建立this
通知spa
private void fireUpdate(List breakpoints, List deltas, int update) { if (breakpoints.isEmpty()) { return; } IBreakpoint[] bpArray = (IBreakpoint[])breakpoints.toArray(new IBreakpoint[breakpoints.size()]); IMarkerDelta[] deltaArray = new IMarkerDelta[bpArray.length]; if (deltas != null) { deltaArray = (IMarkerDelta[])deltas.toArray(deltaArray); } // single listeners getBreakpointNotifier().notify(bpArray, deltaArray, update); // plural listeners getBreakpointsNotifier().notify(bpArray, deltaArray, update); }
全部實現了IBreakpointsListner的類debug
public void notify(IBreakpoint[] breakpoints, IMarkerDelta[] deltas, int update) { fType = update; fNotifierBreakpoints = breakpoints; fDeltas = deltas; Object[] copiedListeners = fBreakpointsListeners.getListeners(); for (int i= 0; i < copiedListeners.length; i++) { fListener = (IBreakpointsListener)copiedListeners[i]; SafeRunner.run(this); } fDeltas = null; fNotifierBreakpoints = null; fListener = null; }
這時候CBreakpointManager這個C層的斷點管理器就收到通知了code
breakpointsAdded 方法最後調用了setBreakpointsOnTarget0。而這個方法就關聯到ICDIFunctionLocation對象
總結一下,其實整個斷點的模型就是一個通知監聽模式,當視圖上建立了一個斷點後,就通知管理器下發建立命令。而實現了斷點監聽的就負責建立。這時候cdt層CBreakpointManager首先了該監聽。開始建立。固然還能夠有其它的模型。這個能夠看下debug的源碼。 管理器中 setBreakpointsOnTarget0 。調用了ICDIBreakpointManagement2。建立斷點。這裏就調用了cdt層的Target目標機。而後繼續向cdt下發。最後發送命令。
整個eclipse 源碼都大量採用了這種模型框架。所以搞清楚這個原理。看源代碼就好理解的多了
如今看下讓斷點視圖上顯示跟蹤點的id。開始改造
CBreakpointManager類中的 setBreakpointsOnTarget0 這個方法差很少就是ui 跟cdt的建立斷點的紐帶。
咱們如今須要的是cdt層的斷點下發建立斷點命令後,返回的跟蹤點id。在ui層展現。所以在ui層咱們須要CFunctionBreakpoint類來給我跟蹤點的id
所以ICFunctionBreakpoint接口中咱們建立跟蹤點的參數跟方法
public interface ICFunctionBreakpoint extends ICLineBreakpoint { /** * 斷點返回的跟蹤點的信息 * wangmin */ public static final String FUNCTION_TRACEPOINT_ID="org.eclipse.cdt.debug.core.funcTracepointId";
/***
*
* 跟蹤點的id
* @param symbolFile
* @throws CoreException
*/
public void setNumber( String number ) throws CoreException;
public String getNumber( String number ) throws CoreException;
}
CFunctionBreakpoint中實現接口。採用IMarker的形式保存參數
@Override public void setNumber(int number) throws CoreException { // TODO 自動生成的方法存根 setAttribute(ICFunctionBreakpoint.FUNCTION_TRACEPOINT_ID, number); } @Override public int getNumber(int number) throws CoreException { // TODO 自動生成的方法存根 return getMarker().getAttribute(ICFunctionBreakpoint.FUNCTION_TRACEPOINT_ID, 0); }
好了。。如今就須要讓cdt層的斷電來告訴最後的跟蹤點id。
繼續看CBreakpointManager 找到 doHandleLocationBreakpointCreatedEvent 這是一個 事件通知 。。嗯。cdt源碼還有很重要的一種事件通知框架模型。這個之後說
這裏只須要知道cdt建立完成以後這個方法就會被觸發。這裏咱們就獲取到了cdt建立完成後的 ICDILocationBreakpoint接口 so。就能夠將ui層以前定義的跟蹤點。設置進來了。
哦。cdt層也要改造。讓它攜帶跟蹤點id。首先時 ICDIBreakpoint接口 定義
/*** * * * @return */ public int getNumber() ;
而後是其子類。:AddressBreakpoint,FunctionBreakpoint,LineBreakpoint
在其抽象父類實現LocationBreakpoint MIBreakpoint miBreakpoints 這個就是命令下發後返回的解析後的信息類
public int getNumber() { if (miBreakpoints != null && miBreakpoints.length > 0) { return miBreakpoints[0].getNumber(); } return 0; }
最後在doHandleLocationBreakpointCreatedEvent 方法中對接
synchronized private void doHandleLocationBreakpointCreatedEvent( ICDILocationBreakpoint cdiBreakpoint ) { ... if (breakpoint instanceof ICFunctionBreakpoint && ((ICFunctionBreakpoint) breakpoint).getCharStart() == -1 && ((ICFunctionBreakpoint) breakpoint).getCharEnd() == -1) { ICFunctionBreakpoint bp = (ICFunctionBreakpoint)cTopMap.get(breakpoint); bp.setNumber(cdiBreakpoint.getNumber()); ... } }
ok..這樣就能夠獲取了number了
org.eclipse.cdt.debug.internal.ui 包下
CBreakpointActionsPage類
//顯示number