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:
parent
4d45b0a3c4
commit
de03bba29b
2 changed files with 141 additions and 70 deletions
|
@ -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,9 +57,12 @@ 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>();
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private boolean isEnabled;
|
private boolean isEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,7 +82,8 @@ 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() {
|
||||||
|
@ -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,47 +442,18 @@ 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
|
|
||||||
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.
|
/* Writes an array of bytes to memory.
|
||||||
|
@ -440,15 +474,50 @@ 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -240,19 +240,19 @@ 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;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point, we only resolved the requested memory block
|
* At this point, we only resolved the requested memory block
|
||||||
|
@ -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$
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue