diff --git a/debug/org.eclipse.cdt.debug.core/ChangeLog b/debug/org.eclipse.cdt.debug.core/ChangeLog index 1fa86a7ef64..fbbc89f7629 100644 --- a/debug/org.eclipse.cdt.debug.core/ChangeLog +++ b/debug/org.eclipse.cdt.debug.core/ChangeLog @@ -1,7 +1,20 @@ +2004-02-10 Mikhail Khodjaiants + Cache the endianness flag. + * CDebugTarget.java + 2004-01-30 Mikhail Khodjaiants Fix for bug 50981: In the 'getValue' method of CVariable 'getType' should be only called once. * CVariable.java +2004-01-29 Mikhail Khodjaiants + Fire sets of debug events instead of firing it one by one. + * CDebugTarget.java + * CThread.java + +2004-01-29 Mikhail Khodjaiants + Added DebugEvent factory methods to 'CDebugElement'. + * CDebugElement.java + 2004-01-15 Mikhail Khodjaiants Fix for bug 48682: IThread.getBreakpoints() stubbed out. * CDebugTarget.java diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugElement.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugElement.java index 82807174ca1..709539cbfcd 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugElement.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugElement.java @@ -120,11 +120,16 @@ public class CDebugElement extends PlatformObject * @param event The debug event to be fired to the listeners * @see org.eclipse.debug.core.DebugEvent */ - protected void fireEvent(DebugEvent event) + protected void fireEvent( DebugEvent event ) { DebugPlugin.getDefault().fireDebugEventSet( new DebugEvent[] { event } ); } + protected void fireEventSet( DebugEvent[] events ) + { + DebugPlugin.getDefault().fireDebugEventSet( events ); + } + /** * Fires a debug event marking the creation of this element. */ @@ -133,6 +138,11 @@ public class CDebugElement extends PlatformObject fireEvent( new DebugEvent( this, DebugEvent.CREATE ) ); } + public DebugEvent createCreateEvent() + { + return new DebugEvent( this, DebugEvent.CREATE ); + } + /** * Fires a debug event marking the RESUME of this element with * the associated detail. @@ -145,6 +155,11 @@ public class CDebugElement extends PlatformObject fireEvent( new DebugEvent( this, DebugEvent.RESUME, detail ) ); } + public DebugEvent createResumeEvent( int detail ) + { + return new DebugEvent( this, DebugEvent.RESUME, detail ); + } + /** * Fires a debug event marking the SUSPEND of this element with * the associated detail. @@ -157,6 +172,11 @@ public class CDebugElement extends PlatformObject fireEvent( new DebugEvent( this, DebugEvent.SUSPEND, detail ) ); } + public DebugEvent createSuspendEvent( int detail ) + { + return new DebugEvent( this, DebugEvent.SUSPEND, detail ); + } + /** * Fires a debug event marking the termination of this element. */ @@ -165,6 +185,11 @@ public class CDebugElement extends PlatformObject fireEvent( new DebugEvent( this, DebugEvent.TERMINATE ) ); } + public DebugEvent createTerminateEvent() + { + return new DebugEvent( this, DebugEvent.TERMINATE ); + } + /** * Fires a debug event marking the CHANGE of this element * with the specifed detail code. @@ -176,6 +201,11 @@ public class CDebugElement extends PlatformObject fireEvent( new DebugEvent( this, DebugEvent.CHANGE, detail ) ); } + public DebugEvent createChangeEvent( int detail ) + { + return new DebugEvent( this, DebugEvent.CHANGE, detail ); + } + /** * Returns the CDI session associated with this element. * diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java index ab8da073175..61618c19a19 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java @@ -137,6 +137,8 @@ public class CDebugTarget extends CDebugElement } } + private boolean fSuspending; + /** * The type of this target. */ @@ -259,6 +261,11 @@ public class CDebugTarget extends CDebugElement */ private IFile fExecFile; + /** + * Whether the target is little endian. + */ + private Boolean fIsLittleEndian = null; + private RunningInfo fRunningInfo = null; /** @@ -334,6 +341,16 @@ public class CDebugTarget extends CDebugElement } for ( int i = 0; i < threads.length; ++i ) createThread( threads[i] ); + + // Fire thread creation events. + List list = getThreadList(); + ArrayList debugEvents = new ArrayList( list.size() ); + Iterator it = list.iterator(); + while( it.hasNext() ) + { + debugEvents.add( ((CThread)it.next()).createCreateEvent() ); + } + fireEventSet( (DebugEvent[])debugEvents.toArray( new DebugEvent[debugEvents.size()] ) ); } /** @@ -514,16 +531,34 @@ public class CDebugTarget extends CDebugElement */ public void terminate() throws DebugException { - try + if ( isTerminating() ) { - setTerminating( true ); - getCDITarget().terminate(); - } - catch( CDIException e ) - { - setTerminating( false ); - targetRequestFailed( e.getMessage(), e ); + return; } + setTerminating( true ); + DebugPlugin.getDefault().asyncExec( + new Runnable() + { + public void run() + { + try + { + getCDITarget().terminate(); + } + catch( CDIException e ) + { + setTerminating( false ); + try + { + targetRequestFailed( e.getMessage(), e ); + } + catch( DebugException e1 ) + { + CDebugUtils.error( e1.getStatus(), CDebugTarget.this ); + } + } + } + } ); } /** @@ -581,7 +616,7 @@ public class CDebugTarget extends CDebugElement */ public void resume() throws DebugException { - if ( !isSuspended() ) + if ( !isSuspended() && !isSuspending() ) return; try { @@ -598,18 +633,41 @@ public class CDebugTarget extends CDebugElement */ public void suspend() throws DebugException { - if ( isSuspended() ) + if ( isSuspended() || isSuspending() ) return; - try - { - getCDITarget().suspend(); - } - catch( CDIException e ) - { - targetRequestFailed( e.getMessage(), e ); - } + + setSuspending(true); + DebugPlugin.getDefault().asyncExec(new Runnable() { + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + public void run() { + try { + getCDITarget().suspend(); + } catch( CDIException e ) { + try { + targetRequestFailed( e.getMessage(), e ); + } catch (DebugException e1) { + CDebugUtils.error(e1.getStatus(), CDebugTarget.this); + } + + } finally { + setSuspending(false); + } + } + }); } + protected void setSuspending( boolean value ) + { + fSuspending = value; + } + + protected boolean isSuspending() + { + return fSuspending; + } + /** * Notifies threads that they have been suspended. * @@ -629,42 +687,50 @@ public class CDebugTarget extends CDebugElement */ protected synchronized List refreshThreads() { - ArrayList list = new ArrayList( 5 ); ArrayList newThreads = new ArrayList( 5 ); + ArrayList list = new ArrayList( 5 ); + ArrayList debugEvents = new ArrayList( 5 ); + List oldList = (List)getThreadList().clone(); + + ICDIThread[] cdiThreads = new ICDIThread[0]; 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(); - } + cdiThreads = getCDITarget().getThreads(); } catch( CDIException e ) { CDebugCorePlugin.log( e ); } + for ( int i = 0; i < cdiThreads.length; ++i ) + { + CThread thread = findThread( oldList, cdiThreads[i] ); + if ( thread == null ) + { + thread = new CThread( this, cdiThreads[i] ); + newThreads.add( thread ); + } + else + { + oldList.remove( thread ); + } + list.add( thread ); + } + + Iterator it = oldList.iterator(); + while( it.hasNext() ) + { + CThread thread = (CThread)it.next(); + thread.terminated(); + debugEvents.add( thread.createTerminateEvent() ); + } + setThreadList( list ); + it = newThreads.iterator(); + while( it.hasNext() ) + { + debugEvents.add( ((CThread)it.next()).createCreateEvent() ); + } + if ( debugEvents.size() > 0 ) + fireEventSet( (DebugEvent[])debugEvents.toArray( new DebugEvent[debugEvents.size()] ) ); setCurrentThread(); return newThreads; } @@ -672,8 +738,13 @@ public class CDebugTarget extends CDebugElement /** * Notifies threads that they have been resumed */ - protected void resumeThreads( ICDIResumedEvent event ) + protected synchronized void resumeThreads( List debugEvents, int detail ) { + Iterator it = getThreadList().iterator(); + while( it.hasNext() ) + { + ((CThread)it.next()).resumed( detail, debugEvents ); + } } /* (non-Javadoc) @@ -693,7 +764,7 @@ public class CDebugTarget extends CDebugElement if ( !isAvailable() ) return; if ( breakpoint instanceof ICAddressBreakpoint && !getBreakpointManager().supportsAddressBreakpoint( (ICAddressBreakpoint)breakpoint ) ) - return; + return; if ( getConfiguration().supportsBreakpoints() ) { try @@ -1167,13 +1238,17 @@ public class CDebugTarget extends CDebugElement */ protected void removeAllThreads() { - Iterator itr = getThreadList().iterator(); + List threads = getThreadList(); setThreadList( new ArrayList( 0 ) ); - while( itr.hasNext() ) + ArrayList debugEvents = new ArrayList( threads.size() ); + Iterator it = threads.iterator(); + while( it.hasNext() ) { - CThread thread = (CThread)itr.next(); + CThread thread = (CThread)it.next(); thread.terminated(); + debugEvents.add( thread.createTerminateEvent() ); } + fireEventSet( (DebugEvent[])debugEvents.toArray( new DebugEvent[debugEvents.size()] ) ); } /** @@ -1206,7 +1281,6 @@ public class CDebugTarget extends CDebugElement { CThread thread = new CThread( this, cdiThread ); getThreadList().add( thread ); - thread.fireCreationEvent(); return thread; } @@ -1221,7 +1295,6 @@ public class CDebugTarget extends CDebugElement CThread thread = new CThread( this, cdiThread ); thread.setRunning( true ); getThreadList().add( thread ); - thread.fireCreationEvent(); return thread; } @@ -1237,7 +1310,6 @@ public class CDebugTarget extends CDebugElement if ( event.getSource() instanceof ICDITarget ) { suspendThreads( event ); - fireSuspendEvent( DebugEvent.UNSPECIFIED ); } // We need this for debuggers that don't have notifications // for newly created threads. @@ -1387,7 +1459,7 @@ public class CDebugTarget extends CDebugElement setCurrentStateId( IState.RUNNING ); setCurrentStateInfo( null ); resetStatus(); - resumeThreads( event ); + ArrayList debugEvents = new ArrayList( 10 ); int detail = DebugEvent.UNSPECIFIED; switch( event.getType() ) { @@ -1406,9 +1478,11 @@ public class CDebugTarget extends CDebugElement detail = DebugEvent.STEP_RETURN; break; } + resumeThreads( debugEvents, detail ); if ( getRunningInfo() == null ) setRunningInfo( event.getType() ); - fireResumeEvent( detail ); + debugEvents.add( createResumeEvent( detail ) ); + fireEventSet( (DebugEvent[])debugEvents.toArray( new DebugEvent[debugEvents.size()] ) ); } private void handleEndSteppingRange( ICDIEndSteppingRange endSteppingRange ) @@ -1514,10 +1588,11 @@ public class CDebugTarget extends CDebugElement { ICDIThread cdiThread = (ICDIThread)event.getSource(); CThread thread = findThread( cdiThread ); - if ( thread == null ) - { - createThread( cdiThread ); - } + if ( thread == null ) + { + thread = createThread( cdiThread ); + thread.fireCreationEvent(); + } } private void handleThreadTerminatedEvent( ICDIDestroyedEvent event ) @@ -1528,6 +1603,7 @@ public class CDebugTarget extends CDebugElement { getThreadList().remove( thread ); thread.terminated(); + thread.fireTerminateEvent(); } } @@ -1550,6 +1626,17 @@ public class CDebugTarget extends CDebugElement return null; } + public CThread findThread( List threads, ICDIThread cdiThread ) + { + 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() */ @@ -1902,15 +1989,19 @@ public class CDebugTarget extends CDebugElement */ public boolean isLittleEndian() { - if ( getExecFile() != null && CoreModel.getDefault().isBinary( getExecFile() ) ) + if ( fIsLittleEndian == null ) { - ICElement cFile = CCorePlugin.getDefault().getCoreModel().create( getExecFile() ); - if ( cFile instanceof IBinary ) + fIsLittleEndian = Boolean.TRUE; + if ( getExecFile() != null && CoreModel.getDefault().isBinary( getExecFile() ) ) { - ((IBinary)cFile).isLittleEndian(); + ICElement cFile = CCorePlugin.getDefault().getCoreModel().create( getExecFile() ); + if ( cFile instanceof IBinary ) + { + fIsLittleEndian = new Boolean( ((IBinary)cFile).isLittleEndian() ); + } } } - return true; + return fIsLittleEndian.booleanValue(); } public IFile getExecFile() @@ -2274,4 +2365,20 @@ public class CDebugTarget extends CDebugElement } return (IBreakpoint[])list.toArray( new IBreakpoint[list.size()]); } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() + { + String result = ""; + try + { + result = getName(); + } + catch( DebugException e ) + { + } + return result; + } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CThread.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CThread.java index f85774c4284..5f0f3221764 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CThread.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CThread.java @@ -11,6 +11,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; +import org.eclipse.cdt.debug.core.CDebugUtils; import org.eclipse.cdt.debug.core.cdi.CDIException; import org.eclipse.cdt.debug.core.cdi.ICDIConfiguration; import org.eclipse.cdt.debug.core.cdi.ICDIEndSteppingRange; @@ -40,6 +41,7 @@ import org.eclipse.cdt.debug.core.sourcelookup.ISourceMode; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; @@ -59,6 +61,8 @@ public class CThread extends CDebugElement ISwitchToFrame, ICDIEventListener { + private boolean fSuspending; + private final static int MAX_STACK_DEPTH = 100; /** @@ -435,8 +439,7 @@ public class CThread extends CDebugElement } else if ( event instanceof ICDIResumedEvent ) { - if ( ( source instanceof ICDIThread && source.equals( getCDIThread() ) ) || - source instanceof ICDITarget ) + if ( ( source instanceof ICDIThread && source.equals( getCDIThread() ) ) ) { handleResumedEvent( (ICDIResumedEvent)event ); } @@ -494,7 +497,7 @@ public class CThread extends CDebugElement */ public void resume() throws DebugException { - if ( !isSuspended() ) + if ( !isSuspended() && !isSuspending() ) return; try { @@ -511,18 +514,39 @@ public class CThread extends CDebugElement */ public void suspend() throws DebugException { - if ( isSuspended() ) - { + if ( isSuspended() || isSuspending() ) return; - } - try - { - getCDIThread().suspend(); - } - catch( CDIException e ) - { - targetRequestFailed( e.getMessage(), e ); - } + + setSuspending(true); + DebugPlugin.getDefault().asyncExec(new Runnable() { + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + public void run() { + try { + getCDITarget().suspend(); + } catch( CDIException e ) { + try { + targetRequestFailed( e.getMessage(), e ); + } catch (DebugException e1) { + CDebugUtils.error(e1.getStatus(), CThread.this); + } + + } finally { + setSuspending(false); + } + } + }); + } + + protected void setSuspending( boolean value ) + { + fSuspending = value; + } + + protected boolean isSuspending() + { + return fSuspending; } /* (non-Javadoc) @@ -735,7 +759,7 @@ public class CThread extends CDebugElement CStackFrame frame = (CStackFrame)(((IAdaptable)it.next()).getAdapter( CStackFrame.class )); if ( frame != null ) { - frame.dispose(); + ((CStackFrame)frame).dispose(); } } fStackFrames.clear(); @@ -771,7 +795,6 @@ public class CThread extends CDebugElement setRunning( false ); dispose(); cleanup(); - fireTerminateEvent(); } /* (non-Javadoc) @@ -865,7 +888,7 @@ public class CThread extends CDebugElement setRunning( false ); if ( event.getSource() instanceof ICDITarget ) { - if ( isCurrent() ) + if ( isCurrent() && getCurrentStateId() != IState.SUSPENDED ) { setCurrentStateId( IState.SUSPENDED ); ICDISessionObject reason = event.getReason(); @@ -1152,4 +1175,40 @@ public class CThread extends CDebugElement return result; } */ + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() + { + String result = ""; + try + { + result = getName(); + } + catch( DebugException e ) + { + } + return result; + } + + protected void resumed( int detail, List events ) + { + setRunning( true ); + setLastStackFrame( null ); + int state = IState.RUNNING; + if ( isCurrent() && detail != DebugEvent.CLIENT_REQUEST && detail != DebugEvent.UNSPECIFIED ) + { + preserveStackFrames(); + state = IState.STEPPING; + events.add( createResumeEvent( detail ) ); + } + else + { + disposeStackFrames(); + events.add( createChangeEvent( DebugEvent.CONTENT ) ); + } + setCurrentStateId( state ); + setCurrentStateInfo( null ); + } }