| /* |
| *(c) Copyright QNX Software Systems Ltd. 2002. |
| * All Rights Reserved. |
| * |
| */ |
| package org.eclipse.cdt.debug.internal.core.model; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.StringTokenizer; |
| |
| import org.eclipse.cdt.core.CCorePlugin; |
| import org.eclipse.cdt.core.model.CoreModel; |
| import org.eclipse.cdt.core.model.IBinary; |
| import org.eclipse.cdt.core.model.IBinaryModule; |
| import org.eclipse.cdt.core.model.ICElement; |
| import org.eclipse.cdt.core.model.IParent; |
| import org.eclipse.cdt.debug.core.CDebugCorePlugin; |
| import org.eclipse.cdt.debug.core.CDebugModel; |
| import org.eclipse.cdt.debug.core.CDebugUtils; |
| import org.eclipse.cdt.debug.core.ICBreakpointManager; |
| import org.eclipse.cdt.debug.core.ICMemoryManager; |
| import org.eclipse.cdt.debug.core.ICRegisterManager; |
| import org.eclipse.cdt.debug.core.ICSharedLibraryManager; |
| import org.eclipse.cdt.debug.core.ICSignalManager; |
| import org.eclipse.cdt.debug.core.cdi.CDIException; |
| import org.eclipse.cdt.debug.core.cdi.ICDIBreakpointHit; |
| import org.eclipse.cdt.debug.core.cdi.ICDIConfiguration; |
| import org.eclipse.cdt.debug.core.cdi.ICDIEndSteppingRange; |
| import org.eclipse.cdt.debug.core.cdi.ICDIErrorInfo; |
| import org.eclipse.cdt.debug.core.cdi.ICDIExpressionManager; |
| import org.eclipse.cdt.debug.core.cdi.ICDILocation; |
| import org.eclipse.cdt.debug.core.cdi.ICDISessionObject; |
| import org.eclipse.cdt.debug.core.cdi.ICDISharedLibraryEvent; |
| import org.eclipse.cdt.debug.core.cdi.ICDISignalReceived; |
| import org.eclipse.cdt.debug.core.cdi.ICDIWatchpointScope; |
| import org.eclipse.cdt.debug.core.cdi.ICDIWatchpointTrigger; |
| import org.eclipse.cdt.debug.core.cdi.event.ICDIChangedEvent; |
| import org.eclipse.cdt.debug.core.cdi.event.ICDICreatedEvent; |
| import org.eclipse.cdt.debug.core.cdi.event.ICDIDestroyedEvent; |
| import org.eclipse.cdt.debug.core.cdi.event.ICDIDisconnectedEvent; |
| import org.eclipse.cdt.debug.core.cdi.event.ICDIEvent; |
| import org.eclipse.cdt.debug.core.cdi.event.ICDIEventListener; |
| import org.eclipse.cdt.debug.core.cdi.event.ICDIExitedEvent; |
| import org.eclipse.cdt.debug.core.cdi.event.ICDIRestartedEvent; |
| import org.eclipse.cdt.debug.core.cdi.event.ICDIResumedEvent; |
| import org.eclipse.cdt.debug.core.cdi.event.ICDISuspendedEvent; |
| import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpoint; |
| import org.eclipse.cdt.debug.core.cdi.model.ICDIObject; |
| import org.eclipse.cdt.debug.core.cdi.model.ICDISharedLibrary; |
| import org.eclipse.cdt.debug.core.cdi.model.ICDISignal; |
| import org.eclipse.cdt.debug.core.cdi.model.ICDITarget; |
| import org.eclipse.cdt.debug.core.cdi.model.ICDIThread; |
| import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; |
| import org.eclipse.cdt.debug.core.model.ICBreakpoint; |
| import org.eclipse.cdt.debug.core.model.ICDebugElementErrorStatus; |
| import org.eclipse.cdt.debug.core.model.ICDebugTarget; |
| import org.eclipse.cdt.debug.core.model.ICDebugTargetType; |
| import org.eclipse.cdt.debug.core.model.ICExpressionEvaluator; |
| import org.eclipse.cdt.debug.core.model.IDebuggerProcessSupport; |
| import org.eclipse.cdt.debug.core.model.IExecFileInfo; |
| import org.eclipse.cdt.debug.core.model.IGlobalVariable; |
| import org.eclipse.cdt.debug.core.model.IJumpToAddress; |
| import org.eclipse.cdt.debug.core.model.IJumpToLine; |
| import org.eclipse.cdt.debug.core.model.IRunToAddress; |
| import org.eclipse.cdt.debug.core.model.IRunToLine; |
| import org.eclipse.cdt.debug.core.model.IState; |
| import org.eclipse.cdt.debug.core.sourcelookup.ICSourceLocator; |
| import org.eclipse.cdt.debug.core.sourcelookup.ISourceMode; |
| import org.eclipse.cdt.debug.internal.core.CBreakpointManager; |
| import org.eclipse.cdt.debug.internal.core.CMemoryManager; |
| import org.eclipse.cdt.debug.internal.core.CRegisterManager; |
| import org.eclipse.cdt.debug.internal.core.CSharedLibraryManager; |
| import org.eclipse.cdt.debug.internal.core.CSignalManager; |
| import org.eclipse.cdt.debug.internal.core.ICDebugInternalConstants; |
| import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceManager; |
| import org.eclipse.cdt.debug.internal.core.sourcelookup.DisassemblyManager; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IMarkerDelta; |
| import org.eclipse.core.resources.IResourceChangeListener; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.MultiStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.debug.core.DebugEvent; |
| import org.eclipse.debug.core.DebugException; |
| import org.eclipse.debug.core.DebugPlugin; |
| import org.eclipse.debug.core.IBreakpointManager; |
| import org.eclipse.debug.core.IExpressionListener; |
| import org.eclipse.debug.core.IExpressionManager; |
| import org.eclipse.debug.core.ILaunch; |
| import org.eclipse.debug.core.ILaunchListener; |
| import org.eclipse.debug.core.model.IBreakpoint; |
| import org.eclipse.debug.core.model.IDebugTarget; |
| import org.eclipse.debug.core.model.IExpression; |
| import org.eclipse.debug.core.model.IMemoryBlock; |
| import org.eclipse.debug.core.model.IProcess; |
| import org.eclipse.debug.core.model.IRegisterGroup; |
| import org.eclipse.debug.core.model.ISourceLocator; |
| import org.eclipse.debug.core.model.IThread; |
| |
| /** |
| * |
| * Enter type comment. |
| * |
| * @since Aug 1, 2002 |
| */ |
| public class CDebugTarget extends CDebugElement |
| implements ICDebugTarget, |
| ICDIEventListener, |
| ILaunchListener, |
| IExpressionListener |
| { |
| public class RunningInfo |
| { |
| private int fType = 0; |
| private int fStackDepth; |
| |
| public RunningInfo( int type, int stackDepth ) |
| { |
| fType = type; |
| fStackDepth = stackDepth; |
| } |
| |
| public int getType() |
| { |
| return fType; |
| } |
| |
| public int getStackDepth() |
| { |
| return fStackDepth; |
| } |
| } |
| |
| /** |
| * The type of this target. |
| */ |
| private int fTargetType; |
| |
| /** |
| * Threads contained in this debug target. When a thread |
| * starts it is added to the list. When a thread ends it |
| * is removed from the list. |
| */ |
| private ArrayList fThreads; |
| |
| /** |
| * Associated inferrior process, or <code>null</code> if not available. |
| */ |
| private IProcess fDebuggeeProcess = null; |
| |
| /** |
| * Associated debugger process, or <code>null</code> if not available. |
| */ |
| private IProcess fDebuggerProcess = null; |
| |
| /** |
| * The underlying CDI target. |
| */ |
| private ICDITarget fCDITarget; |
| |
| /** |
| * The name of this target. |
| */ |
| private String fName; |
| |
| /** |
| * Whether this target is suspended. |
| */ |
| private boolean fSuspended = true; |
| |
| /** |
| * Whether terminated |
| */ |
| private boolean fTerminated; |
| |
| /** |
| * Whether in the process of terminating |
| */ |
| private boolean fTerminating; |
| |
| /** |
| * Whether disconnected |
| */ |
| private boolean fDisconnected; |
| |
| /** |
| * The launch this target is contained in |
| */ |
| private ILaunch fLaunch; |
| |
| /** |
| * The debug configuration of this session |
| */ |
| private ICDIConfiguration fConfig; |
| |
| /** |
| * The current state identifier. |
| */ |
| private int fCurrentStateId = IState.UNKNOWN; |
| |
| /** |
| * The current state info. |
| */ |
| private Object fCurrentStateInfo = null; |
| |
| /** |
| * Count of the number of suspend events in this target |
| */ |
| private int fSuspendCount = 0; |
| |
| /** |
| * A memory manager for this target. |
| */ |
| private CMemoryManager fMemoryManager; |
| |
| /** |
| * A disassembly manager for this target. |
| */ |
| private DisassemblyManager fDisassemblyManager; |
| |
| /** |
| * A shared library manager for this target. |
| */ |
| private CSharedLibraryManager fSharedLibraryManager; |
| |
| /** |
| * A signal manager for this target. |
| */ |
| private CSignalManager fSignalManager; |
| |
| /** |
| * A register manager for this target. |
| */ |
| private CRegisterManager fRegisterManager; |
| |
| /** |
| * A breakpoint manager for this target. |
| */ |
| private CBreakpointManager fBreakpointManager; |
| |
| /** |
| * Whether the debugger process is default. |
| */ |
| private boolean fIsDebuggerProcessDefault = false; |
| |
| /** |
| * The executable file. |
| */ |
| private IFile fExecFile; |
| |
| private RunningInfo fRunningInfo = null; |
| |
| /** |
| * Constructor for CDebugTarget. |
| * @param target |
| */ |
| public CDebugTarget( ILaunch launch, |
| int targetType, |
| ICDITarget cdiTarget, |
| String name, |
| IProcess debuggeeProcess, |
| IProcess debuggerProcess, |
| IFile file, |
| boolean allowsTerminate, |
| boolean allowsDisconnect ) |
| { |
| super( null ); |
| setLaunch( launch ); |
| setTargetType( targetType ); |
| setDebugTarget( this ); |
| setName( name ); |
| setProcesses( debuggeeProcess, debuggerProcess ); |
| setCDITarget( cdiTarget ); |
| setExecFile( file ); |
| setConfiguration( cdiTarget.getSession().getConfiguration() ); |
| setThreadList( new ArrayList( 5 ) ); |
| setDisassemblyManager( new DisassemblyManager( this ) ); |
| setSharedLibraryManager( new CSharedLibraryManager( this ) ); |
| setSignalManager( new CSignalManager( this ) ); |
| setRegisterManager( new CRegisterManager( this ) ); |
| setBreakpointManager( new CBreakpointManager( this ) ); |
| initialize(); |
| DebugPlugin.getDefault().getLaunchManager().addLaunchListener( this ); |
| DebugPlugin.getDefault().getExpressionManager().addExpressionListener( this ); |
| getCDISession().getEventManager().addEventListener( this ); |
| } |
| |
| /** |
| * Initialize state from the underlying debug session. |
| * |
| */ |
| protected void initialize() |
| { |
| initializeState(); |
| initializeBreakpoints(); |
| initializeRegisters(); |
| initializeMemoryManager(); |
| initializeSourceManager(); |
| getLaunch().addDebugTarget( this ); |
| fireCreationEvent(); |
| } |
| |
| private void initializeBreakpoints() |
| { |
| DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener( this ); |
| setBreakpoints(); |
| } |
| |
| /** |
| * Adds all of the pre-existing threads to this debug target. |
| * |
| */ |
| protected void initializeState() |
| { |
| ICDIThread[] threads = new ICDIThread[0]; |
| try |
| { |
| threads = getCDITarget().getThreads(); |
| } |
| catch( CDIException e ) |
| { |
| // ignore |
| } |
| for ( int i = 0; i < threads.length; ++i ) |
| createThread( threads[i] ); |
| } |
| |
| /** |
| * Installs all C/C++ breakpoints that currently exist in |
| * the breakpoint manager. |
| * |
| */ |
| public void setBreakpoints() |
| { |
| IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager(); |
| IBreakpoint[] bps = manager.getBreakpoints( CDebugModel.getPluginIdentifier() ); |
| for ( int i = 0; i < bps.length; i++ ) |
| { |
| if ( bps[i] instanceof ICBreakpoint && |
| getBreakpointManager().isTargetBreakpoint( (ICBreakpoint)bps[i] ) && |
| !getBreakpointManager().isCDIRegistered( (ICBreakpoint)bps[i] ) ) |
| { |
| if ( bps[i] instanceof ICAddressBreakpoint ) |
| { |
| // disable address breakpoints to prevent the debugger to insert them prematurely |
| try |
| { |
| bps[i].setEnabled( false ); |
| } |
| catch( CoreException e ) |
| { |
| } |
| } |
| breakpointAdded0( bps[i] ); |
| } |
| } |
| } |
| |
| protected void initializeRegisters() |
| { |
| getRegisterManager().initialize(); |
| } |
| |
| protected void initializeMemoryManager() |
| { |
| fMemoryManager = new CMemoryManager( this ); |
| } |
| |
| protected void initializeSourceManager() |
| { |
| ISourceLocator locator = getLaunch().getSourceLocator(); |
| if ( locator instanceof IAdaptable ) |
| { |
| ICSourceLocator clocator = (ICSourceLocator)((IAdaptable)locator).getAdapter( ICSourceLocator.class ); |
| if ( clocator instanceof IAdaptable ) |
| { |
| CSourceManager sm = (CSourceManager)((IAdaptable)clocator).getAdapter( CSourceManager.class ); |
| if ( sm != null ) |
| sm.setDebugTarget( this ); |
| } |
| IResourceChangeListener listener = (IResourceChangeListener)((IAdaptable)locator).getAdapter( IResourceChangeListener.class ); |
| if ( listener != null ) |
| CCorePlugin.getWorkspace().addResourceChangeListener( listener ); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.IDebugTarget#getProcess() |
| */ |
| public IProcess getProcess() |
| { |
| return ( fIsDebuggerProcessDefault ) ? fDebuggerProcess : fDebuggeeProcess; |
| } |
| |
| /** |
| * Sets the process associated with this debug target, |
| * possibly <code>null</code>. Set on creation. |
| * |
| * @param process the system process associated with the |
| * underlying CDI target, or <code>null</code> if no process is |
| * associated with this debug target (for example, a core dump debugging). |
| */ |
| protected void setProcesses( IProcess debuggeeProcess, IProcess debuggerProcess ) |
| { |
| fDebuggeeProcess = debuggeeProcess; |
| fDebuggerProcess = debuggerProcess; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.IDebugTarget#getThreads() |
| */ |
| public IThread[] getThreads() |
| { |
| List threads = getThreadList(); |
| return (IThread[])threads.toArray( new IThread[threads.size()] ); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.IDebugTarget#hasThreads() |
| */ |
| public boolean hasThreads() throws DebugException |
| { |
| return getThreadList().size() > 0; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.IDebugTarget#getName() |
| */ |
| public String getName() throws DebugException |
| { |
| return fName; |
| } |
| |
| /** |
| * Sets the name of this debug target. |
| * |
| * @param name the name of this debug target |
| */ |
| protected void setName( String name ) |
| { |
| fName = name; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.IDebugTarget#supportsBreakpoint(IBreakpoint) |
| */ |
| public boolean supportsBreakpoint( IBreakpoint breakpoint ) |
| { |
| if ( !getConfiguration().supportsBreakpoints() ) |
| return false; |
| return ( breakpoint instanceof ICBreakpoint && getBreakpointManager().isCDIRegistered( (ICBreakpoint)breakpoint ) ); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.ILaunchListener#launchRemoved(ILaunch) |
| */ |
| public void launchRemoved( ILaunch launch ) |
| { |
| if ( !isAvailable() ) |
| { |
| return; |
| } |
| if ( launch.equals( getLaunch() ) ) |
| { |
| // This target has been deregistered, but it hasn't successfully terminated. |
| // Update internal state to reflect that it is disconnected |
| disconnected(); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.ILaunchListener#launchAdded(ILaunch) |
| */ |
| public void launchAdded( ILaunch launch ) |
| { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.ILaunchListener#launchChanged(ILaunch) |
| */ |
| public void launchChanged( ILaunch launch ) |
| { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.ITerminate#canTerminate() |
| */ |
| public boolean canTerminate() |
| { |
| return supportsTerminate() && isAvailable(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.ITerminate#isTerminated() |
| */ |
| public boolean isTerminated() |
| { |
| return fTerminated; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.ITerminate#terminate() |
| */ |
| public void terminate() throws DebugException |
| { |
| try |
| { |
| setTerminating( true ); |
| getCDITarget().terminate(); |
| } |
| catch( CDIException e ) |
| { |
| setTerminating( false ); |
| targetRequestFailed( e.getMessage(), e ); |
| } |
| } |
| |
| /** |
| * Sets whether this debug target is terminated |
| * |
| * @param terminated <code>true</code> if this debug |
| * target is terminated, otherwise <code>false</code> |
| */ |
| protected void setTerminated( boolean terminated ) |
| { |
| fTerminated = terminated; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.ISuspendResume#canResume() |
| */ |
| public boolean canResume() |
| { |
| return getConfiguration().supportsResume() && isSuspended() && isAvailable(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend() |
| */ |
| public boolean canSuspend() |
| { |
| if ( !getConfiguration().supportsSuspend() ) |
| return false; |
| if ( !isSuspended() && isAvailable() ) |
| { |
| // only allow suspend if no threads are currently suspended |
| IThread[] threads = getThreads(); |
| for ( int i = 0; i < threads.length; i++ ) |
| { |
| if ( threads[i].isSuspended() ) |
| { |
| return false; |
| } |
| } |
| return true; |
| } |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended() |
| */ |
| public boolean isSuspended() |
| { |
| return fSuspended; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.ISuspendResume#resume() |
| */ |
| public void resume() throws DebugException |
| { |
| if ( !isSuspended() ) |
| return; |
| try |
| { |
| getCDITarget().resume(); |
| } |
| catch( CDIException e ) |
| { |
| targetRequestFailed( e.getMessage(), e ); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.ISuspendResume#suspend() |
| */ |
| public void suspend() throws DebugException |
| { |
| if ( isSuspended() ) |
| return; |
| try |
| { |
| getCDITarget().suspend(); |
| } |
| catch( CDIException e ) |
| { |
| targetRequestFailed( e.getMessage(), e ); |
| } |
| } |
| |
| /** |
| * Notifies threads that they have been suspended. |
| * |
| */ |
| protected void suspendThreads( ICDISuspendedEvent event ) |
| { |
| Iterator it = getThreadList().iterator(); |
| while( it.hasNext() ) |
| { |
| ((CThread)it.next()).handleDebugEvent( event ); |
| } |
| } |
| |
| /** |
| * Refreshes the thread list. |
| * |
| */ |
| protected synchronized List refreshThreads() |
| { |
| ArrayList list = new ArrayList( 5 ); |
| ArrayList newThreads = new ArrayList( 5 ); |
| try |
| { |
| ICDIThread[] cdiThreads = getCDITarget().getThreads(); |
| for ( int i = 0; i < cdiThreads.length; ++i ) |
| { |
| CThread thread = findThread( cdiThreads[i] ); |
| if ( thread == null ) |
| { |
| thread = new CThread( this, cdiThreads[i] ); |
| newThreads.add( thread ); |
| } |
| else |
| { |
| getThreadList().remove( thread ); |
| } |
| list.add( thread ); |
| } |
| Iterator it = getThreadList().iterator(); |
| while( it.hasNext() ) |
| { |
| ((CThread)it.next()).terminated(); |
| } |
| getThreadList().clear(); |
| setThreadList( list ); |
| it = newThreads.iterator(); |
| while( it.hasNext() ) |
| { |
| ((CThread)it.next()).fireCreationEvent(); |
| } |
| } |
| catch( CDIException e ) |
| { |
| CDebugCorePlugin.log( e ); |
| } |
| setCurrentThread(); |
| return newThreads; |
| } |
| |
| /** |
| * Notifies threads that they have been resumed |
| */ |
| protected void resumeThreads( ICDIResumedEvent event ) |
| { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.IBreakpointListener#breakpointAdded(IBreakpoint) |
| */ |
| public void breakpointAdded( IBreakpoint breakpoint ) |
| { |
| if ( !(breakpoint instanceof ICBreakpoint) || |
| !getBreakpointManager().isTargetBreakpoint( (ICBreakpoint)breakpoint ) || |
| !isAvailable() ) |
| return; |
| breakpointAdded0( breakpoint ); |
| } |
| |
| private void breakpointAdded0( IBreakpoint breakpoint ) |
| { |
| if ( !isAvailable() ) |
| return; |
| if ( breakpoint instanceof ICAddressBreakpoint && !getBreakpointManager().supportsAddressBreakpoint( (ICAddressBreakpoint)breakpoint ) ) |
| return; |
| if ( getConfiguration().supportsBreakpoints() ) |
| { |
| try |
| { |
| getBreakpointManager().setBreakpoint( (ICBreakpoint)breakpoint ); |
| } |
| catch( DebugException e ) |
| { |
| } |
| DebugPlugin.getDefault().getBreakpointManager().fireBreakpointChanged( breakpoint ); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.IBreakpointListener#breakpointRemoved(IBreakpoint, IMarkerDelta) |
| */ |
| public void breakpointRemoved( IBreakpoint breakpoint, IMarkerDelta delta ) |
| { |
| if ( !(breakpoint instanceof ICBreakpoint) || |
| !getBreakpointManager().isTargetBreakpoint( (ICBreakpoint)breakpoint ) || |
| !isAvailable() ) |
| return; |
| try |
| { |
| getBreakpointManager().removeBreakpoint( (ICBreakpoint)breakpoint ); |
| } |
| catch( DebugException e ) |
| { |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.IBreakpointListener#breakpointChanged(IBreakpoint, IMarkerDelta) |
| */ |
| public void breakpointChanged( IBreakpoint breakpoint, IMarkerDelta delta ) |
| { |
| if ( !(breakpoint instanceof ICBreakpoint) || |
| !getBreakpointManager().isTargetBreakpoint( (ICBreakpoint)breakpoint ) || |
| !isAvailable() || |
| delta == null ) |
| return; |
| try |
| { |
| getBreakpointManager().changeBreakpointProperties( (ICBreakpoint)breakpoint, delta ); |
| } |
| catch( DebugException e ) |
| { |
| } |
| } |
| |
| /** |
| * Returns whether this debug target supports disconnecting. |
| * |
| * @return whether this debug target supports disconnecting |
| */ |
| protected boolean supportsDisconnect() |
| { |
| return getConfiguration().supportsDisconnect(); |
| } |
| |
| /** |
| * Returns whether this debug target supports termination. |
| * |
| * @return whether this debug target supports termination |
| */ |
| protected boolean supportsTerminate() |
| { |
| return getConfiguration().supportsTerminate(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.IDisconnect#canDisconnect() |
| */ |
| public boolean canDisconnect() |
| { |
| return supportsDisconnect() && isAvailable(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.IDisconnect#disconnect() |
| */ |
| public void disconnect() throws DebugException |
| { |
| if ( isDisconnected() ) |
| { |
| // already done |
| return; |
| } |
| |
| if ( !canDisconnect() ) |
| { |
| notSupported( "Session does not support \'disconnect\'" ); |
| } |
| |
| try |
| { |
| getCDITarget().disconnect(); |
| } |
| catch( CDIException e ) |
| { |
| targetRequestFailed( e.getMessage(), e ); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.IDisconnect#isDisconnected() |
| */ |
| public boolean isDisconnected() |
| { |
| return fDisconnected; |
| } |
| |
| /** |
| * Sets whether this debug target is disconnected |
| * |
| * @param disconnected <code>true</code> if this debug |
| * target is disconnected, otherwise <code>false</code> |
| */ |
| protected void setDisconnected( boolean disconnected ) |
| { |
| fDisconnected = disconnected; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#supportsStorageRetrieval() |
| */ |
| public boolean supportsStorageRetrieval() |
| { |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#getMemoryBlock(long, long) |
| */ |
| public IMemoryBlock getMemoryBlock( long startAddress, long length ) throws DebugException |
| { |
| return null; |
| } |
| |
| /** |
| * @see org.eclipse.debug.core.model.IDebugElement#getLaunch() |
| */ |
| public ILaunch getLaunch() |
| { |
| return fLaunch; |
| } |
| |
| /** |
| * Sets the launch this target is contained in |
| * |
| * @param launch the launch this target is contained in |
| */ |
| private void setLaunch( ILaunch launch ) |
| { |
| fLaunch = launch; |
| } |
| |
| /** |
| * Returns the list of threads contained in this debug target. |
| * |
| * @return list of threads |
| */ |
| protected ArrayList getThreadList() |
| { |
| return fThreads; |
| } |
| |
| /** |
| * Sets the list of threads contained in this debug target. |
| * Set to an empty collection on creation. Threads are |
| * added and removed as they start and end. On termination |
| * this collection is set to the immutable singleton empty list. |
| * |
| * @param threads empty list |
| */ |
| private void setThreadList( ArrayList threads ) |
| { |
| fThreads = threads; |
| } |
| |
| private void setCDITarget( ICDITarget cdiTarget ) |
| { |
| fCDITarget = cdiTarget; |
| } |
| |
| /* (non-Javadoc) |
| * @see IAdaptable#getAdapter(Class) |
| */ |
| public Object getAdapter( Class adapter ) |
| { |
| if ( adapter.equals( IDebugTarget.class ) ) |
| return this; |
| if ( adapter.equals( CDebugTarget.class ) ) |
| return this; |
| if ( adapter.equals( ICDITarget.class ) ) |
| return fCDITarget; |
| if ( adapter.equals( IState.class ) ) |
| return this; |
| if ( adapter.equals( ICExpressionEvaluator.class ) ) |
| return this; |
| if ( adapter.equals( ICDebugTargetType.class ) ) |
| return this; |
| if ( adapter.equals( ISourceMode.class ) ) |
| { |
| if ( getSourceLocator() instanceof IAdaptable ) |
| { |
| return ((IAdaptable)getSourceLocator()).getAdapter( ISourceMode.class ); |
| } |
| } |
| if ( adapter.equals( ICMemoryManager.class ) ) |
| return getMemoryManager(); |
| if ( adapter.equals( IDebuggerProcessSupport.class ) ) |
| return this; |
| if ( adapter.equals( IExecFileInfo.class ) ) |
| return this; |
| if ( adapter.equals( IRunToLine.class ) ) |
| return this; |
| if ( adapter.equals( IRunToAddress.class ) ) |
| return this; |
| if ( adapter.equals( IJumpToLine.class ) ) |
| return this; |
| if ( adapter.equals( IJumpToAddress.class ) ) |
| return this; |
| if ( adapter.equals( ICBreakpointManager.class ) ) |
| return getBreakpointManager(); |
| if ( adapter.equals( DisassemblyManager.class ) ) |
| return getDisassemblyManager(); |
| if ( adapter.equals( ICSharedLibraryManager.class ) ) |
| return getSharedLibraryManager(); |
| if ( adapter.equals( ICSignalManager.class ) ) |
| return getSignalManager(); |
| if ( adapter.equals( ICRegisterManager.class ) ) |
| return getRegisterManager(); |
| return super.getAdapter( adapter ); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.cdi.event.ICDIEventListener#handleDebugEvent(ICDIEvent) |
| */ |
| public void handleDebugEvent( ICDIEvent event ) |
| { |
| ICDIObject source = event.getSource(); |
| if ( source == null && event instanceof ICDIDestroyedEvent ) |
| { |
| handleTerminatedEvent( (ICDIDestroyedEvent)event ); |
| } |
| else if ( source.getTarget().equals( getCDITarget() ) ) |
| { |
| if ( event instanceof ICDICreatedEvent ) |
| { |
| if ( source instanceof ICDIThread ) |
| { |
| handleThreadCreatedEvent( (ICDICreatedEvent)event ); |
| } |
| if ( source instanceof ICDISharedLibrary ) |
| { |
| getSharedLibraryManager().sharedLibraryLoaded( (ICDISharedLibrary)source ); |
| } |
| } |
| else if ( event instanceof ICDISuspendedEvent ) |
| { |
| if ( source instanceof ICDITarget || source instanceof ICDIThread ) |
| { |
| handleSuspendedEvent( (ICDISuspendedEvent)event ); |
| } |
| } |
| else if ( event instanceof ICDIResumedEvent ) |
| { |
| if ( source instanceof ICDITarget ) |
| { |
| handleResumedEvent( (ICDIResumedEvent)event ); |
| } |
| } |
| else if ( event instanceof ICDIExitedEvent ) |
| { |
| if ( source instanceof ICDITarget ) |
| { |
| handleExitedEvent( (ICDIExitedEvent)event ); |
| } |
| } |
| else if ( event instanceof ICDIDestroyedEvent ) |
| { |
| if ( source instanceof ICDIThread ) |
| { |
| handleThreadTerminatedEvent( (ICDIDestroyedEvent)event ); |
| } |
| if ( source instanceof ICDISharedLibrary ) |
| { |
| getSharedLibraryManager().sharedLibraryUnloaded( (ICDISharedLibrary)source ); |
| } |
| } |
| else if ( event instanceof ICDIDisconnectedEvent ) |
| { |
| if ( source instanceof ICDITarget ) |
| { |
| handleDisconnectedEvent( (ICDIDisconnectedEvent)event ); |
| } |
| } |
| else if ( event instanceof ICDIChangedEvent ) |
| { |
| if ( source instanceof ICDITarget ) |
| { |
| handleChangedEvent( (ICDIChangedEvent)event ); |
| } |
| if ( source instanceof ICDISharedLibrary ) |
| { |
| getSharedLibraryManager().symbolsLoaded( (ICDISharedLibrary)source ); |
| } |
| if ( source instanceof ICDISignal ) |
| { |
| getSignalManager().signalChanged( (ICDISignal)source ); |
| } |
| } |
| else if ( event instanceof ICDIRestartedEvent ) |
| { |
| if ( source instanceof ICDITarget ) |
| { |
| handleRestartedEvent( (ICDIRestartedEvent)event ); |
| } |
| } |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.IRestart#canRestart() |
| */ |
| public boolean canRestart() |
| { |
| return getConfiguration().supportsRestart() && isSuspended() && isAvailable(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.IRestart#restart() |
| */ |
| public void restart() throws DebugException |
| { |
| if ( !canRestart() ) |
| { |
| return; |
| } |
| |
| try |
| { |
| ICDILocation location = getCDISession().getBreakpointManager().createLocation( "", "main", 0 ); |
| setInternalTemporaryBreakpoint( location ); |
| getCDITarget().restart(); |
| restarted(); |
| } |
| catch( CDIException e ) |
| { |
| targetRequestFailed( e.getMessage(), e ); |
| } |
| } |
| |
| /** |
| * Updates the state of this target for restarting. |
| * |
| */ |
| protected void restarted() |
| { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.IFormattedMemoryRetrieval#getSupportedFormats() |
| */ |
| public int[] getSupportedFormats() throws DebugException |
| { |
| return null; |
| } |
| |
| /** |
| * Returns whether this target is available to handle client |
| * requests. |
| * |
| * @return whether this target is available to handle client requests |
| */ |
| public boolean isAvailable() |
| { |
| return !( isTerminated() || isTerminating() || isDisconnected() ); |
| } |
| |
| /** |
| * Sets whether this target is suspended. |
| * |
| * @param suspended whether this target is suspended |
| */ |
| private void setSuspended( boolean suspended ) |
| { |
| fSuspended = suspended; |
| } |
| |
| /** |
| * Returns whether this target is in the process of terminating. |
| * |
| * @return whether this target is terminating |
| */ |
| protected boolean isTerminating() |
| { |
| return fTerminating; |
| } |
| |
| /** |
| * Sets whether this target is in the process of terminating. |
| * |
| * @param terminating whether this target is terminating |
| */ |
| protected void setTerminating( boolean terminating ) |
| { |
| fTerminating = terminating; |
| } |
| |
| /** |
| * Updates the state of this target to be terminated, |
| * if not already terminated. |
| */ |
| protected void terminated() |
| { |
| setTerminating( false ); |
| if ( !isTerminated() ) |
| { |
| if ( !isDisconnected() ) |
| { |
| setTerminated( true ); |
| } |
| cleanup(); |
| fireTerminateEvent(); |
| } |
| } |
| |
| /** |
| * Updates the state of this target for disconnection. |
| * |
| */ |
| protected void disconnected() |
| { |
| if ( !isDisconnected() ) |
| { |
| setDisconnected( true ); |
| cleanup(); |
| fireTerminateEvent(); |
| } |
| } |
| |
| /** |
| * Cleans up the internal state of this debug target as a result |
| * of a session ending. |
| * |
| */ |
| protected void cleanup() |
| { |
| resetStatus(); |
| removeAllThreads(); |
| getCDISession().getEventManager().removeEventListener( this ); |
| DebugPlugin.getDefault().getBreakpointManager().removeBreakpointListener( this ); |
| DebugPlugin.getDefault().getExpressionManager().removeExpressionListener( this ); |
| DebugPlugin.getDefault().getLaunchManager().removeLaunchListener( this ); |
| disposeMemoryManager(); |
| disposeSharedLibraryManager(); |
| disposeSignalManager(); |
| disposeRegisterManager(); |
| disposeDisassemblyManager(); |
| disposeSourceManager(); |
| disposeBreakpointManager(); |
| removeAllExpressions(); |
| } |
| |
| /** |
| * Removes all threads from this target's collection |
| * of threads, firing a terminate event for each. |
| * |
| */ |
| protected void removeAllThreads() |
| { |
| Iterator itr = getThreadList().iterator(); |
| setThreadList( new ArrayList( 0 ) ); |
| while( itr.hasNext() ) |
| { |
| CThread thread = (CThread)itr.next(); |
| thread.terminated(); |
| } |
| } |
| |
| /** |
| * Removes all expressions from this target. |
| * |
| */ |
| protected void removeAllExpressions() |
| { |
| IExpressionManager em = DebugPlugin.getDefault().getExpressionManager(); |
| IExpression[] expressions = em.getExpressions(); |
| for ( int i = 0; i < expressions.length; ++i ) |
| { |
| if ( expressions[i] instanceof CExpression && expressions[i].getDebugTarget().equals( this ) ) |
| { |
| em.removeExpression( expressions[i] ); |
| } |
| } |
| } |
| |
| /** |
| * Creates, adds and returns a thread for the given underlying |
| * CDI thread. A creation event is fired for the thread. |
| * Returns <code>null</code> if during the creation of the thread |
| * this target is set to the disconnected state. |
| * |
| * @param thread the underlying CDI thread |
| * @return model thread |
| */ |
| protected CThread createThread( ICDIThread cdiThread ) |
| { |
| CThread thread = new CThread( this, cdiThread ); |
| getThreadList().add( thread ); |
| thread.fireCreationEvent(); |
| return thread; |
| } |
| |
| /** |
| * Creates a new thread from the given CDI thread and initializes |
| * its state to "Running". |
| * |
| * @see CDebugTarget#createThread(ICDIThread) |
| */ |
| protected CThread createRunningThread( ICDIThread cdiThread ) |
| { |
| CThread thread = new CThread( this, cdiThread ); |
| thread.setRunning( true ); |
| getThreadList().add( thread ); |
| thread.fireCreationEvent(); |
| return thread; |
| } |
| |
| private void handleSuspendedEvent( ICDISuspendedEvent event ) |
| { |
| setSuspended( true ); |
| setCurrentStateId( IState.SUSPENDED ); |
| ICDISessionObject reason = event.getReason(); |
| setCurrentStateInfo( reason ); |
| setRunningInfo( null ); |
| List newThreads = refreshThreads(); |
| if ( event.getSource() instanceof ICDITarget ) |
| { |
| suspendThreads( event ); |
| fireSuspendEvent( DebugEvent.UNSPECIFIED ); |
| } |
| // We need this for debuggers that don't have notifications |
| // for newly created threads. |
| else if ( event.getSource() instanceof ICDIThread ) |
| { |
| CThread thread = findThread( (ICDIThread)event.getSource() ); |
| if ( thread != null && newThreads.contains( thread ) ) |
| { |
| thread.handleDebugEvent( event ); |
| } |
| } |
| if ( reason instanceof ICDIEndSteppingRange ) |
| { |
| handleEndSteppingRange( (ICDIEndSteppingRange)reason ); |
| } |
| else if ( reason instanceof ICDIBreakpointHit ) |
| { |
| handleBreakpointHit( (ICDIBreakpointHit)reason ); |
| } |
| else if ( reason instanceof ICDISignalReceived ) |
| { |
| handleSuspendedBySignal( (ICDISignalReceived)reason ); |
| } |
| else if ( reason instanceof ICDIWatchpointTrigger ) |
| { |
| handleWatchpointTrigger( (ICDIWatchpointTrigger)reason ); |
| } |
| else if ( reason instanceof ICDIWatchpointScope ) |
| { |
| handleWatchpointScope( (ICDIWatchpointScope)reason ); |
| } |
| else if ( reason instanceof ICDIErrorInfo ) |
| { |
| handleErrorInfo( (ICDIErrorInfo)reason ); |
| } |
| else if ( reason instanceof ICDISharedLibraryEvent ) |
| { |
| handleSuspendedBySolibEvent( (ICDISharedLibraryEvent)reason ); |
| } |
| |
| } |
| /* |
| private boolean handleInternalSuspendedEvent( ICDISuspendedEvent event ) |
| { |
| setRetryBreakpoints( true ); |
| setBreakpoints(); |
| RunningInfo info = getRunningInfo(); |
| if ( info != null ) |
| { |
| switch( info.getType() ) |
| { |
| case ICDIResumedEvent.CONTINUE: |
| return internalResume(); |
| case ICDIResumedEvent.STEP_INTO: |
| return internalStepInto( info.getStackDepth() ); |
| case ICDIResumedEvent.STEP_OVER: |
| return internalStepOver( info.getStackDepth() ); |
| case ICDIResumedEvent.STEP_RETURN: |
| return internalStepReturn( info.getStackDepth() ); |
| } |
| } |
| return internalResume(); |
| } |
| |
| private boolean internalResume() |
| { |
| boolean result = false; |
| try |
| { |
| getCDITarget().resume(); |
| } |
| catch( CDIException e ) |
| { |
| result = true; |
| } |
| return result; |
| } |
| |
| private boolean internalStepInto( int oldDepth ) |
| { |
| return internalStepOver( oldDepth ); |
| } |
| |
| private boolean internalStepOver( int oldDepth ) |
| { |
| boolean result = true; |
| try |
| { |
| CThread thread = (CThread)getCurrentThread(); |
| if ( thread != null ) |
| { |
| int depth = thread.getStackDepth(); |
| if ( oldDepth < depth ) |
| { |
| ICDIStackFrame[] frames = thread.getCDIStackFrames( depth - oldDepth - 1, depth - oldDepth - 1 ); |
| if ( frames.length == 1 ) |
| { |
| thread.getCDIThread().setCurrentStackFrame( frames[0] ); |
| getCDITarget().stepReturn(); |
| result = false; |
| } |
| } |
| } |
| } |
| catch( CDIException e ) |
| { |
| } |
| catch( DebugException e ) |
| { |
| } |
| return result; |
| } |
| |
| private boolean internalStepReturn( int oldDepth ) |
| { |
| boolean result = true; |
| try |
| { |
| CThread thread = (CThread)getCurrentThread(); |
| if ( thread != null ) |
| { |
| int depth = thread.getStackDepth(); |
| if ( oldDepth < depth ) |
| { |
| ICDIStackFrame[] frames = thread.getCDIStackFrames( depth - oldDepth, depth - oldDepth ); |
| if ( frames.length == 1 ) |
| { |
| thread.getCDIThread().setCurrentStackFrame( frames[0] ); |
| getCDITarget().stepReturn(); |
| result = false; |
| } |
| } |
| } |
| } |
| catch( CDIException e ) |
| { |
| } |
| catch( DebugException e ) |
| { |
| } |
| return result; |
| } |
| */ |
| private void handleResumedEvent( ICDIResumedEvent event ) |
| { |
| setSuspended( false ); |
| setCurrentStateId( IState.RUNNING ); |
| setCurrentStateInfo( null ); |
| resetStatus(); |
| resumeThreads( event ); |
| int detail = DebugEvent.UNSPECIFIED; |
| switch( event.getType() ) |
| { |
| case ICDIResumedEvent.CONTINUE: |
| detail = DebugEvent.CLIENT_REQUEST; |
| break; |
| case ICDIResumedEvent.STEP_INTO: |
| case ICDIResumedEvent.STEP_INTO_INSTRUCTION: |
| detail = DebugEvent.STEP_INTO; |
| break; |
| case ICDIResumedEvent.STEP_OVER: |
| case ICDIResumedEvent.STEP_OVER_INSTRUCTION: |
| detail = DebugEvent.STEP_OVER; |
| break; |
| case ICDIResumedEvent.STEP_RETURN: |
| detail = DebugEvent.STEP_RETURN; |
| break; |
| } |
| if ( getRunningInfo() == null ) |
| setRunningInfo( event.getType() ); |
| fireResumeEvent( detail ); |
| } |
| |
| private void handleEndSteppingRange( ICDIEndSteppingRange endSteppingRange ) |
| { |
| fireSuspendEvent( DebugEvent.UNSPECIFIED ); |
| } |
| |
| private void handleBreakpointHit( ICDIBreakpointHit breakpointHit ) |
| { |
| fireSuspendEvent( DebugEvent.BREAKPOINT ); |
| } |
| |
| private void handleWatchpointTrigger( ICDIWatchpointTrigger wt ) |
| { |
| fireSuspendEvent( DebugEvent.BREAKPOINT ); |
| } |
| |
| private void handleWatchpointScope( ICDIWatchpointScope ws ) |
| { |
| ICBreakpoint watchpoint = getBreakpointManager().getBreakpoint( ws.getWatchpoint() ); |
| if ( watchpoint != null ) |
| { |
| try |
| { |
| getBreakpointManager().removeBreakpoint( watchpoint ); |
| } |
| catch( DebugException e ) |
| { |
| CDebugCorePlugin.log( e ); |
| } |
| fireSuspendEvent( DebugEvent.BREAKPOINT ); |
| } |
| } |
| |
| private void handleSuspendedBySignal( ICDISignalReceived signal ) |
| { |
| fireSuspendEvent( DebugEvent.UNSPECIFIED ); |
| } |
| |
| private void handleErrorInfo( ICDIErrorInfo info ) |
| { |
| setStatus( ICDebugElementErrorStatus.ERROR, ( info != null ) ? info.getMessage() : null ); |
| if ( info != null ) |
| { |
| MultiStatus status = new MultiStatus( CDebugCorePlugin.getUniqueIdentifier(), |
| ICDebugInternalConstants.STATUS_CODE_ERROR, |
| "The execution of program is suspended because of error.", |
| null ); |
| StringTokenizer st = new StringTokenizer( info.getDetailMessage(), "\n\r" ); |
| while( st.hasMoreTokens() ) |
| { |
| String token = st.nextToken(); |
| if ( token.length() > 200 ) |
| { |
| token = token.substring( 0, 200 ); |
| } |
| status.add( new Status( IStatus.ERROR, |
| status.getPlugin(), |
| ICDebugInternalConstants.STATUS_CODE_ERROR, |
| token, |
| null ) ); |
| } |
| CDebugUtils.error( status, this ); |
| } |
| } |
| |
| private void handleSuspendedBySolibEvent( ICDISharedLibraryEvent solibEvent ) |
| { |
| fireSuspendEvent( DebugEvent.UNSPECIFIED ); |
| } |
| |
| private void handleExitedEvent( ICDIExitedEvent event ) |
| { |
| removeAllThreads(); |
| setCurrentStateId( IState.EXITED ); |
| setCurrentStateInfo( event.getReason() ); |
| fireChangeEvent( DebugEvent.CONTENT ); |
| if ( getConfiguration().terminateSessionOnExit() ) |
| terminated(); |
| } |
| |
| private void handleTerminatedEvent( ICDIDestroyedEvent event ) |
| { |
| terminated(); |
| } |
| |
| private void handleDisconnectedEvent( ICDIDisconnectedEvent event ) |
| { |
| setCurrentStateId( IState.DISCONNECTED ); |
| setCurrentStateInfo( null ); |
| disconnected(); |
| } |
| |
| private void handleChangedEvent( ICDIChangedEvent event ) |
| { |
| } |
| |
| private void handleRestartedEvent( ICDIRestartedEvent event ) |
| { |
| } |
| |
| private void handleThreadCreatedEvent( ICDICreatedEvent event ) |
| { |
| ICDIThread cdiThread = (ICDIThread)event.getSource(); |
| CThread thread = findThread( cdiThread ); |
| if ( thread == null ) |
| { |
| createThread( cdiThread ); |
| } |
| } |
| |
| private void handleThreadTerminatedEvent( ICDIDestroyedEvent event ) |
| { |
| ICDIThread cdiThread = (ICDIThread)event.getSource(); |
| CThread thread = findThread( cdiThread ); |
| if ( thread != null) |
| { |
| getThreadList().remove( thread ); |
| thread.terminated(); |
| } |
| } |
| |
| /** |
| * Finds and returns the model thread for the associated CDI thread, |
| * or <code>null</code> if not found. |
| * |
| * @param the underlying CDI thread |
| * @return the associated model thread |
| */ |
| public CThread findThread( ICDIThread cdiThread ) |
| { |
| List threads = getThreadList(); |
| for ( int i = 0; i < threads.size(); i++ ) |
| { |
| CThread t = (CThread)threads.get( i ); |
| if ( t.getCDIThread().equals( cdiThread ) ) |
| return t; |
| } |
| return null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.IState#getCurrentStateId() |
| */ |
| public int getCurrentStateId() |
| { |
| return fCurrentStateId; |
| } |
| |
| /** |
| * Sets the current state identifier. |
| * |
| * @param id the identifier |
| */ |
| private void setCurrentStateId( int id ) |
| { |
| fCurrentStateId = id; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.IState#getCurrentStateInfo() |
| */ |
| public Object getCurrentStateInfo() |
| { |
| return fCurrentStateInfo; |
| } |
| |
| /** |
| * Sets the info object of the current state. |
| * |
| * @param id the info object |
| */ |
| private void setCurrentStateInfo( Object info ) |
| { |
| fCurrentStateInfo = info; |
| } |
| |
| /** |
| * Returns the number of suspend events that have occurred in this |
| * target. |
| * |
| * @return the number of suspend events that have occurred in this |
| * target |
| */ |
| protected int getSuspendCount() |
| { |
| return fSuspendCount; |
| } |
| |
| /** |
| * Increments the suspend counter for this target. |
| */ |
| protected void incrementSuspendCount() |
| { |
| fSuspendCount++; |
| } |
| |
| /** |
| * Overrides the superclass method by incrementing the suspend counter. |
| * |
| * @param detail The int detail of the event |
| * @see org.eclipse.debug.core.DebugEvent |
| */ |
| public void fireSuspendEvent( int detail ) |
| { |
| incrementSuspendCount(); |
| super.fireSuspendEvent( detail ); |
| } |
| |
| protected void setCurrentThread() |
| { |
| ICDIThread currentCDIThread = null; |
| try |
| { |
| currentCDIThread = getCDITarget().getCurrentThread(); |
| } |
| catch( CDIException e ) |
| { |
| CDebugCorePlugin.log( e ); |
| } |
| Iterator it = getThreadList().iterator(); |
| while( it.hasNext() ) |
| { |
| CThread thread = (CThread)it.next(); |
| thread.setCurrent( currentCDIThread != null && thread.getCDIThread().equals( currentCDIThread ) ); |
| } |
| if ( currentCDIThread == null && !getThreadList().isEmpty() ) |
| { |
| ((CThread)getThreadList().get( 0 )).setCurrent( true ); |
| } |
| } |
| |
| /** |
| * Returns the debug configuration of this target. |
| * |
| * @return the debug configuration of this target |
| */ |
| protected ICDIConfiguration getConfiguration() |
| { |
| return fConfig; |
| } |
| |
| /** |
| * Sets the debug configuration of this target. |
| * |
| * @param config the debug configuration to set |
| */ |
| private void setConfiguration( ICDIConfiguration config ) |
| { |
| fConfig = config; |
| } |
| |
| protected boolean supportsExpressionEvaluation() |
| { |
| return getConfiguration().supportsExpressionEvaluation(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.ICExpressionEvaluator#evaluateExpressionToString(String) |
| */ |
| public String evaluateExpressionToString( String expression ) throws DebugException |
| { |
| try |
| { |
| return getCDITarget().evaluateExpressionToString( expression ); |
| } |
| catch( CDIException e ) |
| { |
| targetRequestFailed( e.getMessage(), null ); |
| } |
| return null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.ICExpressionEvaluator#canEvaluate() |
| */ |
| public boolean canEvaluate() |
| { |
| return supportsExpressionEvaluation() && isAvailable() && isSuspended(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.IExpressionListener#expressionAdded(IExpression) |
| */ |
| public void expressionAdded( IExpression expression ) |
| { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.IExpressionListener#expressionChanged(IExpression) |
| */ |
| public void expressionChanged( IExpression expression ) |
| { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.core.IExpressionListener#expressionRemoved(IExpression) |
| */ |
| public void expressionRemoved( IExpression expression ) |
| { |
| if ( expression != null && expression.getDebugTarget().equals( this ) && expression instanceof CExpression ) |
| { |
| ICDIExpressionManager em = getCDISession().getExpressionManager(); |
| try |
| { |
| em.destroyExpression( ((CExpression)expression).getCDIExpression() ); |
| } |
| catch( CDIException e ) |
| { |
| // do nothing |
| } |
| } |
| } |
| |
| public void setInternalTemporaryBreakpoint( ICDILocation location ) throws DebugException |
| { |
| try |
| { |
| getCDISession().getBreakpointManager().setLocationBreakpoint( ICDIBreakpoint.TEMPORARY, |
| location, |
| null, |
| null ); |
| } |
| catch( CDIException e ) |
| { |
| targetRequestFailed( e.getMessage(), null ); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.IRunToLine#canRunToLine(IResource, int) |
| */ |
| public boolean canRunToLine( String fileName, int lineNumber ) |
| { |
| // check if supports run to line |
| return canResume(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.IRunToLine#runToLine(IResource, int) |
| */ |
| public void runToLine( String fileName, int lineNumber ) throws DebugException |
| { |
| if ( !canRunToLine( fileName, lineNumber ) ) |
| return; |
| ICDILocation location = getCDISession().getBreakpointManager().createLocation( fileName, null, lineNumber ); |
| try |
| { |
| getCDITarget().runUntil( location ); |
| } |
| catch( CDIException e ) |
| { |
| targetRequestFailed( e.getMessage(), e ); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.IRunToLine#canRunToLine(IResource, int) |
| */ |
| public boolean canRunToLine( IFile file, int lineNumber ) |
| { |
| // check if supports run to line |
| return canResume(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.IRunToLine#runToLine(IResource, int) |
| */ |
| public void runToLine( IFile file, int lineNumber ) throws DebugException |
| { |
| if ( !canRunToLine( file, lineNumber ) ) |
| return; |
| runToLine( file.getLocation().lastSegment(), lineNumber ); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.ISwitchToThread#setCurrentThread(IThread) |
| */ |
| public void setCurrentThread( IThread thread ) throws DebugException |
| { |
| if ( !isSuspended() || !isAvailable() || thread == null || !(thread instanceof CThread) ) |
| return; |
| try |
| { |
| CThread oldThread = (CThread)getCurrentThread(); |
| if ( !thread.equals( oldThread ) ) |
| { |
| if ( oldThread != null ) |
| oldThread.setCurrent( false ); |
| getCDITarget().setCurrentThread( ((CThread)thread).getCDIThread() ); |
| ((CThread)thread).setCurrent( true ); |
| } |
| } |
| catch( CDIException e ) |
| { |
| targetRequestFailed( e.getMessage(), null ); |
| } |
| } |
| |
| /** |
| * @see org.eclipse.cdt.debug.core.ISwitchToThread#getCurrentThread() |
| */ |
| public IThread getCurrentThread() throws DebugException |
| { |
| IThread[] threads = getThreads(); |
| for ( int i = 0; i < threads.length; ++i ) |
| { |
| if ( ((CThread)threads[i]).isCurrent() ) |
| return threads[i]; |
| } |
| return null; |
| } |
| |
| protected ISourceLocator getSourceLocator() |
| { |
| return getLaunch().getSourceLocator(); |
| } |
| |
| protected void resetRegisters() |
| { |
| getRegisterManager().reset(); |
| } |
| |
| /** |
| * @see org.eclipse.cdt.debug.core.ICDebugTargetType#getTargetType() |
| */ |
| public int getTargetType() |
| { |
| return fTargetType; |
| } |
| |
| private void setTargetType( int targetType ) |
| { |
| fTargetType = targetType; |
| } |
| |
| protected boolean isCoreDumpTarget() |
| { |
| return ( getTargetType() == ICDebugTargetType.TARGET_TYPE_LOCAL_CORE_DUMP ); |
| } |
| |
| protected int getRealSourceMode() |
| { |
| ISourceLocator sl = getSourceLocator(); |
| if ( sl != null && |
| sl instanceof IAdaptable && |
| ((IAdaptable)sl).getAdapter( ICSourceLocator.class ) != null && |
| ((IAdaptable)sl).getAdapter( ICSourceLocator.class ) instanceof CSourceManager ) |
| { |
| return ((CSourceManager)((IAdaptable)sl).getAdapter( ICSourceLocator.class )).getRealMode(); |
| } |
| return ISourceMode.MODE_SOURCE; |
| } |
| |
| protected CMemoryManager getMemoryManager() |
| { |
| return fMemoryManager; |
| } |
| |
| protected void disposeMemoryManager() |
| { |
| getMemoryManager().dispose(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.IDebuggerProcessSupport#isDefault() |
| */ |
| public boolean isDebuggerProcessDefault() |
| { |
| return fIsDebuggerProcessDefault; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.IDebuggerProcessSupport#setDefault(boolean) |
| */ |
| public void setDebuggerProcessDefault( boolean value ) |
| { |
| fIsDebuggerProcessDefault = value; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.IDebuggerProcessSupport#supportsDebuggerProcess() |
| */ |
| public boolean supportsDebuggerProcess() |
| { |
| return ( fDebuggerProcess != null ); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.IExecFileInfo#isLittleEndian() |
| */ |
| public boolean isLittleEndian() |
| { |
| if ( getExecFile() != null && CoreModel.getDefault().isBinary( getExecFile() ) ) |
| { |
| ICElement cFile = CCorePlugin.getDefault().getCoreModel().create( getExecFile() ); |
| if ( cFile instanceof IBinary ) |
| { |
| ((IBinary)cFile).isLittleEndian(); |
| } |
| } |
| return true; |
| } |
| |
| public IFile getExecFile() |
| { |
| return fExecFile; |
| } |
| |
| private void setExecFile( IFile file ) |
| { |
| fExecFile = file; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.IExecFileInfo#getGlobals() |
| */ |
| public IGlobalVariable[] getGlobals() |
| { |
| ArrayList list = new ArrayList(); |
| if ( getExecFile() != null && CoreModel.getDefault().isBinary( getExecFile() ) ) |
| { |
| ICElement cFile = CCorePlugin.getDefault().getCoreModel().create( getExecFile() ); |
| if ( cFile instanceof IParent ) |
| { |
| list.addAll( getCFileGlobals( (IParent)cFile ) ); |
| } |
| } |
| return (IGlobalVariable[])list.toArray( new IGlobalVariable[list.size()] ); |
| } |
| |
| private List getCFileGlobals( IParent file ) |
| { |
| ArrayList list = new ArrayList(); |
| ICElement[] elements = file.getChildren(); |
| for ( int i = 0; i < elements.length; ++i ) |
| { |
| if ( elements[i] instanceof org.eclipse.cdt.core.model.IVariable ) |
| { |
| list.add( createGlobalVariable( (org.eclipse.cdt.core.model.IVariable)elements[i] ) ); |
| } |
| else if ( elements[i] instanceof org.eclipse.cdt.core.model.IParent ) |
| { |
| list.addAll( getCFileGlobals( (org.eclipse.cdt.core.model.IParent)elements[i] ) ); |
| } |
| } |
| return list; |
| } |
| |
| private IGlobalVariable createGlobalVariable( final org.eclipse.cdt.core.model.IVariable var ) |
| { |
| return new IGlobalVariable() |
| { |
| public String getName() |
| { |
| return var.getElementName(); |
| } |
| |
| public IPath getPath() |
| { |
| IPath path = new Path(""); |
| ICElement parent = var.getParent(); |
| if ( parent instanceof IBinaryModule ) |
| { |
| path = ((IBinaryModule)parent).getPath(); |
| } |
| return path; |
| } |
| }; |
| } |
| |
| protected void setDisassemblyManager( DisassemblyManager dm ) |
| { |
| fDisassemblyManager = dm; |
| } |
| |
| protected DisassemblyManager getDisassemblyManager() |
| { |
| return fDisassemblyManager; |
| } |
| |
| protected void setSharedLibraryManager( CSharedLibraryManager libman ) |
| { |
| fSharedLibraryManager = libman; |
| } |
| |
| protected CSharedLibraryManager getSharedLibraryManager() |
| { |
| return fSharedLibraryManager; |
| } |
| |
| protected void disposeSharedLibraryManager() |
| { |
| fSharedLibraryManager.dispose(); |
| } |
| |
| protected void setSignalManager( CSignalManager sm ) |
| { |
| fSignalManager = sm; |
| } |
| |
| protected CSignalManager getSignalManager() |
| { |
| return fSignalManager; |
| } |
| |
| protected void disposeSignalManager() |
| { |
| fSignalManager.dispose(); |
| } |
| |
| protected void disposeRegisterManager() |
| { |
| fRegisterManager.dispose(); |
| } |
| |
| protected void disposeDisassemblyManager() |
| { |
| fDisassemblyManager.dispose(); |
| } |
| |
| /** |
| * @see org.eclipse.cdt.debug.core.model.IRunToAddress#canRunToAddress(long) |
| */ |
| public boolean canRunToAddress( long address ) |
| { |
| // for now |
| return canResume(); |
| } |
| |
| /** |
| * @see org.eclipse.cdt.debug.core.model.IRunToAddress#runToLine(long) |
| */ |
| public void runToAddress( long address ) throws DebugException |
| { |
| if ( !canRunToAddress( address ) ) |
| return; |
| ICDILocation location = getCDISession().getBreakpointManager().createLocation( address ); |
| try |
| { |
| getCDITarget().runUntil( location ); |
| } |
| catch( CDIException e ) |
| { |
| targetRequestFailed( e.getMessage(), e ); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.model.IResumeWithoutSignal#canResumeWithoutSignal() |
| */ |
| public boolean canResumeWithoutSignal() |
| { |
| // Check if the configuration supports this!!! |
| return ( isSuspended() && getCurrentStateInfo() instanceof ICDISignalReceived ); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.model.IResumeWithoutSignal#resumeWithoutSignal() |
| */ |
| public void resumeWithoutSignal() throws DebugException |
| { |
| try |
| { |
| getCDITarget().signal(); |
| } |
| catch( CDIException e ) |
| { |
| targetRequestFailed( e.getMessage(), e ); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.model.IJumpToLine#canJumpToLine(IResource, int) |
| */ |
| public boolean canJumpToLine( IFile file, int lineNumber ) |
| { |
| // check if supports jump to line |
| return canResume(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.model.IJumpToLine#jumpToLine(IResource, int) |
| */ |
| public void jumpToLine( IFile file, int lineNumber ) throws DebugException |
| { |
| if ( !canJumpToLine( file, lineNumber ) ) |
| return; |
| jumpToLine( file.getLocation().lastSegment(), lineNumber ); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.model.IJumpToLine#canJumpToLine(IResource, int) |
| */ |
| public boolean canJumpToLine( String fileName, int lineNumber ) |
| { |
| // check if supports jump to line |
| return canResume(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.model.IJumpToLine#jumpToLine(IResource, int) |
| */ |
| public void jumpToLine( String fileName, int lineNumber ) throws DebugException |
| { |
| if ( !canJumpToLine( fileName, lineNumber ) ) |
| return; |
| ICDILocation location = getCDISession().getBreakpointManager().createLocation( fileName, null, lineNumber ); |
| try |
| { |
| getCDITarget().jump( location ); |
| } |
| catch( CDIException e ) |
| { |
| targetRequestFailed( e.getMessage(), e ); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.model.IJumpToAddress#canJumpToAddress(long) |
| */ |
| public boolean canJumpToAddress( long address ) |
| { |
| // check if supports jump to address |
| return canResume(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.debug.core.model.IJumpToAddress#jumpToAddress(long) |
| */ |
| public void jumpToAddress( long address ) throws DebugException |
| { |
| if ( !canJumpToAddress( address ) ) |
| return; |
| ICDILocation location = getCDISession().getBreakpointManager().createLocation( address ); |
| try |
| { |
| getCDITarget().jump( location ); |
| } |
| catch( CDIException e ) |
| { |
| targetRequestFailed( e.getMessage(), e ); |
| } |
| } |
| |
| public CRegisterManager getRegisterManager() |
| { |
| return fRegisterManager; |
| } |
| |
| protected void setRegisterManager( CRegisterManager registerManager ) |
| { |
| fRegisterManager = registerManager; |
| } |
| |
| public IRegisterGroup[] getRegisterGroups() throws DebugException |
| { |
| return getRegisterManager().getRegisterGroups(); |
| } |
| |
| protected void disposeSourceManager() |
| { |
| ISourceLocator locator = getSourceLocator(); |
| if ( locator instanceof IAdaptable ) |
| { |
| IResourceChangeListener listener = (IResourceChangeListener)((IAdaptable)locator).getAdapter( IResourceChangeListener.class ); |
| if ( listener != null ) |
| CCorePlugin.getWorkspace().removeResourceChangeListener( listener ); |
| } |
| } |
| |
| protected RunningInfo getRunningInfo() |
| { |
| return fRunningInfo; |
| } |
| |
| public IFile getCurrentBreakpointFile() |
| { |
| Object info = getCurrentStateInfo(); |
| if ( info instanceof ICDIBreakpointHit ) |
| { |
| ICDIBreakpoint cdiBreakpoint = ((ICDIBreakpointHit)info).getBreakpoint(); |
| if ( cdiBreakpoint != null ) |
| return getBreakpointManager().getCDIBreakpointFile( cdiBreakpoint ); |
| } |
| return null; |
| } |
| |
| protected void setRunningInfo( RunningInfo info ) |
| { |
| fRunningInfo = info; |
| } |
| |
| protected void setRunningInfo( int type ) |
| { |
| RunningInfo info = null; |
| try |
| { |
| CThread thread = (CThread)getCurrentThread(); |
| if ( thread != null ) |
| { |
| int depth = thread.getLastStackDepth(); |
| if ( depth > 0 ) |
| { |
| info = new RunningInfo( type, depth ); |
| } |
| } |
| } |
| catch( DebugException e ) |
| { |
| } |
| setRunningInfo( info ); |
| } |
| |
| protected CBreakpointManager getBreakpointManager() |
| { |
| return fBreakpointManager; |
| } |
| |
| protected void setBreakpointManager( CBreakpointManager manager ) |
| { |
| fBreakpointManager = manager; |
| } |
| |
| protected void disposeBreakpointManager() |
| { |
| if ( getBreakpointManager() != null ) |
| getBreakpointManager().dispose(); |
| } |
| } |