1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Implementing adapters for the platform's Memory view.

This commit is contained in:
Mikhail Khodjaiants 2004-09-30 20:28:03 +00:00
parent 645b3306eb
commit 30a7d6170f
6 changed files with 555 additions and 0 deletions

View file

@ -1,3 +1,11 @@
2004-09-30 Mikhail Khodjaiants
Implementing adapters for the platform's Memory view.
* CExtendedMemoryBlockRetrieval.java: new
* CDebugTarget.java
* CExtendedMemoryBlock.java: new
* CThread.java
* InternalDebugCoreMessages.properties
2004-09-29 Mikhail Khodjaiants
Use the new "createAddress(BigInteger)" method of "IAddressFactory".
* CBreakpointManager.java

View file

@ -0,0 +1,96 @@
/**********************************************************************
* Copyright (c) 2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.debug.internal.core;
import java.math.BigInteger;
import java.text.MessageFormat;
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.internal.core.model.CDebugTarget;
import org.eclipse.cdt.debug.internal.core.model.CExtendedMemoryBlock;
import org.eclipse.cdt.debug.internal.core.model.CStackFrame;
import org.eclipse.cdt.debug.internal.core.model.CThread;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock;
import org.eclipse.debug.internal.core.memory.IExtendedMemoryBlockRetrieval;
/**
* Implements the memory retrieval features based on the CDI model.
*/
public class CExtendedMemoryBlockRetrieval implements IExtendedMemoryBlockRetrieval {
/**
* Constructor for CExtendedMemoryBlockRetrieval.
*/
public CExtendedMemoryBlockRetrieval() {
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlockRetrieval#getExtendedMemoryBlock(java.lang.String, org.eclipse.debug.core.model.IDebugElement)
*/
public IExtendedMemoryBlock getExtendedMemoryBlock( String expression, IDebugElement selected ) throws DebugException {
String address = null;
if ( selected instanceof CStackFrame ) {
address = ((CStackFrame)selected).evaluateExpressionToString( expression );
}
else if ( selected instanceof CThread ) {
IStackFrame frame = ((CThread)selected).getTopStackFrame();
if ( frame instanceof CStackFrame ) {
address = ((CStackFrame)selected).evaluateExpressionToString( expression );
}
}
IDebugTarget target = selected.getDebugTarget();
if ( target instanceof CDebugTarget ) {
if ( address == null ) {
address = ((CDebugTarget)target).evaluateExpressionToString( expression );
}
if ( address != null ) {
try {
BigInteger a = ( address.startsWith( "0x" ) ) ? new BigInteger( address.substring( 2 ), 16 ) : new BigInteger( address ); //$NON-NLS-1$
return new CExtendedMemoryBlock( (CDebugTarget)target, expression, a );
}
catch( NumberFormatException e ) {
throw new DebugException( new Status( IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), DebugException.REQUEST_FAILED, MessageFormat.format( InternalDebugCoreMessages.getString( "CExtendedMemoryBlockRetrieval.0" ), new String[] { expression, address } ), null ) ); //$NON-NLS-1$
}
}
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlockRetrieval#getPaddedString()
*/
public String getPaddedString() {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#supportsStorageRetrieval()
*/
public boolean supportsStorageRetrieval() {
// TODO Auto-generated method stub
return true;
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#getMemoryBlock(long, long)
*/
public IMemoryBlock getMemoryBlock( long startAddress, long length ) throws DebugException {
// TODO Auto-generated method stub
return null;
}
}

View file

@ -15,3 +15,4 @@ CBreakpointManager.3=Delete breakpoint failed. Reason: {0}.
CBreakpointManager.4=Change breakpoint properties failed. Reason: {0}.
CBreakpointManager.5=Change breakpoint properties failed. Reason: {0}.
CGlobalVariableManager.0=Invalid global variables data.
CExtendedMemoryBlockRetrieval.0=Expression ''{0}'' evaluated to invalid address value: {1}.

View file

@ -83,6 +83,7 @@ import org.eclipse.cdt.debug.core.model.IRunToLine;
import org.eclipse.cdt.debug.core.sourcelookup.ICSourceLocator;
import org.eclipse.cdt.debug.internal.core.CBreakpointManager;
import org.eclipse.cdt.debug.internal.core.CExpressionTarget;
import org.eclipse.cdt.debug.internal.core.CExtendedMemoryBlockRetrieval;
import org.eclipse.cdt.debug.internal.core.CGlobalVariableManager;
import org.eclipse.cdt.debug.internal.core.CMemoryManager;
import org.eclipse.cdt.debug.internal.core.CRegisterManager;
@ -112,10 +113,12 @@ 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.IMemoryBlockRetrieval;
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;
import org.eclipse.debug.internal.core.memory.IExtendedMemoryBlockRetrieval;
/**
* Debug target for C/C++ debug model.
@ -209,8 +212,13 @@ public class CDebugTarget extends CDebugElement implements ICDebugTarget, ICDIEv
*/
private Preferences fPreferences = null;
/**
* The address factory of this target.
*/
private IAddressFactory fAddressFactory;
private CExtendedMemoryBlockRetrieval fMemoryBlockRetrieval;
/**
* Constructor for CDebugTarget.
*/
@ -232,6 +240,7 @@ public class CDebugTarget extends CDebugElement implements ICDebugTarget, ICDIEv
setRegisterManager( new CRegisterManager( this ) );
setBreakpointManager( new CBreakpointManager( this ) );
setGlobalVariableManager( new CGlobalVariableManager( this ) );
setMemoryBlockRetrieval( new CExtendedMemoryBlockRetrieval() );
initialize();
DebugPlugin.getDefault().getLaunchManager().addLaunchListener( this );
DebugPlugin.getDefault().getExpressionManager().addExpressionListener( this );
@ -848,6 +857,10 @@ public class CDebugTarget extends CDebugElement implements ICDebugTarget, ICDIEv
return getGlobalVariableManager();
if ( adapter.equals( ICDISession.class ) )
return getCDISession();
if ( adapter.equals( IExtendedMemoryBlockRetrieval.class ) )
return getMemoryBlockRetrieval();
if ( adapter.equals( IMemoryBlockRetrieval.class ) )
return getMemoryBlockRetrieval();
return super.getAdapter( adapter );
}
@ -1836,4 +1849,22 @@ public class CDebugTarget extends CDebugElement implements ICDebugTarget, ICDIEv
}
return fAddressFactory;
}
private CExtendedMemoryBlockRetrieval getMemoryBlockRetrieval() {
return fMemoryBlockRetrieval;
}
private void setMemoryBlockRetrieval( CExtendedMemoryBlockRetrieval memoryBlockRetrieval ) {
fMemoryBlockRetrieval = memoryBlockRetrieval;
}
public String evaluateExpressionToString( String expression ) throws DebugException {
try {
return getCDITarget().evaluateExpressionToString( expression );
}
catch( CDIException e ) {
targetRequestFailed( e.getMessage(), null );
}
return null;
}
}

View file

@ -0,0 +1,415 @@
/**********************************************************************
* Copyright (c) 2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.debug.internal.core.model;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashSet;
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.core.cdi.CDIException;
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.ICDIMemoryChangedEvent;
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.model.ICDIMemoryBlock;
import org.eclipse.cdt.debug.core.cdi.model.ICDIObject;
import org.eclipse.cdt.debug.core.model.IExecFileInfo;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
import org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock;
import org.eclipse.debug.internal.core.memory.MemoryByte;
/**
* Represents a memory block in the CDI model.
*/
public class CExtendedMemoryBlock extends CDebugElement implements IExtendedMemoryBlock, ICDIEventListener {
private class CMemoryByte extends MemoryByte {
/**
* Constructor for CMemoryByte.
*/
public CMemoryByte( byte value, byte flags ) {
this.value = value;
this.flags = flags;
}
/**
* Constructor for CMemoryByte.
*/
public CMemoryByte() {
}
}
/**
* The address expression this memory block is based on.
*/
private String fExpression;
/**
* The base address of this memory block.
*/
private BigInteger fBaseAddress;
/**
* The underlying CDI memory block.
*/
private ICDIMemoryBlock fCDIBlock;
/**
* The memory bytes values.
*/
private MemoryByte[] fBytes = null;
private HashSet fChanges = new HashSet();
/**
* Constructor for CExtendedMemoryBlock.
*/
public CExtendedMemoryBlock( CDebugTarget target, String expression, BigInteger baseAddress ) {
super( target );
fExpression = expression;
fBaseAddress = baseAddress;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock#getExpression()
*/
public String getExpression() throws DebugException {
return fExpression;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock#getBigBaseAddress()
*/
public BigInteger getBigBaseAddress() {
return fBaseAddress;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock#getAddressSize()
*/
public int getAddressSize() {
// TODO need a similar method for IAddress
return 4;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock#supportBaseAddressModification()
*/
public boolean supportBaseAddressModification() {
return true;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock#isMemoryChangesManaged()
*/
public boolean isMemoryChangesManaged() {
return true;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock#setBaseAddress(java.math.BigInteger)
*/
public void setBaseAddress( BigInteger address ) throws DebugException {
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock#getBytesFromOffset(long, long)
*/
public MemoryByte[] getBytesFromOffset( long offset, long length ) throws DebugException {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock#getBytesFromAddress(java.math.BigInteger, long)
*/
public MemoryByte[] getBytesFromAddress( BigInteger address, long length ) throws DebugException {
ICDIMemoryBlock cdiBlock = getCDIBlock();
if ( cdiBlock == null ||
cdiBlock.getStartAddress().compareTo( address ) > 0 ||
cdiBlock.getStartAddress().add( BigInteger.valueOf( cdiBlock.getLength() ) ).compareTo( address.add( BigInteger.valueOf( length ) ) ) < 0 ) {
synchronized( this ) {
byte[] bytes = null;
try {
cdiBlock = getCDIBlock();
if ( cdiBlock == null ||
cdiBlock.getStartAddress().compareTo( address ) > 0 ||
cdiBlock.getStartAddress().add( BigInteger.valueOf( cdiBlock.getLength() ) ).compareTo( address.add( BigInteger.valueOf( length ) ) ) < 0 ) {
if ( cdiBlock != null ) {
disposeCDIBlock();
fBytes = null;
}
setCDIBlock( createCDIBlock( address, length ) );
}
bytes = getCDIBlock().getBytes();
}
catch( CDIException e ) {
targetRequestFailed( e.getMessage(), null );
}
fBytes = new MemoryByte[bytes.length];
for ( int i = 0; i < bytes.length; ++i ) {
byte flags = MemoryByte.VALID;
if ( hasChanged( getRealBlockAddress().add( BigInteger.valueOf( i ) ) ) )
flags |= MemoryByte.CHANGED;
fBytes[i] = new CMemoryByte( bytes[i], flags );
}
}
}
MemoryByte[] result = new MemoryByte[0];
if ( fBytes != null ) {
int offset = address.subtract( getRealBlockAddress() ).intValue();
if ( offset >= 0 ) {
int size = ( fBytes.length - offset >= length ) ? (int)length : fBytes.length - offset;
if ( size > 0 ) {
result = new MemoryByte[size];
System.arraycopy( fBytes, offset, result, 0, size );
}
}
}
return result;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock#isBigEndian()
*/
public boolean isBigEndian() {
IExecFileInfo info = (IExecFileInfo)getDebugTarget().getAdapter( IExecFileInfo.class );
if ( info != null ) {
return info.isLittleEndian();
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock#enable()
*/
public void enable() {
ICDIMemoryBlock block = getCDIBlock();
if ( block != null ) {
block.setFrozen( false );
}
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock#disable()
*/
public void disable() {
ICDIMemoryBlock block = getCDIBlock();
if ( block != null ) {
block.setFrozen( true );
}
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock#isEnabled()
*/
public boolean isEnabled() {
ICDIMemoryBlock block = getCDIBlock();
if ( block != null ) {
return !block.isFrozen();
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock#delete()
*/
public void delete() {
fChanges.clear();
ICDIMemoryBlock cdiBlock = getCDIBlock();
if ( cdiBlock != null ) {
try {
((CDebugTarget)getDebugTarget()).getCDISession().getMemoryManager().removeBlock( cdiBlock );
}
catch( CDIException e ) {
CDebugCorePlugin.log( e );
}
fCDIBlock = null;
}
getCDISession().getEventManager().removeEventListener( this );
}
/*
* (non-Javadoc)
*
* @see org.eclipse.debug.internal.core.memory.IExtendedMemoryBlock#getMemoryBlockRetrieval()
*/
public IMemoryBlockRetrieval getMemoryBlockRetrieval() {
return (IMemoryBlockRetrieval)getDebugTarget().getAdapter( IMemoryBlockRetrieval.class );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.core.cdi.event.ICDIEventListener#handleDebugEvents(org.eclipse.cdt.debug.core.cdi.event.ICDIEvent[])
*/
public void handleDebugEvents( ICDIEvent[] events ) {
for( int i = 0; i < events.length; i++ ) {
ICDIEvent event = events[i];
ICDIObject source = event.getSource();
if ( source == null )
continue;
if ( source.getTarget().equals( getCDITarget() ) ) {
if ( event instanceof ICDIResumedEvent || event instanceof ICDIRestartedEvent ) {
resetChanges();
}
else if ( event instanceof ICDIMemoryChangedEvent ) {
if ( source instanceof ICDIMemoryBlock && source.equals( getCDIBlock() ) ) {
handleChangedEvent( (ICDIMemoryChangedEvent)event );
}
}
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.debug.core.model.IMemoryBlock#getStartAddress()
*/
public long getStartAddress() {
return 0;
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IMemoryBlock#getLength()
*/
public long getLength() {
return 0;
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IMemoryBlock#getBytes()
*/
public byte[] getBytes() throws DebugException {
return null;
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IMemoryBlock#supportsValueModification()
*/
public boolean supportsValueModification() {
return true;
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IMemoryBlock#setValue(long, byte[])
*/
public void setValue( long offset, byte[] bytes ) throws DebugException {
ICDIMemoryBlock block = getCDIBlock();
if ( block != null ) {
BigInteger base = getBigBaseAddress();
BigInteger real = getRealBlockAddress();
long realOffset = base.add( BigInteger.valueOf( offset ) ).subtract( real ).longValue();
try {
block.setValue( realOffset, bytes );
}
catch( CDIException e ) {
targetRequestFailed( e.getDetailMessage(), null );
}
}
}
private ICDIMemoryBlock createCDIBlock( BigInteger address, long length ) throws CDIException {
ICDIMemoryBlock block = ((CDebugTarget)getDebugTarget()).getCDISession().getMemoryManager().createMemoryBlock( address.toString(), (int)length );
getCDISession().getEventManager().addEventListener( this );
return block;
}
private void disposeCDIBlock() {
ICDIMemoryBlock block = getCDIBlock();
if ( block != null ) {
try {
((CDebugTarget)getDebugTarget()).getCDISession().getMemoryManager().removeBlock( block );
}
catch( CDIException e ) {
DebugPlugin.log( e );
}
setCDIBlock( null );
getCDISession().getEventManager().removeEventListener( this );
}
}
private ICDIMemoryBlock getCDIBlock() {
return fCDIBlock;
}
private void setCDIBlock( ICDIMemoryBlock cdiBlock ) {
fCDIBlock = cdiBlock;
}
private BigInteger getRealBlockAddress() {
ICDIMemoryBlock block = getCDIBlock();
return ( block != null ) ? block.getStartAddress() : BigInteger.ZERO;
}
private long getBlockSize() {
ICDIMemoryBlock block = getCDIBlock();
return ( block != null ) ? block.getLength() : 0;
}
private void handleChangedEvent( ICDIMemoryChangedEvent event ) {
ICDIMemoryBlock block = getCDIBlock();
if ( block != null && fBytes != null ) {
MemoryByte[] memBytes = (MemoryByte[])fBytes.clone();
try {
BigInteger start = getRealBlockAddress();
long length = block.getLength();
byte[] newBytes = block.getBytes();
BigInteger[] addresses = event.getAddresses();
saveChanges( addresses );
for ( int i = 0; i < addresses.length; ++i ) {
fChanges.add( addresses[i] );
if ( addresses[i].compareTo( start ) >= 0 && addresses[i].compareTo( start.add( BigInteger.valueOf( length ) ) ) < 0 ) {
int index = addresses[i].subtract( start ).intValue();
if ( index >= 0 && index < memBytes.length && index < newBytes.length ) {
memBytes[index].flags |= MemoryByte.CHANGED;
memBytes[index].value = newBytes[index];
}
}
}
fBytes = memBytes;
fireChangeEvent( DebugEvent.CONTENT );
}
catch( CDIException e ) {
DebugPlugin.log( e );
}
}
}
private void saveChanges( BigInteger[] addresses ) {
fChanges.addAll( Arrays.asList( addresses ) );
}
private boolean hasChanged( BigInteger address ) {
return fChanges.contains( address );
}
private void resetChanges() {
if ( fBytes != null ) {
BigInteger[] changes = (BigInteger[])fChanges.toArray( new BigInteger[fChanges.size()] );
for ( int i = 0; i < changes.length; ++i ) {
BigInteger real = getRealBlockAddress();
if ( real.compareTo( changes[i] ) <= 0 && real.add( BigInteger.valueOf( getBlockSize() ) ).compareTo( changes[i] ) > 0 ) {
int index = changes[i].subtract( real ).intValue();
if ( index >= 0 && index < fBytes.length ) {
fBytes[index].flags &= ~MemoryByte.CHANGED;
}
}
}
}
fChanges.clear();
fireChangeEvent( DebugEvent.CONTENT );
}
}

View file

@ -52,6 +52,7 @@ 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.IMemoryBlockRetrieval;
import org.eclipse.debug.core.model.IStackFrame;
/**
@ -839,6 +840,9 @@ public class CThread extends CDebugElement implements ICThread, IRestart, IResum
// do nothing
}
}
if ( adapter == IMemoryBlockRetrieval.class ) {
return getDebugTarget().getAdapter( adapter );
}
return super.getAdapter( adapter );
}