From 4054c82f50a7dcf2907ff5bb94dc106943302f43 Mon Sep 17 00:00:00 2001 From: Mikhail Khodjaiants Date: Mon, 30 Sep 2002 20:21:01 +0000 Subject: [PATCH] Implementation of 'attach to running process' and 'post-mortem' debug targets. --- .../eclipse/cdt/debug/core/CDebugModel.java | 145 ++++++++++++++---- .../cdt/debug/core/ICDebugTargetType.java | 22 +++ .../internal/core/model/CDebugElement.java | 2 +- .../internal/core/model/CDebugTarget.java | 75 ++++----- .../core/model/CModificationVariable.java | 6 + .../debug/internal/core/model/CThread.java | 7 +- .../ui/CDTDebugModelPresentation.java | 26 ++++ 7 files changed, 208 insertions(+), 75 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICDebugTargetType.java diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugModel.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugModel.java index c317f1f912f..73f07aa7308 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugModel.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugModel.java @@ -12,7 +12,10 @@ import java.util.HashMap; import org.eclipse.cdt.debug.core.cdi.CDIException; import org.eclipse.cdt.debug.core.cdi.ICDIConfiguration; import org.eclipse.cdt.debug.core.cdi.ICDILocation; +import org.eclipse.cdt.debug.core.cdi.ICDISessionObject; +import org.eclipse.cdt.debug.core.cdi.event.ICDISuspendedEvent; import org.eclipse.cdt.debug.core.cdi.model.ICDIExpression; +import org.eclipse.cdt.debug.core.cdi.model.ICDIObject; import org.eclipse.cdt.debug.core.cdi.model.ICDITarget; import org.eclipse.cdt.debug.internal.core.CDebugUtils; import org.eclipse.cdt.debug.internal.core.ICDebugInternalConstants; @@ -20,6 +23,7 @@ import org.eclipse.cdt.debug.internal.core.breakpoints.CLineBreakpoint; import org.eclipse.cdt.debug.internal.core.breakpoints.CWatchpoint; import org.eclipse.cdt.debug.internal.core.model.CDebugTarget; import org.eclipse.cdt.debug.internal.core.model.CExpression; +import org.eclipse.cdt.debug.internal.core.model.CThread; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -29,6 +33,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; 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; @@ -37,6 +42,7 @@ 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.IProcess; +import org.eclipse.debug.core.model.IThread; /** * @@ -83,7 +89,7 @@ public class CDebugModel * which will be returned from IDebugTarget.getProcess * @param allowTerminate whether the target will support termianation * @param allowDisconnect whether the target will support disconnection - * @param resume whether the target is to be resumed on startup. + * @param stopInMain whether to set a temporary breakpoint in main. * @return a debug target */ public static IDebugTarget newDebugTarget( final ILaunch launch, @@ -101,7 +107,8 @@ public class CDebugModel { public void run( IProgressMonitor m ) { - target[0] = new CDebugTarget( launch, + target[0] = new CDebugTarget( launch, + ICDebugTargetType.TARGET_TYPE_LOCAL_RUN, cdiTarget, name, process, @@ -135,6 +142,108 @@ public class CDebugModel return target[0]; } + public static IDebugTarget newAttachDebugTarget( final ILaunch launch, + final ICDITarget cdiTarget, + final String name, + final IProcess process, + final IProject project ) throws DebugException + { + final IDebugTarget[] target = new IDebugTarget[1]; + + IWorkspaceRunnable r = new IWorkspaceRunnable() + { + public void run( IProgressMonitor m ) + { + target[0] = new CDebugTarget( launch, + ICDebugTargetType.TARGET_TYPE_LOCAL_ATTACH, + cdiTarget, + name, + process, + project, + false, + true ); + } + }; + try + { + ResourcesPlugin.getWorkspace().run( r, null ); + } + catch( CoreException e ) + { + CDebugCorePlugin.log( e ); + throw new DebugException( e.getStatus() ); + } + + ICDIConfiguration config = cdiTarget.getSession().getConfiguration(); + + ((CDebugTarget)target[0]).handleDebugEvent( new ICDISuspendedEvent() + { + public ICDISessionObject getReason() + { + return null; + } + + public ICDIObject getSource() + { + return cdiTarget; + } + + } ); + + return target[0]; + } + + public static IDebugTarget newCoreFileDebugTarget( final ILaunch launch, + final ICDITarget cdiTarget, + final String name, + final IProcess process, + final IProject project ) throws DebugException + { + final IDebugTarget[] target = new IDebugTarget[1]; + + IWorkspaceRunnable r = new IWorkspaceRunnable() + { + public void run( IProgressMonitor m ) + { + target[0] = new CDebugTarget( launch, + ICDebugTargetType.TARGET_TYPE_LOCAL_CORE_DUMP, + cdiTarget, + name, + process, + project, + true, + false ); + } + }; + try + { + ResourcesPlugin.getWorkspace().run( r, null ); + } + catch( CoreException e ) + { + CDebugCorePlugin.log( e ); + throw new DebugException( e.getStatus() ); + } + + ICDIConfiguration config = cdiTarget.getSession().getConfiguration(); + + ((CDebugTarget)target[0]).handleDebugEvent( new ICDISuspendedEvent() + { + public ICDISessionObject getReason() + { + return null; + } + + public ICDIObject getSource() + { + return cdiTarget; + } + + } ); + + return target[0]; + } + /** * Returns a C/C++ line breakpoint that is already registered with the breakpoint * manager for a file with the given name at the given line number. @@ -174,38 +283,6 @@ public class CDebugModel return null; } - /** - * Creates and returns a line breakpoint in the file with the - * given name, at the given line number. The marker associated with the - * breakpoint will be created on the specified resource. If a character - * range within the line is known, it may be specified by charStart/charEnd. - * If ignoreCount is > 0, the breakpoint will suspend execution when it is - * "hit" the specified number of times. - * - * @param resource the resource on which to create the associated breakpoint - * marker - * @param typeName the fully qualified name of the type the breakpoint is - * to be installed in. If the breakpoint is to be installed in an inner type, - * it is sufficient to provide the name of the top level enclosing type. - * If an inner class name is specified, it should be formatted as the - * associated class file name (i.e. with $). For example, - * example.SomeClass$InnerType, could be specified, but - * example.SomeClass is sufficient. - * @param lineNumber the lineNumber on which the breakpoint is set - line - * numbers are 1 based, associated with the source file in which - * the breakpoint is set - * @param charStart the first character index associated with the breakpoint, - * or -1 if unspecified, in the source file in which the breakpoint is set - * @param charEnd the last character index associated with the breakpoint, - * or -1 if unspecified, in the source file in which the breakpoint is set - * @param hitCount the number of times the breakpoint will be hit before - * suspending execution - 0 if it should always suspend - * @param register whether to add this breakpoint to the breakpoint manager - * @param attributes a map of client defined attributes that should be assigned - * to the underlying breakpoint marker on creation, or null if none. - * @return a line breakpoint - * @exception DebugException If this method fails. Reasons include: - */ public static ICLineBreakpoint createLineBreakpoint( IResource resource, int lineNumber, boolean enabled, diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICDebugTargetType.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICDebugTargetType.java new file mode 100644 index 00000000000..e07add589ac --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICDebugTargetType.java @@ -0,0 +1,22 @@ +package org.eclipse.cdt.debug.core; + +/** + * + * Enter type comment. + * + * @since: Sep 30, 2002 + */ +public interface ICDebugTargetType +{ + public static final int TARGET_TYPE_UNKNOWN = 0; + public static final int TARGET_TYPE_LOCAL_RUN = 1; + public static final int TARGET_TYPE_LOCAL_ATTACH = 2; + public static final int TARGET_TYPE_LOCAL_CORE_DUMP = 3; + + /** + * Returns the type of this target. + * + * @return the type of this target + */ + int getTargetType(); +} 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 c9a537d4fdd..58df384f4f9 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 @@ -153,7 +153,7 @@ public class CDebugElement extends PlatformObject /** * Fires a debug event marking the termination of this element. */ - protected void fireTerminateEvent() + public void fireTerminateEvent() { fireEvent( new DebugEvent( this, DebugEvent.TERMINATE ) ); } 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 0e5fd280a8f..e775e938336 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 @@ -14,6 +14,7 @@ import java.util.List; import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.core.CDebugModel; import org.eclipse.cdt.debug.core.ICBreakpoint; +import org.eclipse.cdt.debug.core.ICDebugTargetType; import org.eclipse.cdt.debug.core.ICExpressionEvaluator; import org.eclipse.cdt.debug.core.ICLineBreakpoint; import org.eclipse.cdt.debug.core.ICWatchpoint; @@ -87,6 +88,7 @@ import org.eclipse.debug.core.model.IThread; */ public class CDebugTarget extends CDebugElement implements IDebugTarget, + ICDebugTargetType, ICDIEventListener, IRestart, IRunToLine, @@ -97,6 +99,11 @@ public class CDebugTarget extends CDebugElement IExpressionListener, ICExpressionEvaluator { + /** + * 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 @@ -139,11 +146,6 @@ public class CDebugTarget extends CDebugElement */ private boolean fDisconnected; - /** - * Whether the target should be resumed on startup - */ - private boolean fResumeOnStartup = false; - /** * The launch this target is contained in */ @@ -198,7 +200,8 @@ public class CDebugTarget extends CDebugElement * Constructor for CDebugTarget. * @param target */ - public CDebugTarget( ILaunch launch, + public CDebugTarget( ILaunch launch, + int targetType, ICDITarget cdiTarget, String name, IProcess process, @@ -208,6 +211,7 @@ public class CDebugTarget extends CDebugElement { super( null ); setLaunch( launch ); + setTargetType( targetType ); setDebugTarget( this ); setName( name ); setProcess( process ); @@ -256,12 +260,7 @@ public class CDebugTarget extends CDebugElement // ignore } for ( int i = 0; i < threads.length; ++i ) - createRunningThread( threads[i] ); - - if ( isResumeOnStartup() ) - { - setSuspended( false ); - } + createThread( threads[i] ); } /** @@ -780,12 +779,16 @@ public class CDebugTarget extends CDebugElement { 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; return super.getAdapter( adapter ); } @@ -989,8 +992,10 @@ public class CDebugTarget extends CDebugElement setTerminating( false ); if ( !isTerminated() ) { - setTerminated( true ); - setDisconnected( true ); + if ( !isDisconnected() ) + { + setTerminated( true ); + } cleanup(); fireTerminateEvent(); } @@ -1004,6 +1009,7 @@ public class CDebugTarget extends CDebugElement { if ( !isDisconnected() ) { + setDisconnected( true ); try { getCDISession().terminate(); @@ -1012,7 +1018,6 @@ public class CDebugTarget extends CDebugElement { logError( e ); } - setDisconnected( true ); cleanup(); fireTerminateEvent(); } @@ -1216,26 +1221,6 @@ public class CDebugTarget extends CDebugElement return thread; } - /** - * Sets whether this target should be resumed on startup. - * - * @param resume whether this target should be resumed on startup - */ - private void setResumeOnStartup( boolean resume ) - { - fResumeOnStartup = resume; - } - - /** - * Returns whether this target should be resumed on startup. - * - * @return whether this target should be resumed on startup - */ - protected boolean isResumeOnStartup() - { - return fResumeOnStartup; - } - private void handleSuspendedEvent( ICDISuspendedEvent event ) { setSuspended( true ); @@ -1359,8 +1344,6 @@ public class CDebugTarget extends CDebugElement private void handleTerminatedEvent( ICDIDestroyedEvent event ) { -// setCurrentStateId( IState.TERMINATED ); -// setCurrentStateInfo( null ); IProcess process = getProcess(); if ( process != null ) { @@ -1868,4 +1851,22 @@ public class CDebugTarget extends CDebugElement CDebugCorePlugin.log( e ); } } + + /** + * @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 ); + } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CModificationVariable.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CModificationVariable.java index 0697500f007..48df8c0edad 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CModificationVariable.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CModificationVariable.java @@ -45,6 +45,12 @@ public abstract class CModificationVariable extends CVariable */ public boolean supportsValueModification() { + CDebugTarget target = (CDebugTarget)getDebugTarget().getAdapter( CDebugTarget.class ); + if ( target == null || target.isCoreDumpTarget() ) + { + return false; + } + try { IValue value = getValue(); 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 ecf0e6380d3..34a820238b9 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 @@ -120,7 +120,8 @@ public class CThread extends CDebugElement protected void initialize() { fStackFrames = Collections.EMPTY_LIST; - setRunning( !getCDIThread().isSuspended() ); + setRunning( false ); +// setRunning( !getCDIThread().isSuspended() ); } /* (non-Javadoc) @@ -432,7 +433,7 @@ public class CThread extends CDebugElement */ public boolean canResume() { - return isSuspended(); + return fConfig.supportsResume() && isSuspended(); } /* (non-Javadoc) @@ -440,7 +441,7 @@ public class CThread extends CDebugElement */ public boolean canSuspend() { - return !isSuspended(); + return fConfig.supportsSuspend() && !isSuspended(); } /* (non-Javadoc) diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDTDebugModelPresentation.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDTDebugModelPresentation.java index cfe5469009f..19b057596c6 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDTDebugModelPresentation.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDTDebugModelPresentation.java @@ -11,6 +11,7 @@ import java.util.HashMap; import org.eclipse.cdt.debug.core.ICAddressBreakpoint; import org.eclipse.cdt.debug.core.ICBreakpoint; +import org.eclipse.cdt.debug.core.ICDebugTargetType; import org.eclipse.cdt.debug.core.ICFunctionBreakpoint; import org.eclipse.cdt.debug.core.ICLineBreakpoint; import org.eclipse.cdt.debug.core.ICValue; @@ -164,6 +165,25 @@ public class CDTDebugModelPresentation extends LabelProvider */ public Image getImage( Object element ) { + if ( element instanceof IDebugTarget ) + { + ICDebugTargetType targetType = (ICDebugTargetType)((IDebugTarget)element).getAdapter( ICDebugTargetType.class ); + int type = ( targetType != null ) ? targetType.getTargetType() : ICDebugTargetType.TARGET_TYPE_UNKNOWN; + if ( type == ICDebugTargetType.TARGET_TYPE_LOCAL_CORE_DUMP ) + { + return fDebugImageRegistry.get( new CImageDescriptor( DebugUITools.getImageDescriptor( IDebugUIConstants.IMG_OBJS_DEBUG_TARGET_TERMINATED ), 0 ) ); + } + } + if ( element instanceof IThread ) + { + ICDebugTargetType targetType = (ICDebugTargetType)((IThread)element).getDebugTarget().getAdapter( ICDebugTargetType.class ); + int type = ( targetType != null ) ? targetType.getTargetType() : ICDebugTargetType.TARGET_TYPE_UNKNOWN; + if ( type == ICDebugTargetType.TARGET_TYPE_LOCAL_CORE_DUMP ) + { + return fDebugImageRegistry.get( new CImageDescriptor( DebugUITools.getImageDescriptor( IDebugUIConstants.IMG_OBJS_THREAD_TERMINATED ), 0 ) ); + } + } + try { if ( element instanceof IMarker ) @@ -347,6 +367,12 @@ public class CDTDebugModelPresentation extends LabelProvider protected String getThreadText( IThread thread, boolean qualified ) throws DebugException { + ICDebugTargetType targetType = (ICDebugTargetType)thread.getDebugTarget().getAdapter( ICDebugTargetType.class ); + int type = ( targetType != null ) ? targetType.getTargetType() : ICDebugTargetType.TARGET_TYPE_UNKNOWN; + if ( type == ICDebugTargetType.TARGET_TYPE_LOCAL_CORE_DUMP ) + { + return getFormattedString( "Thread [{0}]", thread.getName() ); + } if ( thread.isTerminated() ) { return getFormattedString( "Thread [{0}] (Terminated)", thread.getName() );