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

Committing patches for bugs 159946 (disassembly) and 214546 (memory monitor persistence).

This commit is contained in:
Francois Chouinard 2008-03-01 20:21:08 +00:00
parent 90f4dc4c71
commit 8868398cc9
25 changed files with 1708 additions and 43 deletions

View file

@ -58,6 +58,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
private BigInteger fBlockAddress; private BigInteger fBlockAddress;
private int fLength; private int fLength;
private int fWordSize;
private MemoryByte[] fBlock; private MemoryByte[] fBlock;
private ArrayList<Object> fConnections = new ArrayList<Object>(); private ArrayList<Object> fConnections = new ArrayList<Object>();
@ -72,9 +73,10 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
* @param modelId - * @param modelId -
* @param expression - the displayed expression in the UI * @param expression - the displayed expression in the UI
* @param address - the actual memory block start address * @param address - the actual memory block start address
* @param length - the memory block length (could be 0) * @param word_size - the number of bytes per address
* @param length - the requested block length (could be 0)
*/ */
DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, String modelId, String expression, BigInteger address, long length) { DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, String modelId, String expression, BigInteger address, int word_size, long length) {
fLaunch = retrieval.getLaunch(); fLaunch = retrieval.getLaunch();
fDebugTarget = retrieval.getDebugTarget(); fDebugTarget = retrieval.getDebugTarget();
@ -85,6 +87,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
// Current block information // Current block information
fBlockAddress = address; fBlockAddress = address;
fWordSize = word_size;
fLength = (int) length; fLength = (int) length;
fBlock = null; fBlock = null;
@ -413,7 +416,6 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
// For the IAddress interface // For the IAddress interface
final Addr64 address = new Addr64(bigAddress); final Addr64 address = new Addr64(bigAddress);
final int word_size = 1;
// Use a Query to synchronize the downstream calls // Use a Query to synchronize the downstream calls
Query<MemoryByte[]> query = new Query<MemoryByte[]>() { Query<MemoryByte[]> query = new Query<MemoryByte[]>() {
@ -423,7 +425,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
if (memoryService != null) { if (memoryService != null) {
// Go for it // Go for it
memoryService.getMemory( memoryService.getMemory(
fRetrieval.getContext(), address, 0, word_size, (int) length, fRetrieval.getContext(), address, 0, fWordSize, (int) length,
new DataRequestMonitor<MemoryByte[]>(fRetrieval.getExecutor(), drm) { new DataRequestMonitor<MemoryByte[]>(fRetrieval.getExecutor(), drm) {
@Override @Override
protected void handleOK() { protected void handleOK() {
@ -460,9 +462,8 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
// For the IAddress interface // For the IAddress interface
final Addr64 address = new Addr64(fBaseAddress); final Addr64 address = new Addr64(fBaseAddress);
final int word_size = 1;
// Use a Query to synchronise the downstream calls // Use a Query to synchronize the downstream calls
Query<MemoryByte[]> query = new Query<MemoryByte[]>() { Query<MemoryByte[]> query = new Query<MemoryByte[]>() {
@Override @Override
protected void execute(final DataRequestMonitor<MemoryByte[]> drm) { protected void execute(final DataRequestMonitor<MemoryByte[]> drm) {
@ -470,7 +471,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
if (memoryService != null) { if (memoryService != null) {
// Go for it // Go for it
memoryService.setMemory( memoryService.setMemory(
fRetrieval.getContext(), address, offset, word_size, bytes.length, bytes, fRetrieval.getContext(), address, offset, fWordSize, bytes.length, bytes,
new RequestMonitor(fRetrieval.getExecutor(), null)); new RequestMonitor(fRetrieval.getExecutor(), null));
} }

View file

@ -15,8 +15,11 @@
package org.eclipse.dd.dsf.debug.model; package org.eclipse.dd.dsf.debug.model;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.PlatformObject; import org.eclipse.core.runtime.PlatformObject;
@ -36,8 +39,12 @@ import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext;
import org.eclipse.dd.dsf.service.DsfServices; import org.eclipse.dd.dsf.service.DsfServices;
import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.service.IDsfService;
import org.eclipse.dd.dsf.service.DsfSession.SessionEndedListener;
import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IMemoryBlock; import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.core.model.IMemoryBlockExtension; import org.eclipse.debug.core.model.IMemoryBlockExtension;
@ -45,6 +52,10 @@ import org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.InvalidSyntaxException;
import org.osgi.util.tracker.ServiceTracker; import org.osgi.util.tracker.ServiceTracker;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/** /**
* Implementation of memory access API of the Eclipse standard debug model. * Implementation of memory access API of the Eclipse standard debug model.
@ -62,15 +73,24 @@ import org.osgi.util.tracker.ServiceTracker;
* code will still be functional after some trivial adjustments. * code will still be functional after some trivial adjustments.
* *
*/ */
public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBlockRetrievalExtension public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBlockRetrievalExtension, SessionEndedListener
{ {
private final String fModelId; private final String fModelId;
private final DsfSession fSession; private final DsfSession fSession;
private final DsfExecutor fExecutor; private final DsfExecutor fExecutor;
private IMemoryDMContext fContext; private final IMemoryDMContext fContext;
private final String fContextString;
private final ServiceTracker fMemoryServiceTracker; private final ServiceTracker fMemoryServiceTracker;
private final ServiceTracker fExpressionServiceTracker; private final ServiceTracker fExpressionServiceTracker;
private final ILaunchConfiguration fLaunchConfig;
private final ILaunch fLaunch;
private final IDebugTarget fDebugTarget;
private final boolean fSupportsValueModification;
private final boolean fSupportBaseAddressModification;
private final int fAddressSize;
private final int fWordSize; // Number of bytes per address
/** /**
* Constructor * Constructor
* *
@ -78,10 +98,22 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl
* @param dmc * @param dmc
* @throws DebugException * @throws DebugException
*/ */
public DsfMemoryBlockRetrieval(String modelId, IMemoryDMContext dmc) throws DebugException { public DsfMemoryBlockRetrieval(String modelId, ILaunchConfiguration config, IMemoryDMContext dmc) throws DebugException {
// DSF stuff
fModelId = modelId; fModelId = modelId;
fContext = dmc; fContext = dmc;
// FIXME: Currently memory contexts are differentiated by sessionID
// so there is no way to guarantee the memory blocks will be reinstated
// in the correct memory space.
// Need a way to create deterministically the context ID from a unique
// target, ideally from the launch configuration (or derived from it).
// For the time being, just put some constant. This will work until we
// support multiple targets in the same launch.
// fContextString = fContext.toString();
fContextString = "Context string"; //$NON-NLS-1$
fSession = DsfSession.getSession(fContext.getSessionId()); fSession = DsfSession.getSession(fContext.getSessionId());
if (fSession == null) { if (fSession == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
@ -124,11 +156,160 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl
"Error creating service filter.", e)); //$NON-NLS-1$ "Error creating service filter.", e)); //$NON-NLS-1$
} }
fExpressionServiceTracker.open(); fExpressionServiceTracker.open();
// Launch configuration information
fLaunchConfig = config;
fLaunch = null;
fDebugTarget = null;
fAddressSize = 4; // Get this from the launch configuration
fWordSize = 1; // Get this from the launch configuration
fSupportsValueModification = true; // Get this from the launch configuration
fSupportBaseAddressModification = false; // Get this from the launch configuration
// So we are notified on exit and can save the memory blocks
DsfSession.addSessionEndedListener(this);
} }
// //////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Memory monitors persistence
///////////////////////////////////////////////////////////////////////////
/*
* In the launch configuration file, the memory block entry is structured
* as follows (note: this differs from CDI):
*
* <stringAttribute
* key="org.eclipse.dsf.launch.MEMORY_BLOCKS"
* value="<?xml version="1.0" encoding="UTF-8" standalone="no"?>
* <memoryBlockExpressionList context=[memory context ID]>
* <memoryBlockExpression label=[monitor label] address=[base address]/>
* <memoryBlockExpression ...>
* ...
* </memoryBlockExpressionList>
* ...
* <memoryBlockExpressionList context=...>
* ...
* </memoryBlockExpressionList>"
* />
*/
//-------------------------------------------------------------------------
// Memory blocks memento tags
//-------------------------------------------------------------------------
// These 2 really belong in the DSF launch configuration class...
private static final String DSF_LAUNCH_ID = "org.eclipse.dsf.launch"; //$NON-NLS-1$
private static final String ATTR_DEBUGGER_MEMORY_BLOCKS = DSF_LAUNCH_ID + ".MEMORY_BLOCKS"; //$NON-NLS-1$
private static final String MEMORY_BLOCK_EXPRESSION_LIST = "memoryBlockExpressionList"; //$NON-NLS-1$
private static final String ATTR_EXPRESSION_LIST_CONTEXT = "context"; //$NON-NLS-1$
private static final String MEMORY_BLOCK_EXPRESSION = "memoryBlockExpression"; //$NON-NLS-1$
private static final String ATTR_MEMORY_BLOCK_EXPR_LABEL = "label"; //$NON-NLS-1$
private static final String ATTR_MEMORY_BLOCK_EXPR_ADDRESS = "address"; //$NON-NLS-1$
//-------------------------------------------------------------------------
// Install persisted memory monitors
//-------------------------------------------------------------------------
/**
* Restore the memory monitors from the memento in the launch configuration
*/
public void initialize() {
try {
final String memento = fLaunchConfig.getAttribute(ATTR_DEBUGGER_MEMORY_BLOCKS, ""); //$NON-NLS-1$
if (memento != null && memento.trim().length() != 0) {
// Submit the runnable to install the monitors on dispatch thread.
getExecutor().submit(new Runnable() {
public void run() {
try {
createBlocksFromConfiguration(memento);
} catch (CoreException e) {
DsfDebugPlugin.getDefault().getLog().log(e.getStatus());
}
}
});
}
} catch (CoreException e) {
DsfDebugPlugin.getDefault().getLog().log(e.getStatus());
}
}
private void createBlocksFromConfiguration(String memento) throws CoreException {
// Parse the memento and validate its type
Element root = DebugPlugin.parseDocument(memento);
if (!root.getNodeName().equalsIgnoreCase(MEMORY_BLOCK_EXPRESSION_LIST)) {
IStatus status = new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, DebugPlugin.INTERNAL_ERROR,
"Memory monitor initialization: invalid memento", null);//$NON-NLS-1$
throw new CoreException(status);
}
// Process the block list specific to this memory context
// FIXME: We only process the first entry...
if (root.getAttribute(ATTR_EXPRESSION_LIST_CONTEXT).equals(fContextString)) {
List<IMemoryBlock> blocks = new ArrayList<IMemoryBlock>();
NodeList expressionList = root.getChildNodes();
int length = expressionList.getLength();
for (int i = 0; i < length; ++i) {
Node node = expressionList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element entry = (Element) node;
if (entry.getNodeName().equalsIgnoreCase(MEMORY_BLOCK_EXPRESSION)) {
String label = entry.getAttribute(ATTR_MEMORY_BLOCK_EXPR_LABEL);
String address = entry.getAttribute(ATTR_MEMORY_BLOCK_EXPR_ADDRESS);
BigInteger blockAddress = new BigInteger(address);
DsfMemoryBlock block = new DsfMemoryBlock(this, fModelId, label, blockAddress, fWordSize, 0);
blocks.add(block);
}
}
}
DebugPlugin.getDefault().getMemoryBlockManager().addMemoryBlocks( blocks.toArray(new IMemoryBlock[blocks.size()]));
}
}
/**
* On session exit, save the memory blocks in the launch configuration
*/
public void sessionEnded(DsfSession session) {
DsfSession.removeSessionEndedListener(this);
saveMemoryBlocks();
}
// FIXME: Each retrieval overwrites the previous one :-(
// FIXME: Racing condition :-( - synchronize on launch config enough?
// FIXME: Make it a Job?
public void saveMemoryBlocks() {
try {
ILaunchConfigurationWorkingCopy wc = fLaunchConfig.getWorkingCopy();
wc.setAttribute(ATTR_DEBUGGER_MEMORY_BLOCKS, getMemento());
wc.doSave();
}
catch( CoreException e ) {
DsfDebugPlugin.getDefault().getLog().log(e.getStatus());
}
}
public String getMemento() throws CoreException {
IMemoryBlock[] blocks = DebugPlugin.getDefault().getMemoryBlockManager().getMemoryBlocks(this);
Document document = DebugPlugin.newDocument();
Element expressionList = document.createElement(MEMORY_BLOCK_EXPRESSION_LIST);
expressionList.setAttribute(ATTR_EXPRESSION_LIST_CONTEXT, fContextString);
for (IMemoryBlock block : blocks) {
if (block instanceof IMemoryBlockExtension) {
IMemoryBlockExtension memoryBlock = (IMemoryBlockExtension) block;
Element expression = document.createElement(MEMORY_BLOCK_EXPRESSION);
expression.setAttribute(ATTR_MEMORY_BLOCK_EXPR_LABEL, memoryBlock.getExpression());
expression.setAttribute(ATTR_MEMORY_BLOCK_EXPR_ADDRESS, memoryBlock.getBigBaseAddress().toString());
expressionList.appendChild(expression);
}
}
document.appendChild(expressionList);
return DebugPlugin.serializeDocument(document);
}
///////////////////////////////////////////////////////////////////////////
// Accessors // Accessors
// //////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
public DsfSession getSession() { public DsfSession getSession() {
return fSession; return fSession;
@ -146,38 +327,37 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl
return fMemoryServiceTracker; return fMemoryServiceTracker;
} }
// //////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Launch/Target specific information // Launch/Target specific information
// To be completed ///////////////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////////////
public ILaunch getLaunch() { public ILaunch getLaunch() {
return null; return fLaunch;
} }
public IDebugTarget getDebugTarget() { public IDebugTarget getDebugTarget() {
return null; return fDebugTarget;
} }
public int getAddressSize() { public int getAddressSize() {
return 4; return fAddressSize;
} }
public int getAddressableSize() { public int getAddressableSize() {
return 1; return fWordSize;
} }
public boolean supportsValueModification() { public boolean supportsValueModification() {
return true; return fSupportsValueModification;
} }
public boolean supportBaseAddressModification() { public boolean supportBaseAddressModification() {
return false; return fSupportBaseAddressModification;
} }
// //////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// IMemoryBlockRetrieval - obsoleted by IMemoryBlockRetrievalExtension // IMemoryBlockRetrieval - obsoleted by IMemoryBlockRetrievalExtension
// //////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
/* /*
* (non-Javadoc) * (non-Javadoc)
@ -198,12 +378,12 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl
// The expression to display in the rendering tab (in hex by convention) // The expression to display in the rendering tab (in hex by convention)
// Put here for the sake of completeness (not used with IMemoryBlockExtension) // Put here for the sake of completeness (not used with IMemoryBlockExtension)
String expression = "0x" + Long.toHexString(startAddress); //$NON-NLS-1$ String expression = "0x" + Long.toHexString(startAddress); //$NON-NLS-1$
return new DsfMemoryBlock(this, fModelId, expression, BigInteger.valueOf(startAddress), length); return new DsfMemoryBlock(this, fModelId, expression, BigInteger.valueOf(startAddress), fWordSize, length);
} }
// //////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// IMemoryBlockRetrievalExtension // IMemoryBlockRetrievalExtension
// //////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
/* /*
* (non-Javadoc) * (non-Javadoc)
@ -277,12 +457,12 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl
* the memory request cache should save the day. * the memory request cache should save the day.
*/ */
return new DsfMemoryBlock(this, fModelId, expression, blockAddress, 0); return new DsfMemoryBlock(this, fModelId, expression, blockAddress, fWordSize, 0);
} }
// //////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Helper functions // Helper functions
// //////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
private BigInteger resolveMemoryAddress(final IDMContext idmContext, final String expression) throws DebugException { private BigInteger resolveMemoryAddress(final IDMContext idmContext, final String expression) throws DebugException {

View file

@ -0,0 +1,91 @@
/*******************************************************************************
* Copyright (c) 2008 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug.service;
import java.math.BigInteger;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.service.IDsfService;
/**
* Disassembly service interface
*/
public interface IDisassembly extends IDsfService {
public interface IDisassemblyDMContext extends IDMContext {}
/**
* Gets the disassembled code from an address range.
* If [startAddress] == null, disassemble from the instruction pointer.
*
* @param context Context of the disassembly code
* @param startAddress Beginning address
* @param endAddress End address
* @param drm Disassembled code
*/
public void getInstructions(
IDisassemblyDMContext context,
BigInteger startAddress,
BigInteger endAddress,
DataRequestMonitor<IInstruction[]> drm);
/**
* Gets the disassembled code from a file location.
* If [lines] == -1, the whole function is disassembled.
*
* @param context Context of the disassembly code
* @param filename File to disassemble
* @param linenum Line number within the file
* @param lines Number of lines of disassembled code to produce
* @param drm Disassembled code
*/
public void getInstructions(
IDisassemblyDMContext context,
String filename,
int linenum,
int lines,
DataRequestMonitor<IInstruction[]> drm);
/**
* Gets the mixed disassembled code from an address range.
* If [startAddress] == null, disassemble from the instruction pointer.
*
* @param context Context of the disassembly code
* @param startAddress Beginning address
* @param endAddress End address
* @param drm Disassembled code
*/
public void getMixedInstructions(
IDisassemblyDMContext context,
BigInteger startAddress,
BigInteger endAddress,
DataRequestMonitor<IMixedInstruction[]> drm);
/**
* Gets the mixed disassembled code from a file location.
* If [lines] == -1, the whole function is disassembled.
*
* @param context Context of the disassembly code
* @param filename File to disassemble
* @param linenum Line number within the file
* @param lines Number of lines of disassembled code to produce
* @param drm Disassembled code
*/
public void getMixedInstructions(
IDisassemblyDMContext context,
String filename,
int linenum,
int lines,
DataRequestMonitor<IMixedInstruction[]> drm);
}

View file

@ -0,0 +1,51 @@
/*******************************************************************************
* Copyright (c) 2008 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug.service;
import java.math.BigInteger;
/**
* Represents an assembly instruction
*/
public interface IInstruction {
/**
* @return the instruction address.
*/
BigInteger getAdress();
/**
* @return the function name.
*/
String getFuntionName();
/**
* @return the offset of this machine instruction
*/
long getOffset();
/**
* @return the instruction.
*/
String getInstruction();
/**
* @return the opcode
*/
String getOpcode();
/**
* @return any arguments to the instruction
*/
String getArgs();
}

View file

@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2008 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug.service;
/**
* Represents the assembly instruction(s) corresponding to a source line
*/
public interface IMixedInstruction {
/**
* @return the file name
*/
String getFileName();
/**
* @return the line Number.
*/
int getLineNumber();
/**
* @return the array of instruction.
*/
IInstruction[] getInstructions();
}

View file

@ -88,7 +88,7 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate
} }
} }
private void launchLocalDebugSession( ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException { private void launchLocalDebugSession( final ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException {
if ( monitor.isCanceled() ) { if ( monitor.isCanceled() ) {
return; return;
} }
@ -154,8 +154,9 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate
GDBControl gdbControl = tracker.getService(GDBControl.class); GDBControl gdbControl = tracker.getService(GDBControl.class);
if (gdbControl != null) { if (gdbControl != null) {
IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval(
GDB_DEBUG_MODEL_ID, (IMemoryDMContext)gdbControl.getControlDMContext()); GDB_DEBUG_MODEL_ID, config, (IMemoryDMContext)gdbControl.getControlDMContext());
launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval);
((DsfMemoryBlockRetrieval) memRetrieval).initialize();
} }
tracker.dispose(); tracker.dispose();
return null; return null;

View file

@ -33,6 +33,7 @@ import org.eclipse.dd.mi.service.CSourceLookup;
import org.eclipse.dd.mi.service.ExpressionService; import org.eclipse.dd.mi.service.ExpressionService;
import org.eclipse.dd.mi.service.MIBreakpoints; import org.eclipse.dd.mi.service.MIBreakpoints;
import org.eclipse.dd.mi.service.MIBreakpointsManager; import org.eclipse.dd.mi.service.MIBreakpointsManager;
import org.eclipse.dd.mi.service.MIDisassembly;
import org.eclipse.dd.mi.service.MIMemory; import org.eclipse.dd.mi.service.MIMemory;
import org.eclipse.dd.mi.service.MIModules; import org.eclipse.dd.mi.service.MIModules;
import org.eclipse.dd.mi.service.MIRegisters; import org.eclipse.dd.mi.service.MIRegisters;
@ -121,6 +122,10 @@ public class LaunchSequence extends Sequence {
public void execute(RequestMonitor requestMonitor) { public void execute(RequestMonitor requestMonitor) {
new MIRegisters(fSession).initialize(requestMonitor); new MIRegisters(fSession).initialize(requestMonitor);
}}, }},
new Step() { @Override
public void execute(RequestMonitor requestMonitor) {
new MIDisassembly(fSession).initialize(requestMonitor);
}},
/* /*
* If needed, insert breakpoint at main and run to it. * If needed, insert breakpoint at main and run to it.
*/ */

View file

@ -24,6 +24,7 @@ import org.eclipse.dd.mi.service.CSourceLookup;
import org.eclipse.dd.mi.service.ExpressionService; import org.eclipse.dd.mi.service.ExpressionService;
import org.eclipse.dd.mi.service.MIBreakpoints; import org.eclipse.dd.mi.service.MIBreakpoints;
import org.eclipse.dd.mi.service.MIBreakpointsManager; import org.eclipse.dd.mi.service.MIBreakpointsManager;
import org.eclipse.dd.mi.service.MIDisassembly;
import org.eclipse.dd.mi.service.MIMemory; import org.eclipse.dd.mi.service.MIMemory;
import org.eclipse.dd.mi.service.MIModules; import org.eclipse.dd.mi.service.MIModules;
import org.eclipse.dd.mi.service.MIRegisters; import org.eclipse.dd.mi.service.MIRegisters;
@ -63,6 +64,11 @@ public class ShutdownSequence extends Sequence {
fTracker = null; fTracker = null;
requestMonitor.done(); requestMonitor.done();
} }
}, new Step() {
@Override
public void execute(RequestMonitor requestMonitor) {
shutdownService(MIDisassembly.class, requestMonitor);
}
}, new Step() { }, new Step() {
@Override @Override
public void execute(RequestMonitor requestMonitor) { public void execute(RequestMonitor requestMonitor) {

View file

@ -11,6 +11,7 @@
package org.eclipse.dd.gdb.service.command; package org.eclipse.dd.gdb.service.command;
import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
import org.eclipse.dd.dsf.debug.service.IDisassembly.IDisassemblyDMContext;
import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext;
import org.eclipse.dd.dsf.debug.service.IModules.ISymbolDMContext; import org.eclipse.dd.dsf.debug.service.IModules.ISymbolDMContext;
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
@ -23,7 +24,7 @@ import org.eclipse.dd.mi.service.command.MIControlDMContext;
*/ */
public class GDBControlDMContext extends MIControlDMContext public class GDBControlDMContext extends MIControlDMContext
implements IContainerDMContext, ISymbolDMContext, IMemoryDMContext, IBreakpointsTargetDMContext, ISourceLookupDMContext, implements IContainerDMContext, ISymbolDMContext, IMemoryDMContext, IBreakpointsTargetDMContext, ISourceLookupDMContext,
ISignalsDMContext ISignalsDMContext, IDisassemblyDMContext
{ {
public GDBControlDMContext(String sessionId, String commandControlId) { public GDBControlDMContext(String sessionId, String commandControlId) {

View file

@ -0,0 +1,200 @@
/*******************************************************************************
* Copyright (c) 2008 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.mi.service;
import java.math.BigInteger;
import java.util.Hashtable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.debug.service.IDisassembly;
import org.eclipse.dd.dsf.debug.service.IInstruction;
import org.eclipse.dd.dsf.debug.service.IMixedInstruction;
import org.eclipse.dd.dsf.debug.service.command.ICommandControl;
import org.eclipse.dd.dsf.service.AbstractDsfService;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.mi.internal.MIPlugin;
import org.eclipse.dd.mi.service.command.commands.MIDataDisassemble;
import org.eclipse.dd.mi.service.command.output.MIDataDisassembleInfo;
import org.osgi.framework.BundleContext;
public class MIDisassembly extends AbstractDsfService implements IDisassembly {
// Services
ICommandControl fConnection;
///////////////////////////////////////////////////////////////////////////
// AbstractDsfService
///////////////////////////////////////////////////////////////////////////
/**
* The service constructor
*
* @param session The debugging session
*/
public MIDisassembly(DsfSession session) {
super(session);
}
/* (non-Javadoc)
* @see org.eclipse.dd.dsf.service.AbstractDsfService#initialize(org.eclipse.dd.dsf.concurrent.RequestMonitor)
*/
@Override
public void initialize(final RequestMonitor rm) {
super.initialize(new RequestMonitor(getExecutor(), rm) {
@Override
protected void handleOK() {
doInitialize(rm);
}
});
}
private void doInitialize(final RequestMonitor rm) {
fConnection = getServicesTracker().getService(ICommandControl.class);
// getSession().addServiceEventListener(this, null);
register(new String[] { IDisassembly.class.getName(), MIDisassembly.class.getName() },
new Hashtable<String, String>());
rm.done();
}
/* (non-Javadoc)
* @see org.eclipse.dd.dsf.service.AbstractDsfService#shutdown(org.eclipse.dd.dsf.concurrent.RequestMonitor)
*/
@Override
public void shutdown(RequestMonitor rm) {
unregister();
// getSession().removeServiceEventListener(this);
rm.done();
}
/* (non-Javadoc)
* @see org.eclipse.dd.dsf.service.AbstractDsfService#getBundleContext()
*/
@Override
protected BundleContext getBundleContext() {
return MIPlugin.getBundleContext();
}
///////////////////////////////////////////////////////////////////////////
// IDisassembly
///////////////////////////////////////////////////////////////////////////
/* (non-Javadoc)
* @see org.eclipse.dd.dsf.debug.service.IDisassembly#getInstructions(org.eclipse.dd.dsf.debug.service.IDisassembly.IDisassemblyDMContext, java.math.BigInteger, java.math.BigInteger, org.eclipse.dd.dsf.concurrent.DataRequestMonitor)
*/
public void getInstructions(IDisassemblyDMContext context,
BigInteger startAddress, BigInteger endAddress,
final DataRequestMonitor<IInstruction[]> drm)
{
// Validate the context
if (context == null) {
drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
drm.done();
return;
}
// Go for it
String start = (startAddress != null) ? startAddress.toString() : "$pc"; //$NON-NLS-1$
String end = (endAddress != null) ? endAddress.toString() : "$pc + 100"; //$NON-NLS-1$
fConnection.queueCommand(new MIDataDisassemble(context, start, end, false),
new DataRequestMonitor<MIDataDisassembleInfo>(getExecutor(), drm) {
@Override
protected void handleOK() {
IInstruction[] result = getData().getMIAssemblyCode();
drm.setData(result);
drm.done();
}
});
}
/* (non-Javadoc)
* @see org.eclipse.dd.dsf.debug.service.IDisassembly#getInstructions(org.eclipse.dd.dsf.debug.service.IDisassembly.IDisassemblyDMContext, java.lang.String, int, int, org.eclipse.dd.dsf.concurrent.DataRequestMonitor)
*/
public void getInstructions(IDisassemblyDMContext context, String filename,
int linenum, int lines, final DataRequestMonitor<IInstruction[]> drm)
{
// Validate the context
if (context == null) {
drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
drm.done();
return;
}
// Go for it
fConnection.queueCommand(new MIDataDisassemble(context, filename, linenum, lines, false),
new DataRequestMonitor<MIDataDisassembleInfo>(getExecutor(), drm) {
@Override
protected void handleOK() {
IInstruction[] result = getData().getMIAssemblyCode();
drm.setData(result);
drm.done();
}
});
}
/* (non-Javadoc)
* @see org.eclipse.dd.dsf.debug.service.IDisassembly#getMixedInstructions(org.eclipse.dd.dsf.debug.service.IDisassembly.IDisassemblyDMContext, java.math.BigInteger, java.math.BigInteger, org.eclipse.dd.dsf.concurrent.DataRequestMonitor)
*/
public void getMixedInstructions(IDisassemblyDMContext context,
BigInteger startAddress, BigInteger endAddress,
final DataRequestMonitor<IMixedInstruction[]> drm)
{
// Validate the context
if (context == null) {
drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
drm.done();
return;
}
// Go for it
String start = (startAddress != null) ? startAddress.toString() : "$pc"; //$NON-NLS-1$
String end = (endAddress != null) ? endAddress.toString() : "$pc + 100"; //$NON-NLS-1$
fConnection.queueCommand(new MIDataDisassemble(context, start, end, true),
new DataRequestMonitor<MIDataDisassembleInfo>(getExecutor(), drm) {
@Override
protected void handleOK() {
IMixedInstruction[] result = getData().getMIMixedCode();
drm.setData(result);
drm.done();
}
});
}
/* (non-Javadoc)
* @see org.eclipse.dd.dsf.debug.service.IDisassembly#getMixedInstructions(org.eclipse.dd.dsf.debug.service.IDisassembly.IDisassemblyDMContext, java.lang.String, int, int, org.eclipse.dd.dsf.concurrent.DataRequestMonitor)
*/
public void getMixedInstructions(IDisassemblyDMContext context,
String filename, int linenum, int lines,
final DataRequestMonitor<IMixedInstruction[]> drm)
{
// Validate the context
if (context == null) {
drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
drm.done();
return;
}
// Go for it
fConnection.queueCommand(new MIDataDisassemble(context, filename, linenum, lines, true),
new DataRequestMonitor<MIDataDisassembleInfo>(getExecutor(), drm) {
@Override
protected void handleOK() {
IMixedInstruction[] result = getData().getMIMixedCode();
drm.setData(result);
drm.done();
}
});
}
}

View file

@ -0,0 +1,93 @@
/*******************************************************************************
* Copyright (c) 2000, 2008 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
* Ericsson - Modified for DSF Reference Implementation
*******************************************************************************/
package org.eclipse.dd.mi.service.command.commands;
import org.eclipse.dd.dsf.debug.service.IDisassembly.IDisassemblyDMContext;
import org.eclipse.dd.mi.service.command.output.MIDataDisassembleInfo;
import org.eclipse.dd.mi.service.command.output.MIOutput;
/**
* -data-disassemble
* [ -s START-ADDR -e END-ADDR ]
* | [ -f FILENAME -l LINENUM [ -n LINES ] ]
* -- MODE
*
* Where:
*
* '-s START-ADDR'
* is the beginning address (or '$pc')
*
* '-e END-ADDR'
* is the end address
*
* '-f FILENAME'
* is the name of the file to disassemble
*
* '-l LINENUM'
* is the line number to disassemble around
*
* -n LINES'
* is the the number of disassembly lines to be produced. If it is
* -1, the whole function will be disassembled, in case no END-ADDR is
* specified. If END-ADDR is specified as a non-zero value, and
* LINES is lower than the number of disassembly lines between
* START-ADDR and END-ADDR, only LINES lines are displayed; if LINES
* is higher than the number of lines between START-ADDR and
* END-ADDR, only the lines up to END-ADDR are displayed.
*
* '-- MODE'
* is either 0 (meaning only disassembly) or 1 (meaning mixed source
* and disassembly).
*/
public class MIDataDisassemble extends MICommand<MIDataDisassembleInfo> {
public MIDataDisassemble(IDisassemblyDMContext ctx, String start, String end, boolean mode) {
super(ctx, "-data-disassemble"); //$NON-NLS-1$
setOptions(new String[]{"-s", start, "-e", end}); //$NON-NLS-1$ //$NON-NLS-2$
String mixed = "0"; //$NON-NLS-1$
if (mode) {
mixed = "1"; //$NON-NLS-1$
}
setParameters(new String[]{mixed});
}
public MIDataDisassemble(IDisassemblyDMContext ctx, String file, int linenum, int lines, boolean mode) {
super(ctx, "-data-disassemble"); //$NON-NLS-1$
setOptions(new String[]{"-f", file, "-l", //$NON-NLS-1$ //$NON-NLS-2$
Integer.toString(linenum), "-n", Integer.toString(lines)}); //$NON-NLS-1$
String mixed = "0"; //$NON-NLS-1$
if (mode) {
mixed = "1"; //$NON-NLS-1$
}
setParameters(new String[]{mixed});
}
/*
* GDB the -data-disassemble uses "--" as a separator wit only the MODE
* So override the MICommand
*/
@Override
protected String parametersToString() {
String[] parameters = getParameters();
if (parameters != null && parameters.length > 0) {
return "-- " + parameters[0]; //$NON-NLS-1$
}
return new String();
}
@Override
public MIDataDisassembleInfo getResult(MIOutput output) {
return new MIDataDisassembleInfo(output);
}
}

View file

@ -0,0 +1,164 @@
/*******************************************************************************
* Copyright (c) 2000, 2008 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
* Ericsson - Modified for DSF Reference Implementation
*******************************************************************************/
package org.eclipse.dd.mi.service.command.output;
import java.util.ArrayList;
import java.util.List;
/**
* The parsed output of the data-disassemble command. The output format is
* determined by the mode field on the request.
*
* -data-disassemble -s $pc -e "$pc + 20" -- 0
* ^done,asm_insns=[
* {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"},
* {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"},
* {address="0x000107c8",func-name="main",offset="12",inst="or %o2, 0x140, %o1\t! 0x11940 <_lib_version+8>"},
* {address="0x000107cc",func-name="main",offset="16",inst="sethi %hi(0x11800), %o2"},
* {address="0x000107d0",func-name="main",offset="20",inst="or %o2, 0x168, %o4\t! 0x11968 <_lib_version+48>"}]
*
* -data-disassemble -f basics.c -l 32 -- 0
* ^done,asm_insns=[
* {address="0x000107bc",func-name="main",offset="0",inst="save %sp, -112, %sp"},
* {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"},
* {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"},
* [...]
* {address="0x0001081c",func-name="main",offset="96",inst="ret "},
* {address="0x00010820",func-name="main",offset="100",inst="restore "}]
*
* -data-disassemble -f basics.c -l 32 -n 3 -- 1
* ^done,asm_insns=[
* src_and_asm_line={line="31",file="/dir1/dir2/basics.c",line_asm_insn=[
* {address="0x000107bc",func-name="main",offset="0",inst="save %sp, -112, %sp"}]},
* src_and_asm_line={line="32",file="/dir1/dir2/basics.c",line_asm_insn=[
* {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"},
* {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"}]}]
*
*/
public class MIDataDisassembleInfo extends MIInfo {
// The parsed information
private boolean mixed;
private MIMixedInstruction[] mixedCode;
private MIInstruction[] assemblyCode;
public MIDataDisassembleInfo(MIOutput record) {
super(record);
mixed = false;
parse();
}
public boolean isMixed() {
return mixed;
}
public MIInstruction[] getMIAssemblyCode() {
return assemblyCode;
}
public MIMixedInstruction[] getMIMixedCode() {
return mixedCode;
}
/**
* Find the relevant tag in the output record ("asm_insns") and then
* parse its value.
*/
private void parse() {
List<MIInstruction> asmList = new ArrayList<MIInstruction>();
List<MIMixedInstruction> srcList = new ArrayList<MIMixedInstruction>();
if (isDone()) {
MIOutput out = getMIOutput();
MIResultRecord rr = out.getMIResultRecord();
if (rr != null) {
MIResult[] results = rr.getMIResults();
// Technically, there should be only one field (asm_insns), but just in case...
for (int i = 0; i < results.length; i++) {
String var = results[i].getVariable();
if (var.equals("asm_insns")) { //$NON-NLS-1$
MIValue value = results[i].getMIValue();
if (value instanceof MIList) {
parseResult((MIList) value, srcList, asmList);
}
}
}
}
}
assemblyCode = asmList.toArray(new MIInstruction[asmList.size()]);
mixedCode = srcList.toArray(new MIMixedInstruction[srcList.size()]);
}
/**
* Parse the back-end result. Depending on the requested mode
* ("-- 0" or "-- 1" on the request), the result has one of the
* following forms:
*
* [1] Mode == 0 (assembly instructions only)
* {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"},
* {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"},
* ...,
* {address="0x00010820",func-name="main",offset="100",inst="restore "}
*
* [2] Mode == 1 (Mixed source and assembly code)
* src_and_asm_line={
* line="31",file="/dir1/dir2/basics.c",
* line_asm_insn=[
* {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"},
* {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"},
* ...,
* {address="0x00010820",func-name="main",offset="100",inst="restore "}
* ]
* },
* ...,
* src_and_asm_line={
* line="31",file="/dir1/dir2/basics.c",
* line_asm_insn=[
* ...,
* ]
* }
*/
private void parseResult(MIList list,
List<MIMixedInstruction> srcList, List<MIInstruction> asmList) {
// Mixed mode (with source)
MIResult[] results = list.getMIResults();
if (results != null && results.length > 0) {
for (int i = 0; i < results.length; i++) {
String var = results[i].getVariable();
if (var.equals("src_and_asm_line")) { //$NON-NLS-1$
MIValue value = results[i].getMIValue();
if (value instanceof MITuple) {
srcList.add(new MIMixedInstruction((MITuple) value));
}
}
}
mixed = true;
}
// Non-mixed mode
MIValue[] values = list.getMIValues();
if (values != null && values.length > 0) {
for (int i = 0; i < values.length; i++) {
if (values[i] instanceof MITuple) {
asmList.add(new MIInstruction((MITuple) values[i]));
}
}
mixed = false;
}
}
}

View file

@ -0,0 +1,130 @@
/*******************************************************************************
* Copyright (c) 2000, 2006 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
* Ericsson - Adapted for DSF
*******************************************************************************/
package org.eclipse.dd.mi.service.command.output;
import java.math.BigInteger;
import org.eclipse.dd.dsf.debug.service.IInstruction;
public class MIInstruction implements IInstruction {
// The parsed information
BigInteger address;
String function = ""; //$NON-NLS-1$
long offset;
String opcode = ""; //$NON-NLS-1$
String args = ""; //$NON-NLS-1$
public MIInstruction(MITuple tuple) {
parse(tuple);
}
public BigInteger getAdress() {
return address;
}
public String getFuntionName() {
return function;
}
public long getOffset() {
return offset;
}
public String getInstruction() {
return opcode + " " + args; //$NON-NLS-1$;
}
public String getOpcode() {
return opcode;
}
public String getArgs() {
return args;
}
/**
* Parse the assembly instruction result. Each instruction has the following
* fields:
* - Address
* - Function name
* - Offset
* - Instruction
*
* {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"},
* {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"},
* ...,
* {address="0x00010820",func-name="main",offset="100",inst="restore "}
*
* In addition, the opcode and arguments are extracted form the assembly instruction.
*/
private void parse(MITuple tuple) {
MIResult[] results = tuple.getMIResults();
for (int i = 0; i < results.length; i++) {
String var = results[i].getVariable();
MIValue value = results[i].getMIValue();
String str = ""; //$NON-NLS-1$
if (value != null && value instanceof MIConst) {
str = ((MIConst)value).getCString();
}
if (var.equals("address")) { //$NON-NLS-1$
try {
address = new BigInteger(str.trim(), 16);
} catch (NumberFormatException e) {
}
continue;
}
if (var.equals("func-name")) { //$NON-NLS-1$
function = str;
continue;
}
if (var.equals("offset")) { //$NON-NLS-1$
try {
offset = Long.decode(str.trim()).longValue();
} catch (NumberFormatException e) {
}
continue;
}
if (var.equals("inst")) { //$NON-NLS-1$
/* for the instruction, we do not want the C string but the
translated string since the only thing we are doing is
displaying it. */
str = ((MIConst) value).getString();
char chars[] = str.toCharArray();
int index = 0;
// count the non-whitespace characters.
while( (index < chars.length) && (chars[index] > '\u0020'))
index++;
opcode = str.substring( 0, index );
// skip any whitespace characters
while( index < chars.length && chars[index] >= '\u0000' && chars[index] <= '\u0020')
index++;
// guard no argument
if( index < chars.length )
args = str.substring( index );
}
}
}
}

View file

@ -0,0 +1,97 @@
/*******************************************************************************
* Copyright (c) 2000, 2006 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
* Ericsson - Adapted for DSF
*******************************************************************************/
package org.eclipse.dd.mi.service.command.output;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.dd.dsf.debug.service.IInstruction;
import org.eclipse.dd.dsf.debug.service.IMixedInstruction;
public class MIMixedInstruction implements IMixedInstruction {
// The parsed information
private String fileName = ""; //$NON-NLS-1$
private int lineNumber = 0;
private MIInstruction[] assemblyCode;
public MIMixedInstruction(MITuple tuple) {
parse(tuple);
}
public String getFileName() {
return fileName;
}
public int getLineNumber() {
return lineNumber;
}
public IInstruction[] getInstructions() {
return assemblyCode;
}
/**
* Parse the mixed instruction result. It has the following 3 fields:
*
* line="31",
* file="/dir1/dir2/basics.c",
* line_asm_insn=[
* {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"},
* {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"},
* ...,
* {address="0x00010820",func-name="main",offset="100",inst="restore "}
* ]
*/
private void parse(MITuple tuple) {
List<MIInstruction> instructions = new ArrayList<MIInstruction>();
MIResult[] results = tuple.getMIResults();
for (int i = 0; i < results.length; i++) {
String var = results[i].getVariable();
MIValue value = results[i].getMIValue();
String str = ""; //$NON-NLS-1$
if (value != null && value instanceof MIConst) {
str = ((MIConst) value).getCString();
}
if (var.equals("line")) { //$NON-NLS-1$
try {
lineNumber = Integer.parseInt(str.trim());
} catch (NumberFormatException e) {
}
continue;
}
if (var.equals("file")) { //$NON-NLS-1$
fileName = str;
continue;
}
if (var.equals("line_asm_insn")) { //$NON-NLS-1$
if (value instanceof MIList) {
MIList list = (MIList) value;
MIValue[] values = list.getMIValues();
for (int j = 0; j < values.length; j++) {
if (values[j] instanceof MITuple) {
instructions.add(new MIInstruction((MITuple) values[j]));
}
}
}
}
}
assemblyCode = instructions.toArray(new MIInstruction[instructions.size()]);
}
}

View file

@ -0,0 +1,592 @@
/*******************************************************************************
* Copyright (c) 2008 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson - Initial Implementation
*******************************************************************************/
package org.eclipse.dd.tests.gdb;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.math.BigInteger;
import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.utils.Addr64;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.dd.dsf.debug.service.IExpressions;
import org.eclipse.dd.dsf.debug.service.IFormattedValues;
import org.eclipse.dd.dsf.debug.service.IInstruction;
import org.eclipse.dd.dsf.debug.service.IMixedInstruction;
import org.eclipse.dd.dsf.debug.service.IDisassembly.IDisassemblyDMContext;
import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext;
import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData;
import org.eclipse.dd.dsf.service.DsfServicesTracker;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.gdb.service.command.GDBControl;
import org.eclipse.dd.gdb.service.command.GDBControlDMContext;
import org.eclipse.dd.mi.service.MIDisassembly;
import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor;
import org.eclipse.dd.tests.gdb.framework.BackgroundRunner;
import org.eclipse.dd.tests.gdb.framework.BaseTestCase;
import org.eclipse.dd.tests.gdb.framework.SyncUtil;
import org.eclipse.dd.tests.gdb.launching.TestsPlugin;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
/*
* This is the Disassembly Service test suite.
*
* It is meant to be a regression suite to be executed automatically against
* the DSF nightly builds.
*
* It is also meant to be augmented with a proper test case(s) every time a
* feature is added or in the event (unlikely :-) that a bug is found in the
* Disassembly Service.
*
* Refer to the JUnit4 documentation for an explanation of the annotations.
*/
@RunWith(BackgroundRunner.class)
public class MIDisassemblyTest extends BaseTestCase {
private static final String FILE_NAME = "MemoryTestApp.cc";
private static final int LINE_NUMBER = 35;
private static final String INVALID_FILE_NAME = "invalid_filename";
private final AsyncCompletionWaitor fWait = new AsyncCompletionWaitor();
private DsfSession fSession;
private DsfServicesTracker fServicesTracker;
private GDBControlDMContext fGdbControlDmc;
private MIDisassembly fDisassembly;
private IExpressions fExpressionService;
// ========================================================================
// Housekeeping stuff
// ========================================================================
@BeforeClass
public static void testSuiteInitialization() {
// Select the binary to run the tests against
setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, "data/launch/bin/MemoryTestApp.exe");
}
@AfterClass
public static void testSuiteCleanup() {
}
@Before
public void testCaseInitialization() {
fSession = getGDBLaunch().getSession();
// Get a reference to the memory service
fServicesTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), fSession.getId());
assert(fServicesTracker != null);
GDBControl gdbControl = fServicesTracker.getService(GDBControl.class);
fGdbControlDmc = gdbControl.getGDBDMContext();
assert(fGdbControlDmc != null);
fDisassembly = fServicesTracker.getService(MIDisassembly.class);
assert(fDisassembly != null);
fExpressionService = fServicesTracker.getService(IExpressions.class);
assert(fExpressionService != null);
// fSession.addServiceEventListener(MIDisassemblyTest.this, null);
}
@After
public void testCaseCleanup() {
// Clear the references (not strictly necessary)
// fSession.removeServiceEventListener(MIDisassemblyTest.this);
fExpressionService = null;
fDisassembly = null;
fServicesTracker.dispose();
fServicesTracker = null;
}
// ========================================================================
// Helper Functions
// ========================================================================
/* ------------------------------------------------------------------------
* evaluateExpression
* ------------------------------------------------------------------------
* Invokes the ExpressionService to evaluate an expression. In theory, we
* shouldn't rely on another service to test this one but we need a way to
* access a variable from the test application in order verify that the
* memory operations (read/write) are working properly.
* ------------------------------------------------------------------------
* @param expression Expression to resolve
* @return Resolved expression
* @throws InterruptedException
* ------------------------------------------------------------------------
*/
private IAddress evaluateExpression(String expression) throws Throwable
{
// Create the expression and format contexts
final IExpressionDMContext expressionDMC = SyncUtil.SyncCreateExpression(fGdbControlDmc, expression);
final FormattedValueDMContext formattedValueDMC = SyncUtil.SyncGetFormattedValue(fExpressionService, expressionDMC, IFormattedValues.HEX_FORMAT);
// Create the DataRequestMonitor which will store the operation result in the wait object
final DataRequestMonitor<FormattedValueDMData> drm =
new DataRequestMonitor<FormattedValueDMData>(fSession.getExecutor(), null) {
@Override
protected void handleCompleted() {
if (getStatus().isOK()) {
fWait.setReturnInfo(getData());
}
fWait.waitFinished(getStatus());
}
};
// Evaluate the expression (asynchronously)
fSession.getExecutor().submit(new Runnable() {
public void run() {
fExpressionService.getFormattedExpressionValue(formattedValueDMC, drm);
}
});
// Wait for completion
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
assertTrue(fWait.getMessage(), fWait.isOK());
// Return the string formatted by the back-end
String result = "";
Object returnInfo = fWait.getReturnInfo();
if (returnInfo instanceof FormattedValueDMData)
result = ((FormattedValueDMData) returnInfo).getFormattedValue();
return new Addr64(result);
}
/* ------------------------------------------------------------------------
* getInstruction
* ------------------------------------------------------------------------
* Issues a disassembly request. The result is stored in fWait.
* ------------------------------------------------------------------------
* Typical usage:
* getInstruction(dmc, start, end);
* fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
* assertTrue(fWait.getMessage(), fWait.isOK());
* ------------------------------------------------------------------------
* @param dmc the data model context
* @param start the start address (null == $pc)
* @param end the end address
* @throws InterruptedException
* ------------------------------------------------------------------------
*/
private void getInstruction(final IDisassemblyDMContext dmc,
final BigInteger startAddress, final BigInteger endAddress)
throws InterruptedException
{
// Set the Data Request Monitor
final DataRequestMonitor<IInstruction[]> drm =
new DataRequestMonitor<IInstruction[]>(fSession.getExecutor(), null) {
@Override
protected void handleCompleted() {
if (getStatus().isOK()) {
fWait.setReturnInfo(getData());
}
fWait.waitFinished(getStatus());
}
};
// Issue the get memory request
fSession.getExecutor().submit(new Runnable() {
public void run() {
fDisassembly.getInstructions(dmc, startAddress, endAddress, drm);
}
});
}
/* ------------------------------------------------------------------------
* getInstruction
* ------------------------------------------------------------------------
* Issues a disassembly request. The result is stored in fWait.
* ------------------------------------------------------------------------
* Typical usage:
* getInstruction(dmc, start, end);
* fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
* assertTrue(fWait.getMessage(), fWait.isOK());
* ------------------------------------------------------------------------
* @param dmc the data model context
* @param fucntion the function
* @param linenum the line
* @param count the instruction count
* @throws InterruptedException
* ------------------------------------------------------------------------
*/
private void getInstruction(final IDisassemblyDMContext dmc,
final String function, final int linenum, final int count)
throws InterruptedException
{
// Set the Data Request Monitor
final DataRequestMonitor<IInstruction[]> drm =
new DataRequestMonitor<IInstruction[]>(fSession.getExecutor(), null) {
@Override
protected void handleCompleted() {
if (getStatus().isOK()) {
fWait.setReturnInfo(getData());
}
fWait.waitFinished(getStatus());
}
};
// Issue the get memory request
fSession.getExecutor().submit(new Runnable() {
public void run() {
fDisassembly.getInstructions(dmc, function, linenum, count, drm);
}
});
}
/* ------------------------------------------------------------------------
* getMixedInstruction
* ------------------------------------------------------------------------
* Issues a disassembly request. The result is stored in fWait.
* ------------------------------------------------------------------------
* Typical usage:
* getInstruction(dmc, start, end);
* fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
* assertTrue(fWait.getMessage(), fWait.isOK());
* ------------------------------------------------------------------------
* @param dmc the data model context
* @param start the start address (null == $pc)
* @param end the end address
* @throws InterruptedException
* ------------------------------------------------------------------------
*/
private void getMixedInstruction(final IDisassemblyDMContext dmc,
final BigInteger startAddress, final BigInteger endAddress)
throws InterruptedException
{
// Set the Data Request Monitor
final DataRequestMonitor<IMixedInstruction[]> drm =
new DataRequestMonitor<IMixedInstruction[]>(fSession.getExecutor(), null) {
@Override
protected void handleCompleted() {
if (getStatus().isOK()) {
fWait.setReturnInfo(getData());
}
fWait.waitFinished(getStatus());
}
};
// Issue the get memory request
fSession.getExecutor().submit(new Runnable() {
public void run() {
fDisassembly.getMixedInstructions(dmc, startAddress, endAddress, drm);
}
});
}
/* ------------------------------------------------------------------------
* getMixedInstruction
* ------------------------------------------------------------------------
* Issues a disassembly request. The result is stored in fWait.
* ------------------------------------------------------------------------
* Typical usage:
* getInstruction(dmc, start, end);
* fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
* assertTrue(fWait.getMessage(), fWait.isOK());
* ------------------------------------------------------------------------
* @param dmc the data model context
* @param start the start address (null == $pc)
* @param end the end address
* @throws InterruptedException
* ------------------------------------------------------------------------
*/
private void getMixedInstruction(final IDisassemblyDMContext dmc,
final String function, final int linenum, final int count)
throws InterruptedException
{
// Set the Data Request Monitor
final DataRequestMonitor<IMixedInstruction[]> drm =
new DataRequestMonitor<IMixedInstruction[]>(fSession.getExecutor(), null) {
@Override
protected void handleCompleted() {
if (getStatus().isOK()) {
fWait.setReturnInfo(getData());
}
fWait.waitFinished(getStatus());
}
};
// Issue the get memory request
fSession.getExecutor().submit(new Runnable() {
public void run() {
fDisassembly.getMixedInstructions(dmc, function, linenum, count, drm);
}
});
}
// ========================================================================
// Test Cases
// ------------------------------------------------------------------------
// Templates:
// ------------------------------------------------------------------------
// @ Test
// public void basicTest() {
// // First test to run
// assertTrue("", true);
// }
// ------------------------------------------------------------------------
// @ Test(timeout=5000)
// public void timeoutTest() {
// // Second test to run, which will timeout if not finished on time
// assertTrue("", true);
// }
// ------------------------------------------------------------------------
// @ Test(expected=FileNotFoundException.class)
// public void exceptionTest() throws FileNotFoundException {
// // Third test to run which expects an exception
// throw new FileNotFoundException("Just testing");
// }
// ========================================================================
///////////////////////////////////////////////////////////////////////////
// getMemory tests
///////////////////////////////////////////////////////////////////////////
// ------------------------------------------------------------------------
// readWithNullContext
// ------------------------------------------------------------------------
@Test(timeout=20000)
public void readWithNullContext() throws Throwable {
// Setup call parameters
BigInteger startAddress = null;
BigInteger endAddress = null;
// Perform the test
fWait.waitReset();
getInstruction(null, startAddress, endAddress);
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
// Verify the result
String expected = "Unknown context type";
assertFalse(fWait.getMessage(), fWait.isOK());
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
fWait.getMessage().contains(expected));
}
// ------------------------------------------------------------------------
// readWithInvalidAddress
// ------------------------------------------------------------------------
@Test(timeout=20000)
public void readWithInvalidAddress() throws Throwable {
// Setup call parameters
BigInteger startAddress = BigInteger.ZERO;
BigInteger endAddress = null;
// Perform the test
fWait.waitReset();
getInstruction(fGdbControlDmc, startAddress, endAddress);
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
// Verify the result
String expected = "Cannot access memory at address";
assertFalse(fWait.getMessage(), fWait.isOK());
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
fWait.getMessage().contains(expected));
}
// ------------------------------------------------------------------------
// readWithNullAddress
// ------------------------------------------------------------------------
@Test(timeout=20000)
public void readWithNullAddress() throws Throwable {
// Setup call parameters
BigInteger startAddress = null;
BigInteger endAddress = null;
// Perform the test
fWait.waitReset();
getInstruction(fGdbControlDmc, startAddress, endAddress);
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
// Verify the result
assertTrue(fWait.getMessage(), fWait.isOK());
IInstruction[] result = (IInstruction[]) fWait.getReturnInfo();
assertTrue("No instruction retrieved", result.length != 0);
}
// ------------------------------------------------------------------------
// readWithValidAddress
// ------------------------------------------------------------------------
@Test(timeout=20000)
public void readWithValidAddress() throws Throwable {
// Setup call parameters
Addr64 main = (Addr64) evaluateExpression("&main");
BigInteger startAddress = main.getValue();
BigInteger endAddress = null;
// Perform the test
fWait.waitReset();
getInstruction(fGdbControlDmc, startAddress, endAddress);
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
// Verify the result
assertTrue(fWait.getMessage(), fWait.isOK());
IInstruction[] result = (IInstruction[]) fWait.getReturnInfo();
assertTrue("No instruction retrieved", result.length != 0);
}
// ------------------------------------------------------------------------
// readWithInvalidFilename
// ------------------------------------------------------------------------
@Test(timeout=20000)
public void readWithValidFunction() throws Throwable {
// Setup call parameters
String filename = INVALID_FILE_NAME;
int linenum = 1;
int count = -1;
// Perform the test
fWait.waitReset();
getInstruction(fGdbControlDmc, filename, linenum, count);
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
// Verify the result
String expected = "Invalid filename";
assertFalse(fWait.getMessage(), fWait.isOK());
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
fWait.getMessage().contains(expected));
}
// ------------------------------------------------------------------------
// readWithInvalidLineNumber
// ------------------------------------------------------------------------
@Test(timeout=20000)
public void readWithInvalidLineNumber() throws Throwable {
// Setup call parameters
String filename = FILE_NAME;
int linenum = -1;
int count = -1;
// Perform the test
fWait.waitReset();
getInstruction(fGdbControlDmc, filename, linenum, count);
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
// Verify the result
String expected = "Invalid line number";
assertFalse(fWait.getMessage(), fWait.isOK());
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
fWait.getMessage().contains(expected));
}
// ------------------------------------------------------------------------
// readWithValidFilename
// ------------------------------------------------------------------------
@Test(timeout=20000)
public void readWithValidFilename() throws Throwable {
// Setup call parameters
String filename = FILE_NAME;
int linenum = LINE_NUMBER;
int count = -1;
// Perform the test
fWait.waitReset();
getInstruction(fGdbControlDmc, filename, linenum, count);
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
// Verify the result
assertTrue(fWait.getMessage(), fWait.isOK());
IInstruction[] result = (IInstruction[]) fWait.getReturnInfo();
assertTrue("No instruction retrieved", result.length != 0);
}
// ------------------------------------------------------------------------
// readWithLineCount
// ------------------------------------------------------------------------
@Test(timeout=20000)
public void readWithLineCount() throws Throwable {
// Setup call parameters
String filename = FILE_NAME;
int linenum = LINE_NUMBER;
int count = 5;
// Perform the test
fWait.waitReset();
getInstruction(fGdbControlDmc, filename, linenum, count);
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
// Verify the result
assertTrue(fWait.getMessage(), fWait.isOK());
IInstruction[] result = (IInstruction[]) fWait.getReturnInfo();
assertTrue("Wrong number of instructions retrieved, expected " + count + ", got " + result.length,
result.length == count);
}
// ------------------------------------------------------------------------
// readMixedWithValidAddress
// ------------------------------------------------------------------------
@Test(timeout=20000)
public void readMixedWithValidAddress() throws Throwable {
// Setup call parameters
Addr64 main = (Addr64) evaluateExpression("&main");
BigInteger startAddress = main.getValue();
BigInteger endAddress = null;
// Perform the test
fWait.waitReset();
getMixedInstruction(fGdbControlDmc, startAddress, endAddress);
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
// Verify the result
assertTrue(fWait.getMessage(), fWait.isOK());
IMixedInstruction[] result = (IMixedInstruction[]) fWait.getReturnInfo();
assertTrue("No instruction retrieved", result.length != 0);
}
// ------------------------------------------------------------------------
// readMixedWithLineCount
// ------------------------------------------------------------------------
@Test(timeout=20000)
public void readMixedWithLineCount() throws Throwable {
// Setup call parameters
String filename = FILE_NAME;
int linenum = LINE_NUMBER;
int count = 5;
// Perform the test
fWait.waitReset();
getMixedInstruction(fGdbControlDmc, filename, linenum, count);
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
// Verify the result
assertTrue(fWait.getMessage(), fWait.isOK());
IMixedInstruction[] result = (IMixedInstruction[]) fWait.getReturnInfo();
int total = 0;
for (IMixedInstruction mixed : result) {
IInstruction[] inst = mixed.getInstructions();
total += inst.length;
}
assertTrue("Wrong number of instructions retrieved, expected " + count + ", got " + result.length,
total == count);
}
}

View file

@ -34,6 +34,7 @@ import org.eclipse.dd.mi.service.CSourceLookup;
import org.eclipse.dd.mi.service.ExpressionService; import org.eclipse.dd.mi.service.ExpressionService;
import org.eclipse.dd.mi.service.MIBreakpoints; import org.eclipse.dd.mi.service.MIBreakpoints;
import org.eclipse.dd.mi.service.MIBreakpointsManager; import org.eclipse.dd.mi.service.MIBreakpointsManager;
import org.eclipse.dd.mi.service.MIDisassembly;
import org.eclipse.dd.mi.service.MIMemory; import org.eclipse.dd.mi.service.MIMemory;
import org.eclipse.dd.mi.service.MIRegisters; import org.eclipse.dd.mi.service.MIRegisters;
import org.eclipse.dd.mi.service.MIStack; import org.eclipse.dd.mi.service.MIStack;
@ -226,6 +227,10 @@ public class LaunchSequence extends Sequence {
public void execute(RequestMonitor requestMonitor) { public void execute(RequestMonitor requestMonitor) {
new MIRegisters(fSession).initialize(requestMonitor); new MIRegisters(fSession).initialize(requestMonitor);
}}, }},
new Step() { @Override
public void execute(RequestMonitor requestMonitor) {
new MIDisassembly(fSession).initialize(requestMonitor);
}},
/*new Step() { public void execute(RequestMonitor requestMonitor) { /*new Step() { public void execute(RequestMonitor requestMonitor) {
new GDBVariables(fSession).initialize(requestMonitor); new GDBVariables(fSession).initialize(requestMonitor);
}},*/ }},*/

View file

@ -23,6 +23,7 @@ import org.eclipse.dd.mi.service.CSourceLookup;
import org.eclipse.dd.mi.service.ExpressionService; import org.eclipse.dd.mi.service.ExpressionService;
import org.eclipse.dd.mi.service.MIBreakpoints; import org.eclipse.dd.mi.service.MIBreakpoints;
import org.eclipse.dd.mi.service.MIBreakpointsManager; import org.eclipse.dd.mi.service.MIBreakpointsManager;
import org.eclipse.dd.mi.service.MIDisassembly;
import org.eclipse.dd.mi.service.MIMemory; import org.eclipse.dd.mi.service.MIMemory;
import org.eclipse.dd.mi.service.MIRegisters; import org.eclipse.dd.mi.service.MIRegisters;
import org.eclipse.dd.mi.service.MIStack; import org.eclipse.dd.mi.service.MIStack;
@ -59,6 +60,7 @@ public class ShutdownSequence extends Sequence {
requestMonitor.done(); requestMonitor.done();
} }
}, },
new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIDisassembly.class, requestMonitor); }},
new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIRegisters.class, requestMonitor); }}, new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIRegisters.class, requestMonitor); }},
new Step() { new Step() {
// Uninstall the breakpoints before the service is shut down. // Uninstall the breakpoints before the service is shut down.

View file

@ -89,7 +89,7 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate
} }
} }
private void launchLocalDebugSession( ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException { private void launchLocalDebugSession( final ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException {
if ( monitor.isCanceled() ) { if ( monitor.isCanceled() ) {
return; return;
} }
@ -151,8 +151,9 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate
GDBControl gdbControl = tracker.getService(GDBControl.class); GDBControl gdbControl = tracker.getService(GDBControl.class);
if (gdbControl != null) { if (gdbControl != null) {
IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval(
GDB_DEBUG_MODEL_ID, gdbControl.getGDBDMContext()); GDB_DEBUG_MODEL_ID, config, gdbControl.getGDBDMContext());
launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval);
((DsfMemoryBlockRetrieval) memRetrieval).initialize();
} }
tracker.dispose(); tracker.dispose();
return null; return null;

11
tests/.project Normal file
View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>tests</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>