1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-03 07:05:24 +02:00

DSF Updates related to adding registers view.

This commit is contained in:
Pawel Piech 2006-09-28 18:14:14 +00:00
parent 5516763481
commit 5fa8b64ad6
22 changed files with 142 additions and 99 deletions

View file

@ -65,7 +65,7 @@ abstract public class DataViewModelSchemaNode implements IViewModelSchemaNode {
}
public String toString() {
return fParent.toString() + "\n" + fDmc.toString();
return fParent.toString() + "->" + fDmc.toString();
}
}
@ -127,7 +127,7 @@ abstract public class DataViewModelSchemaNode implements IViewModelSchemaNode {
fExecutor.execute(done);
}};
// TODO: Note this is pretty inefficient: for one the below loop could
// Note: this is pretty inefficient. For one the below loop could
// potentially retrieve the elements for this node several times, but
// beyond that it may be possible to optimize this code based on what's
// visible in the view.
@ -222,7 +222,6 @@ abstract public class DataViewModelSchemaNode implements IViewModelSchemaNode {
}
public void sessionDispose() {
// FIXME: should track when disposed and avoid issuing model deltas
fServices.dispose();
for (IViewModelSchemaNode childNode : getChildNodes()) {
childNode.sessionDispose();

View file

@ -45,14 +45,14 @@ public interface IViewModelSchemaNode {
* current level.
* @param done The data return token.
*/
public void getElements(final IViewModelContext parentVmc, GetDataDone<IViewModelContext[]> done);
public void getElements(IViewModelContext parentVmc, GetDataDone<IViewModelContext[]> done);
/**
* Retrieves the label for the given element.
* @param vmc Element for which to retrieve label information.
* @param result Monitor which accepts the data.
*/
public void retrieveLabel(IViewModelContext vmc, final ILabelRequestMonitor result);
public void retrieveLabel(IViewModelContext vmc, ILabelRequestMonitor result);
/**
* Returns the list of child schema nodes which are configured for this node.

View file

@ -18,9 +18,7 @@ import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta;
* This delta class mostly just duplicates the ModelDelta implemention, but
* it allows clients to modify the flags after the original object is
* constructed.
* <p>
* TODO: This class derives from ModelDelta as opposed to just implementing IModelDelta
* because of a reference in IModelDelta to ModelDelta. Need to file a bug on it.
*
* @see IModelDelta#getNodes()
*/
@SuppressWarnings("restriction")

View file

@ -108,6 +108,14 @@ public class ViewModelProvider extends AbstractModelProxy
}
}
private boolean isOurSchemaNode(IViewModelSchemaNode schemaNode, IViewModelSchemaNode[] nodesToSearch) {
for (IViewModelSchemaNode node : nodesToSearch) {
if (node == schemaNode) return true;
if (isOurSchemaNode(schemaNode, node.getChildNodes())) return true;
}
return false;
}
/**
* Performs the query to determine if given VNC is a container.
* Note: this method must be called on the provider's dispatch thread.
@ -122,7 +130,7 @@ public class ViewModelProvider extends AbstractModelProxy
// collect the list of children. Otherwise, get the child schema nodes
// out of VMC's schema node.
IViewModelSchemaNode[] childSchemaNodes;
if (vmc == fRootVMC) {
if (vmc == fRootVMC || !isOurSchemaNode(vmc.getSchemaNode(), fRootSchemaNodes)) {
childSchemaNodes = fRootSchemaNodes;
} else {
childSchemaNodes = vmc.getSchemaNode().getChildNodes();
@ -161,7 +169,7 @@ public class ViewModelProvider extends AbstractModelProxy
// Get the child nodes as in isContainer().
IViewModelSchemaNode[] childSchemaNodes;
if (vmc == fRootVMC) {
if (vmc == fRootVMC || !isOurSchemaNode(vmc.getSchemaNode(), fRootSchemaNodes)) {
childSchemaNodes = fRootSchemaNodes;
} else {
childSchemaNodes = vmc.getSchemaNode().getChildNodes();

View file

@ -0,0 +1,2 @@
org.eclipse.dd.dsf/debug = false
org.eclipse.dd.dsf/debug/executor = false

View file

@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.dd.dsf;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleContext;
@ -24,8 +25,12 @@ public class DsfPlugin extends Plugin {
// The shared instance
private static DsfPlugin fgPlugin;
// BundleContext of this plugin
private static BundleContext fgBundleContext;
// Debugging flag
public static boolean DEBUG = false;
/**
* The constructor
*/
@ -40,7 +45,8 @@ public class DsfPlugin extends Plugin {
public void start(BundleContext context) throws Exception {
fgBundleContext = context;
super.start(context);
}
DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.debug.ui/debug")); //$NON-NLS-1$//$NON-NLS-2$
}
/*
* (non-Javadoc)
@ -64,5 +70,12 @@ public class DsfPlugin extends Plugin {
public static BundleContext getBundleContext() {
return fgBundleContext;
}
public static void debug(String message) {
if (DEBUG) {
System.out.println(message);
}
}
}

View file

@ -10,10 +10,17 @@
*******************************************************************************/
package org.eclipse.dd.dsf.concurrent;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.dd.dsf.DsfPlugin;
@ -25,6 +32,14 @@ import org.eclipse.dd.dsf.DsfPlugin;
public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor
implements DsfExecutor
{
// debug tracing flags
public static boolean DEBUG_EXECUTOR = false;
static {
DEBUG_EXECUTOR = DsfPlugin.DEBUG && "true".equals( //$NON-NLS-1$
Platform.getDebugOption("org.eclipse.dd.dsf/debug/executor")); //$NON-NLS-1$
}
static class DsfThreadFactory implements ThreadFactory {
Thread fThread;
public Thread newThread(Runnable r) {
@ -34,8 +49,6 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor
}
}
public DefaultDsfExecutor() {
super(1, new DsfThreadFactory());
}
@ -45,16 +58,36 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
// FIXME: Unfortunately this is not enough to catch runnable exceptions, because
// FutureTask implementation swallows exceptions when they're thrown by runnables.
// Need to override the FutureTask class, and the AbstractExecutorService.submit()
// methods in order to provide access to these exceptions.
protected void beforeExecute(Thread t, Runnable r) {
System.out.println("");
}
super.afterExecute(r, t);
if (t != null) {
DsfPlugin.getDefault().getLog().log(new Status(
IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Uncaught exception in dispatch thread.", t));
@Override
protected void afterExecute(Runnable r, Throwable t) {
if (r instanceof Future) {
Future future = (Future)r;
try {
future.get();
} catch (InterruptedException e) { // Ignore
} catch (CancellationException e) { // Ignore also
} catch (ExecutionException e) {
if (e.getCause() != null) {
DsfPlugin.getDefault().getLog().log(new Status(
IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Uncaught exception in DSF executor thread", e.getCause()));
if (DEBUG_EXECUTOR) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream(512);
PrintStream printStream = new PrintStream(outStream);
try {
printStream.write("Uncaught exception in session executor thread: ".getBytes());
} catch (IOException e2) {}
e.getCause().printStackTrace(new PrintStream(outStream));
DsfPlugin.debug(outStream.toString());
}
}
}
}
}
}

View file

@ -25,7 +25,6 @@ import org.eclipse.dd.dsf.DsfPlugin;
* data at end of Callable#call method.
*
* @see java.util.concurrent.Callable
* FIXME: make this class implement the Future<V> interface.
*/
abstract public class DsfQuery<V> {
@ -66,7 +65,7 @@ abstract public class DsfQuery<V> {
if (!fWaiting) {
fFuture = fExecutor.submit(new DsfRunnable() {
public void run() {
// TODO: not sure if this try-catch is desirable. It might encourage
// Note: not sure if this try-catch is desirable. It might encourage
// implementors to not catch its own exceptions. If the query code takes
// more than one dispatch, then this code will not be helpful anyway.
try {

View file

@ -14,32 +14,49 @@ package org.eclipse.dd.dsf.concurrent;
* A DSF-instrumented alternative to the Runnable interface.
* <p>
* While it is perfectly fine for clients to call the DSF executor with
* an object only implementing the Runnable interface, the DsfRunnable is a
* place holder for future tracing enhancments for DSF.
* an object only implementing the Runnable interface, the DsfRunnable
* contains fields and methods that used for debugging and tracing when
* tracing is enabled.
*/
abstract public class DsfRunnable implements Runnable {
private StackTraceElement [] fStackTrace = null;
private Runnable fSubmittedBy = null;
public DsfRunnable() {
// Use assertion flag (-ea) to jre to avoid affecting performance when not debugging.
boolean assertsEnabled = false;
assert assertsEnabled = true;
if (assertsEnabled) {
if (assertsEnabled || DefaultDsfExecutor.DEBUG_EXECUTOR) {
fStackTrace = Thread.currentThread().getStackTrace();
}
}
public String toString () {
// If assertions are not turned on.
if (fStackTrace == null) return super.toString();
StringBuilder builder = new StringBuilder() ;
// ommit the first elements in the stack trace
for ( int i= 3 ; i < fStackTrace.length; i++ ) {
builder.append ( "\tat " ) ;
builder.append ( fStackTrace [ i ] .toString ()) ;
builder.append ( "\n" ) ;
// If assertions are not turned on.
builder.append(super.toString());
if (fStackTrace != null) {
builder.append ( "\n\tCreated at" ) ;
// ommit the first elements in the stack trace
for (int i = 3; i < fStackTrace.length && i < 13; i++) {
if (i > 3) builder.append ( "\tat " ) ;
builder.append( fStackTrace [ i ] .toString ()) ;
builder.append( "\n" ) ;
}
if (fStackTrace.length > 13) {
builder.append("\t at ...");
}
}
return builder.toString () ;
if (fSubmittedBy != null) {
builder.append("Submitted by \n");
builder.append(fSubmittedBy.toString());
}
return builder.toString();
}
void setSubmittedBy(Runnable runnable) {
fSubmittedBy = runnable;
}
}

View file

@ -38,18 +38,11 @@ import org.eclipse.dd.dsf.DsfPlugin;
* if progress reporting, cancellability, and roll-back ability is required, it
* has to be re-implemented every time. The Sequence class tries to address
* this problem by containing this pattern in a single class.
*
* <br>TODO: should a sequence be re-entrant. I.e. should the arguments be
* passed in through a map, and the return values returned back in the done?
* <br>FIXME: convert to implement Future interface
*/
abstract public class DsfSequence {
/**
* The abstract class that each step has to implement
* <br>FIXME: convert execute() and rollBacl() to take "done" as an argument.
* This way we can make step a static class, and make its paradigm
* more consistent with rest of DSF.
*/
abstract public class Step {
public void execute() { stepFinished(); }
@ -165,9 +158,7 @@ abstract public class DsfSequence {
invokeLater();
try {
wait();
} catch (InterruptedException e) {
// TODO: error handling?
}
} catch (InterruptedException e) {}
}
private void doInvoke() {

View file

@ -16,6 +16,9 @@ import org.eclipse.core.runtime.IStatus;
* Convenience extension to GetDataDone, which handles posting of the client's
* <code>Done</code> upon the completion of this <code>GetDataDone</code>.
* @param <V> Class type of data.
* @deprecated This class has been replaced with the
* {@link Done#propagateErrorToClient(DsfExecutor, Done, int, String)}
* method.
*/
public abstract class GetDataDoneWithClientDone<V> extends GetDataDone<V> {
private DsfExecutor fExecutor;

View file

@ -53,7 +53,7 @@ public interface IExpressions extends IDataModelService {
String getBinaryValue();
String getStringValue();
IAddress getAddress();
IRegisters.RegisterDMC getRegister();
IRegisters.IRegisterDMC getRegister();
Map<String,String> getEnumerations();
}

View file

@ -21,11 +21,6 @@ import org.eclipse.dd.dsf.model.IDataModelService;
/**
* Debugger service representing module handling logic of a debugger.
* <br>
* TODO: I meant this as a replacement for Application service as well as the
* registry API in DSF 1. But I still don't fully understand the format
* of the symbol data that is stored in the registry, so that needs to be added
* to this interface.
*/
public interface IModules extends IDataModelService {

View file

@ -21,9 +21,7 @@ import org.eclipse.dd.dsf.model.IDataModelService;
* manipulate those objects. This is a much more extensive interface than
* the NativeProcesses service but for simple debugging, it serves the same
* purpose: to list/create/terminate processes and attach debugger to them.
* <p>
* TODO: need methods for performing actions on objects (create, terminate,
* etc).
*
* @see INativeProcesses
*/
public interface IOS extends IDataModelService {

View file

@ -22,24 +22,25 @@ import org.eclipse.dd.dsf.model.IDataModelService;
public interface IRegisters extends IDataModelService {
/** Register group context */
public interface RegisterGroupDMC extends IDataModelContext<RegisterGroupData> {}
public interface IRegisterGroupDMC extends IDataModelContext<IRegisterGroupData> {}
/**
* Register groups only have a name. Sub groups and registered are retrieved
* through the service interface.
*/
public interface RegisterGroupData extends IDataModelData {
public interface IRegisterGroupData extends IDataModelData {
public String getName();
public String getDescription();
}
/** Register context */
public interface RegisterDMC extends IDataModelContext<RegisterData> {}
public interface IRegisterDMC extends IDataModelContext<IRegisterData> {}
/** Event indicating register value changed. */
public interface RegisterChangedEvent extends IDataModelEvent<RegisterDMC> {}
public interface IRegisterChangedEvent extends IDataModelEvent<IRegisterDMC> {}
/** Register information */
public interface RegisterData extends IDataModelData, NumericalValue {
public interface IRegisterData extends IDataModelData, INumericalValue {
String getName();
String getDescription();
boolean isReadable();
@ -52,13 +53,13 @@ public interface IRegisters extends IDataModelService {
}
/** Bit field context */
public interface BitFieldDMC extends IDataModelContext<BitFieldData> {}
public interface IBitFieldDMC extends IDataModelContext<IBitFieldData> {}
/**
* Bitfield data, big groups and mnemonics are retrieved at the same
* time as rest of bit field data
*/
public interface BitFieldData extends IDataModelData, NumericalValue {
public interface IBitFieldData extends IDataModelData, INumericalValue {
String getName();
String getDescription();
boolean isReadable();
@ -68,18 +69,18 @@ public interface IRegisters extends IDataModelService {
boolean hasSideEffects();
boolean isZeroBasedNumbering();
boolean isZeroBitLeftMost();
BitGroup[] getBitGroup();
Mnemonic[] getMnemonics();
IBitGroup[] getBitGroup();
IMnemonic[] getMnemonics();
}
/** Bit group definition */
public interface BitGroup {
public interface IBitGroup {
int startBit();
int bitCount();
}
/** Bit field mnemonic */
public interface Mnemonic extends NumericalValue {
public interface IMnemonic extends INumericalValue {
String getShortName();
String getLongName();
}
@ -88,7 +89,7 @@ public interface IRegisters extends IDataModelService {
* Common interface for describing a number value for various register
* data objects
*/
public interface NumericalValue {
public interface INumericalValue {
String getNaturalValue();
String getHexValue();
String getOctalValue();
@ -101,14 +102,14 @@ public interface IRegisters extends IDataModelService {
* @param frameCtx Stack frame DMC, this is optional and may be null.
* @param done Return token.
*/
void getRegisterGroups(IRunControl.IExecutionDMC execCtx, IStack.IFrameDMC frameCtx, GetDataDone<RegisterGroupDMC[]> done);
void getRegisterGroups(IRunControl.IExecutionDMC execCtx, IStack.IFrameDMC frameCtx, GetDataDone<IRegisterGroupDMC[]> done);
/** Retrieves list of sub-groups of given register group. */
void getRegisterSubGroups(RegisterGroupDMC groupCtx, GetDataDone<RegisterGroupDMC[]> done);
void getRegisterSubGroups(IRegisterGroupDMC groupCtx, GetDataDone<IRegisterGroupDMC[]> done);
/** Retrieves registers in given register group. */
void getRegisters(RegisterGroupDMC groupCtx, GetDataDone<RegisterDMC[]> done);
void getRegisters(IRegisterGroupDMC groupCtx, GetDataDone<IRegisterDMC[]> done);
/** Retrieves bit fields for given register */
void getBitFields(RegisterDMC regCtx, GetDataDone<BitFieldDMC[]> done);
void getBitFields(IRegisterDMC regCtx, GetDataDone<IBitFieldDMC[]> done);
}

View file

@ -58,10 +58,6 @@ public interface IStack extends IDataModelService {
/**
* Returns whether the stack frames can be retrieved for given thread.
* <br>
* TODO: I'm not sure if this method should be async. It assumes that the
* implementation can determine if stack is available based on process
* state information.
*/
boolean isStackAvailable(IRunControl.IExecutionDMC execContext);

View file

@ -23,12 +23,12 @@ import org.eclipse.dd.dsf.model.IDataModelService;
* @see IModules
*/
public interface ISymbols extends IDataModelService {
public interface SymbolObjectDMC extends IDataModelContext<SymbolObjectData> {}
public interface ISymbolObjectDMC extends IDataModelContext<ISymbolObjectData> {}
/**
* Data about a debug symbol.
*/
public interface SymbolObjectData extends IDataModelData {
public interface ISymbolObjectData extends IDataModelData {
String getName();
String getTypeName();
String getFilepath();
@ -41,10 +41,8 @@ public interface ISymbols extends IDataModelService {
* even while it's still parsing. This event may be issued periodically
* by the service to indicate that a section of debug symbols has been
* parsed.
* TODO: This is not an IModelEvent because the context of this event is
* the whole service. This needs to be fixed.
*/
public interface SymbolDataChanged extends IDataModelEvent<IModules.ISymbolDMC> {}
public interface ISymbolDataChanged extends IDataModelEvent<IModules.ISymbolDMC> {}
/**
* Retrieves the list of symbols.
@ -52,5 +50,5 @@ public interface ISymbols extends IDataModelService {
* @param done Return token. The return value is an iterator (rather than
* array) since there could be a very large number of symbols returned.
*/
public void getSymbols(IModules.ISymbolDMC symCtx, GetDataDone<Iterable<SymbolObjectDMC>> done);
public void getSymbols(IModules.ISymbolDMC symCtx, GetDataDone<Iterable<ISymbolObjectDMC>> done);
}

View file

@ -12,8 +12,6 @@ package org.eclipse.dd.dsf.model;
/**
* Base implementation of the IDataModelContext interface.
* <p>
* TODO: consider merging the event interface with this class.
*/
public class DataModelEvent<V extends IDataModelContext> implements IDataModelEvent<V> {

View file

@ -87,8 +87,6 @@ abstract public class AbstractDsfService
/**
* Registers this service.
* <br> FIXME: Move registering call to default initialize()/shutdown(). Add a new
* protected method calcProperties() to get the initial list of properties.
*/
@SuppressWarnings("unchecked")
protected void register(String[] classes, Dictionary properties) {

View file

@ -34,8 +34,6 @@ import java.lang.annotation.Target;
* will be called every time one of the sub-class events is invoked.
* If a listener declares a handler for an event AND a superclass of that event,
* both handlers will be invoked when the event is dispatched.
*
* <br>TODO: Handling of second argument is not yet implemented.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)

View file

@ -136,11 +136,12 @@ public class DsfSession
* thread, but the session-started listeners will be called using the session's
* executor.
* @param executor The DSF executor to use for this session.
* @param ownerId ID (plugin ID preferably) of the owner of this session
* @return instance object of the new session
*/
public static DsfSession startSession(DsfExecutor executor) {
public static DsfSession startSession(DsfExecutor executor, String ownerId) {
synchronized(fgActiveSessions) {
final DsfSession newSession = new DsfSession(executor, Integer.toString(fgSessionIdCounter++));
final DsfSession newSession = new DsfSession(executor, ownerId, Integer.toString(fgSessionIdCounter++));
fgActiveSessions.add(newSession);
executor.submit( new DsfRunnable() { public void run() {
SessionStartedListener[] listeners = fSessionStartedListeners.toArray(
@ -191,6 +192,9 @@ public class DsfSession
public int hashCode() { return fListener.hashCode(); }
}
/** ID (plugin ID preferably) of the owner of this session */
private String fOwnerId;
/** Session ID of this session. */
private String fId;
@ -210,6 +214,8 @@ public class DsfSession
*/
private Map<Class,Object> fAdapters = Collections.synchronizedMap(new HashMap<Class,Object>());
/** Returns the owner ID of this session */
public String getOwnerId() { return fOwnerId; }
/** Returns the ID of this session */
public String getId() { return fId; }
@ -256,10 +262,7 @@ public class DsfSession
*/
public void dispatchEvent(final Object event, final Dictionary serviceProperties) {
getExecutor().submit(new DsfRunnable() { public void run() {
// TED added FIXME otherwise no way to detect!!!
try {
doDispatchEvent(event, serviceProperties);
} catch(Throwable e) { e.printStackTrace(); }
}});
}
@ -387,8 +390,9 @@ public class DsfSession
/**
* Class to be instanciated only using startSession()
*/
private DsfSession(DsfExecutor executor, String id) {
private DsfSession(DsfExecutor executor, String ownerId, String id) {
fId = id;
fOwnerId = ownerId;
fExecutor = executor;
}

View file

@ -32,8 +32,6 @@ import org.eclipse.dd.dsf.concurrent.DsfExecutor;
* service exposes a method that is to be called on non-dispatch thread, it should
* be documented so.
*
* TODO: Add IStatus error code constants for common service related failures.
*
* @see org.osgi.framework.BundleContext#registerService(String[], Object, Dictionary)
*/
public interface IDsfService {
@ -52,10 +50,6 @@ public interface IDsfService {
/**
* Returns the map of properties that this service was registered with.
* <br>
* TODO: is returning the properties and service filter redundant? Should
* getServiceFilter() be removed from the interface since it can be generated
* from the properties?
*/
Dictionary getProperties();