mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 09:25:31 +02:00
Implementation of 'attach to running process' and 'post-mortem' debug targets.
This commit is contained in:
parent
3b3e71a2a1
commit
4054c82f50
7 changed files with 208 additions and 75 deletions
|
@ -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 <code>IDebugTarget.getProcess</code>
|
||||
* @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 <code>$</code>). For example,
|
||||
* <code>example.SomeClass$InnerType</code>, could be specified, but
|
||||
* <code>example.SomeClass</code> 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 <code>null</code> if none.
|
||||
* @return a line breakpoint
|
||||
* @exception DebugException If this method fails. Reasons include:
|
||||
*/
|
||||
public static ICLineBreakpoint createLineBreakpoint( IResource resource,
|
||||
int lineNumber,
|
||||
boolean enabled,
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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 ) );
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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() );
|
||||
|
|
Loading…
Add table
Reference in a new issue