1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Management of memory delats between debugger steps.

This commit is contained in:
Francois Chouinard 2007-10-12 02:41:05 +00:00
parent 4d45b0a3c4
commit de03bba29b
2 changed files with 141 additions and 70 deletions

View file

@ -9,6 +9,8 @@
* Wind River Systems - initial API and implementation * Wind River Systems - initial API and implementation
* Ericsson Communication - upgrade IF to IMemoryBlockExtension * Ericsson Communication - upgrade IF to IMemoryBlockExtension
* Ericsson Communication - added support for 64 bit processors * Ericsson Communication - added support for 64 bit processors
* Ericsson Communication - added support for changed bytes
* Ericsson Communication - better management of exceptions
*******************************************************************************/ *******************************************************************************/
package org.eclipse.dd.dsf.debug.model; package org.eclipse.dd.dsf.debug.model;
@ -19,11 +21,14 @@ import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.utils.Addr64; import org.eclipse.cdt.utils.Addr64;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.PlatformObject; import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.core.runtime.Status;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.Query;
import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.DMContexts;
import org.eclipse.dd.dsf.debug.DsfDebugPlugin;
import org.eclipse.dd.dsf.debug.service.IMemory; import org.eclipse.dd.dsf.debug.service.IMemory;
import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IRunControl;
import org.eclipse.dd.dsf.debug.service.IMemory.MemoryChangedEvent; import org.eclipse.dd.dsf.debug.service.IMemory.MemoryChangedEvent;
@ -52,10 +57,13 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
private final String fModelId; private final String fModelId;
private final String fExpression; private final String fExpression;
protected BigInteger fBaseAddress; protected BigInteger fBaseAddress;
protected long fLength; protected int fLength;
private MemoryByte[] fBlock;
private ArrayList<Object> fConnections = new ArrayList<Object>(); private ArrayList<Object> fConnections = new ArrayList<Object>();
private boolean isEnabled;
@SuppressWarnings("unused")
private boolean isEnabled;
/** /**
* Constructor. * Constructor.
@ -74,8 +82,9 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
fModelId = modelId; fModelId = modelId;
fExpression = expression; fExpression = expression;
fBaseAddress = address; fBaseAddress = address;
fLength = length; fLength = (int) length;
fBlock = null;
try { try {
fRetrieval.getExecutor().execute(new Runnable() { fRetrieval.getExecutor().execute(new Runnable() {
public void run() { public void run() {
@ -160,7 +169,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
* @see org.eclipse.debug.core.model.IMemoryBlock#supportsValueModification() * @see org.eclipse.debug.core.model.IMemoryBlock#supportsValueModification()
*/ */
public boolean supportsValueModification() { public boolean supportsValueModification() {
// return fDebugTarget.supportsValueModification(this); // TODO: return fDebugTarget.supportsValueModification(this);
return true; return true;
} }
@ -217,7 +226,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getAddressSize() * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getAddressSize()
*/ */
public int getAddressSize() throws DebugException { public int getAddressSize() throws DebugException {
// // TODO: // TODO:
// try { // try {
// return fDebugTarget.getAddressSize(); // return fDebugTarget.getAddressSize();
// } catch (CoreException e) { // } catch (CoreException e) {
@ -238,9 +247,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#supportsChangeManagement() * @see org.eclipse.debug.core.model.IMemoryBlockExtension#supportsChangeManagement()
*/ */
public boolean supportsChangeManagement() { public boolean supportsChangeManagement() {
// TODO: UI is a bit lazy. Implement change management ourselves. return true;
// return true;
return false;
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -261,9 +268,65 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBytesFromAddress(java.math.BigInteger, long) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBytesFromAddress(java.math.BigInteger, long)
*/ */
public MemoryByte[] getBytesFromAddress(BigInteger address, long units) throws DebugException { public MemoryByte[] getBytesFromAddress(BigInteger address, long units) throws DebugException {
fLength = units;
MemoryByte[] block = fetchMemoryBlock(address, units); MemoryByte[] block = fetchMemoryBlock(address, units);
return block; int newLength = (block != null) ? block.length : 0;
// Flag the changed bytes
if (fBlock != null && newLength > 0) {
int offset = fBaseAddress.compareTo(address);
switch (offset) {
case -1:
{
offset = -offset;
int length = Math.min(fLength - offset, newLength);
for (int i = 0; i < length; i += 4) {
boolean changed = false;
for (int j = i; j < (i + 4) && j < length; j++) {
block[j].setFlags(fBlock[offset + j].getFlags());
if (block[j].getValue() != fBlock[offset + j].getValue())
changed = true;
}
if (changed)
for (int j = i; j < (i + 4) && j < length; j++) {
block[j].setHistoryKnown(true);
block[j].setChanged(true);
}
}
break;
}
case 0:
case 1:
{
int length = Math.min(newLength - offset, fLength);
for (int i = 0; i < length; i += 4) {
boolean changed = false;
for (int j = i; j < (i + 4) && j < length; j++) {
block[offset + j].setFlags(fBlock[j].getFlags());
if (block[offset + j].getValue() != fBlock[j].getValue())
changed = true;
}
if (changed)
for (int j = i; j < (i + 4) && j < length; j++) {
block[offset + j].setHistoryKnown(true);
block[offset + j].setChanged(true);
}
}
break;
}
default:
break;
}
}
// Update the internal state
fBlock = block;
fBaseAddress = address;
fLength = newLength;
return fBlock;
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -319,7 +382,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
} }
}); });
} catch (RejectedExecutionException e) { } catch (RejectedExecutionException e) {
// Session is shut down. // Session is down.
} }
} }
@ -338,9 +401,9 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
return 1; return 1;
} }
// //////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Helper functions // Helper functions
// //////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
/* /*
* The real thing. Since the original call is synchronous (from a platform * The real thing. Since the original call is synchronous (from a platform
@ -379,50 +442,21 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
} }
}; };
fRetrieval.getExecutor().execute(query); fRetrieval.getExecutor().execute(query);
try {
try {
return query.get(); return query.get();
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.out.println("Interrupted Exception"); //$NON-NLS-1$ throw new DebugException(new Status(IStatus.ERROR,
DsfDebugPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR,
"Error reading memory block (InterruptedException)", e)); //$NON-NLS-1$
} catch (ExecutionException e) { } catch (ExecutionException e) {
System.out.println("Execution Exception"); //$NON-NLS-1$ throw new DebugException(new Status(IStatus.ERROR,
DsfDebugPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR,
"Error reading memory block (ExecutionException)", e)); //$NON-NLS-1$
} }
return null;
} }
@DsfServiceEventHandler /* Writes an array of bytes to memory.
public void eventDispatched(MemoryChangedEvent e) {
// Find the container of the event
IContainerDMContext eventContext = DMContexts.getAncestorOfType(e.getContext(), IContainerDMContext.class);
if (eventContext == null) {
return;
}
// Find the container of the block
IContainerDMContext blockContext = DMContexts.getAncestorOfType(fRetrieval.getContext(), IContainerDMContext.class);
if (blockContext == null) {
// Should not happen: throw an exception
return;
}
// Check if we are in the same address space
if (eventContext != blockContext) {
return;
}
IAddress[] addresses = e.getAddresses();
for (int i = 0; i < addresses.length; i++)
handleMemoryChange(addresses[i].getValue());
}
@DsfServiceEventHandler
public void eventDispatched(IRunControl.ISuspendedDMEvent e) {
// TODO: Check if we are in the right context
handleMemoryChange(BigInteger.ZERO);
}
/* Writes an array of bytes to memory.
* *
* @param offset * @param offset
* @param bytes * @param bytes
@ -440,17 +474,52 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
public void run() { public void run() {
memoryService.setMemory( memoryService.setMemory(
fRetrieval.getContext(), address, offset, word_size, bytes.length, bytes, fRetrieval.getContext(), address, offset, word_size, bytes.length, bytes,
new RequestMonitor(fRetrieval.getExecutor(), null) { new RequestMonitor(fRetrieval.getExecutor(), null));
@Override
protected void handleOK() {
// handleMemoryChange(fBaseAddress);
}
});
} }
}); });
} }
} }
///////////////////////////////////////////////////////////////////////////
// Event Handlers
///////////////////////////////////////////////////////////////////////////
@DsfServiceEventHandler
public void eventDispatched(IRunControl.ISuspendedDMEvent e) {
// Clear the "Changed" flags after each run/resume/step
for (int i = 0; i < fLength; i++)
fBlock[i].setChanged(false);
// Generate the MemoryChangedEvents
handleMemoryChange(BigInteger.ZERO);
}
@DsfServiceEventHandler
public void eventDispatched(MemoryChangedEvent e) {
// Find the container of the event
IContainerDMContext eventContext = DMContexts.getAncestorOfType(e.getContext(), IContainerDMContext.class);
if (eventContext == null) {
return;
}
// Find the container of the block
IContainerDMContext blockContext = DMContexts.getAncestorOfType(fRetrieval.getContext(), IContainerDMContext.class);
if (blockContext == null) {
return;
}
// Check if we are in the same address space
if (eventContext != blockContext) {
return;
}
IAddress[] addresses = e.getAddresses();
for (int i = 0; i < addresses.length; i++)
handleMemoryChange(addresses[i].getValue());
}
/** /**
* @param address * @param address
* @param length * @param length

View file

@ -240,18 +240,18 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl
dmc = (IDMContext<?>)((IAdaptable)context).getAdapter(IDMContext.class); dmc = (IDMContext<?>)((IAdaptable)context).getAdapter(IDMContext.class);
} }
// TODO: throw an exception
if (dmc == null) { if (dmc == null) {
return null; return null;
} }
// Update the DMC
// Update the DMC
fContext = dmc; fContext = dmc;
// Resolve the expression // Resolve the expression
blockAddress = resolveMemoryAddress(fContext, expression); blockAddress = resolveMemoryAddress(fContext, expression);
if (blockAddress == null) if (blockAddress == null) {
// TODO: throw an exception
return null; return null;
}
} }
/* /*
@ -317,13 +317,15 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl
// The happy case // The happy case
return query.get(); return query.get();
} catch (InterruptedException e) { } catch (InterruptedException e) {
// TODO: throw an exception throw new DebugException(new Status(IStatus.ERROR,
} catch (ExecutionException e) { DsfDebugPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR,
// TODO: throw an exception "Error evaluating memory address (InterruptedException).", e)); //$NON-NLS-1$
}
// The error case } catch (ExecutionException e) {
return null; throw new DebugException(new Status(IStatus.ERROR,
DsfDebugPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR,
"Error evaluating memory address (ExecutionException).", e)); //$NON-NLS-1$
}
} }
} }