mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-09-10 12:03:16 +02:00
[160041] - [debug view] Retrieving limited # of stack frames.
This commit is contained in:
parent
f9b2f38049
commit
fd5c004c84
25 changed files with 1225 additions and 65 deletions
|
@ -41,4 +41,8 @@ action.setDefaultNumberFormatHex.label = Hex
|
|||
action.setDefaultNumberFormatDecimal.label = Decimal
|
||||
action.setDefaultNumberFormatOctal.label = Octal
|
||||
action.setDefaultNumberFormatBinary.label = Binary
|
||||
action.setDefaultNumberFormatNatural.label = Natural
|
||||
action.setDefaultNumberFormatNatural.label = Natural
|
||||
|
||||
preferencePage.name = DSF Debugging
|
||||
|
||||
action.expandStack.label = E&xpand Stack
|
||||
|
|
|
@ -448,6 +448,12 @@
|
|||
category="org.eclipse.debug.ui.DebugPreferencePage"
|
||||
name="%disassemblyPreferencePage.name"
|
||||
id="org.eclipse.dd.dsf.debug.ui.disassembly.preferencePage"/>
|
||||
<page
|
||||
category="org.eclipse.debug.ui.DebugPreferencePage"
|
||||
class="org.eclipse.dd.dsf.debug.internal.ui.preferences.DsfDebugPreferencePage"
|
||||
id="org.eclipse.dd.dsf.debug.ui.preferences"
|
||||
name="%preferencePage.name">
|
||||
</page>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.popupMenus">
|
||||
|
@ -523,4 +529,18 @@
|
|||
</viewContribution>
|
||||
</extension>
|
||||
|
||||
<!-- Debug view context menu contributions -->
|
||||
<extension point="org.eclipse.ui.popupMenus">
|
||||
<viewerContribution
|
||||
id="org.eclipse.dd.dsf.debug.ui.DebugView.context"
|
||||
targetID="org.eclipse.debug.ui.DebugView">
|
||||
<action
|
||||
class="org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.actions.ExpandStackAction"
|
||||
id="org.eclipse.dd.dsf.debug.ui.retrieveMoreFrames"
|
||||
label="%action.expandStack.label"
|
||||
menubarPath="renderGroup">
|
||||
</action>
|
||||
</viewerContribution>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
||||
|
|
|
@ -24,13 +24,17 @@ import org.eclipse.dd.dsf.datamodel.DMContexts;
|
|||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.LaunchRootVMNode.LaunchesEvent;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.StackFramesVMNode.IncompleteStackVMContext;
|
||||
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.IVMModelProxy;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.IVMNode;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.update.AutomaticUpdatePolicy;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.update.IVMUpdatePolicy;
|
||||
|
@ -41,6 +45,12 @@ import org.eclipse.debug.core.IDebugEventSetListener;
|
|||
import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.core.ILaunchesListener2;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.util.IPropertyChangeListener;
|
||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||
import org.eclipse.jface.viewers.DoubleClickEvent;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -57,10 +67,36 @@ public class AbstractLaunchVMProvider extends AbstractDMVMProvider
|
|||
|
||||
private final Map<IExecutionDMContext,ScheduledFuture<?>> fRefreshStackFramesFutures = new HashMap<IExecutionDMContext,ScheduledFuture<?>>();
|
||||
|
||||
private IPropertyChangeListener fPreferencesListener;
|
||||
|
||||
@ThreadSafe
|
||||
public AbstractLaunchVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session)
|
||||
{
|
||||
super(adapter, presentationContext, session);
|
||||
|
||||
final IPreferenceStore store= DsfDebugUIPlugin.getDefault().getPreferenceStore();
|
||||
if (store.getBoolean(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE)) {
|
||||
getPresentationContext().setProperty(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, store.getInt(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT));
|
||||
}
|
||||
|
||||
fPreferencesListener = new IPropertyChangeListener() {
|
||||
public void propertyChange(final PropertyChangeEvent event) {
|
||||
String property = event.getProperty();
|
||||
if (IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE.equals(property)
|
||||
|| IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT.equals(property)) {
|
||||
if (store.getBoolean(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE)) {
|
||||
getPresentationContext().setProperty(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, store.getInt(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT));
|
||||
} else {
|
||||
getPresentationContext().setProperty(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, null);
|
||||
}
|
||||
getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
handleEvent(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
}};
|
||||
store.addPropertyChangeListener(fPreferencesListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -91,6 +127,33 @@ public class AbstractLaunchVMProvider extends AbstractDMVMProvider
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(Object event) {
|
||||
if (event instanceof DoubleClickEvent && !isDisposed()) {
|
||||
final ISelection selection= ((DoubleClickEvent) event).getSelection();
|
||||
if (selection instanceof IStructuredSelection) {
|
||||
Object element= ((IStructuredSelection) selection).getFirstElement();
|
||||
if (element instanceof IncompleteStackVMContext) {
|
||||
IncompleteStackVMContext incStackVmc = ((IncompleteStackVMContext) element);
|
||||
IVMNode node = ((IncompleteStackVMContext) element).getVMNode();
|
||||
if (incStackVmc.getVMNode() instanceof StackFramesVMNode) {
|
||||
IExecutionDMContext exeCtx= incStackVmc.getExecutionDMContext();
|
||||
((StackFramesVMNode) node).incrementStackFrameLimit(exeCtx);
|
||||
// replace double click event with expand stack event
|
||||
final ExpandStackEvent expandStackEvent = new ExpandStackEvent(exeCtx);
|
||||
getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
handleEvent(expandStackEvent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
super.handleEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleEvent(IVMModelProxy proxyStrategy, final Object event, RequestMonitor rm) {
|
||||
super.handleEvent(proxyStrategy, event, rm);
|
||||
|
@ -131,6 +194,7 @@ public class AbstractLaunchVMProvider extends AbstractDMVMProvider
|
|||
fRefreshStackFramesFutures.remove(exeContext);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -150,6 +214,10 @@ public class AbstractLaunchVMProvider extends AbstractDMVMProvider
|
|||
public void dispose() {
|
||||
DebugPlugin.getDefault().removeDebugEventListener(this);
|
||||
DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
|
||||
|
||||
final IPreferenceStore store= DsfDebugUIPlugin.getDefault().getPreferenceStore();
|
||||
store.removePropertyChangeListener(fPreferencesListener);
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems, Inc. 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:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch;
|
||||
|
||||
import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
|
||||
/**
|
||||
* Event to increase the stack frame limit for an execution context.
|
||||
*/
|
||||
public class ExpandStackEvent extends AbstractDMEvent<IExecutionDMContext> {
|
||||
|
||||
public ExpandStackEvent(IExecutionDMContext execCtx) {
|
||||
super(execCtx);
|
||||
}
|
||||
|
||||
}
|
|
@ -10,7 +10,10 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
|
@ -21,14 +24,19 @@ import org.eclipse.dd.dsf.datamodel.DMContexts;
|
|||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack2;
|
||||
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExitedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData;
|
||||
import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.ModelProxyInstalledEvent;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.VMChildrenUpdate;
|
||||
|
@ -47,6 +55,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
|
|||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
||||
import org.eclipse.debug.ui.DebugUITools;
|
||||
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||
import org.eclipse.ui.IMemento;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
|
@ -54,7 +63,42 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
implements IElementLabelProvider, IElementMementoProvider
|
||||
{
|
||||
|
||||
public StackFramesVMNode(AbstractDMVMProvider provider, DsfSession session) {
|
||||
/**
|
||||
* View model context representing the end of an incomplete stack.
|
||||
*/
|
||||
public class IncompleteStackVMContext extends AbstractVMContext {
|
||||
private final int fLevel;
|
||||
private final IExecutionDMContext fDmc;
|
||||
|
||||
public IncompleteStackVMContext(IExecutionDMContext dmc, int level) {
|
||||
super(StackFramesVMNode.this);
|
||||
fDmc = dmc;
|
||||
fLevel = level;
|
||||
}
|
||||
public int getLevel() {
|
||||
return fLevel;
|
||||
}
|
||||
public IExecutionDMContext getExecutionDMContext() {
|
||||
return fDmc;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof IncompleteStackVMContext &&
|
||||
((IncompleteStackVMContext)obj).fDmc.equals(fDmc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return fDmc.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary stack frame limit to allow incremental stack updates.
|
||||
*/
|
||||
private Map<IExecutionDMContext, Integer> fTemporaryLimits = new HashMap<IExecutionDMContext, Integer>();
|
||||
|
||||
public StackFramesVMNode(AbstractDMVMProvider provider, DsfSession session) {
|
||||
super(provider, session, IStack.IFrameDMContext.class);
|
||||
}
|
||||
|
||||
|
@ -89,8 +133,9 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
return;
|
||||
}
|
||||
|
||||
final int stackFrameLimit= getStackFrameLimit(execDmc);
|
||||
stackService.getStackDepth(
|
||||
execDmc, 0,
|
||||
execDmc, stackFrameLimit == Integer.MAX_VALUE ? 0 : stackFrameLimit + 1,
|
||||
new ViewerDataRequestMonitor<Integer>(getSession().getExecutor(), update) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
|
@ -98,7 +143,11 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
update.setChildCount(getData());
|
||||
int stackDepth= getData();
|
||||
if (stackFrameLimit < stackDepth) {
|
||||
stackDepth = stackFrameLimit + 1;
|
||||
}
|
||||
update.setChildCount(stackDepth);
|
||||
update.done();
|
||||
}
|
||||
});
|
||||
|
@ -117,7 +166,10 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
return;
|
||||
}
|
||||
|
||||
if (update.getOffset() == 0 && update.getLength() == 1) {
|
||||
final int stackFrameLimit= getStackFrameLimit(execDmc);
|
||||
final int startIndex= update.getOffset();
|
||||
|
||||
if (startIndex == 0 && update.getLength() == 1) {
|
||||
// Requesting top stack frame only
|
||||
stackService.getTopFrame(
|
||||
execDmc,
|
||||
|
@ -134,24 +186,59 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
});
|
||||
|
||||
} else {
|
||||
// full stack dump
|
||||
stackService.getFrames(
|
||||
execDmc,
|
||||
new ViewerDataRequestMonitor<IFrameDMContext[]>(getSession().getExecutor(), update) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
if (!isSuccess()) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
if (startIndex >= 0 && update.getLength() > 0 && stackService instanceof IStack2) {
|
||||
// partial stack dump
|
||||
IStack2 stackService2= (IStack2) stackService;
|
||||
int endIndex= startIndex + update.getLength() - 1;
|
||||
if (startIndex < stackFrameLimit && endIndex >= stackFrameLimit) {
|
||||
endIndex = stackFrameLimit - 1;
|
||||
}
|
||||
stackService2.getFrames(
|
||||
execDmc,
|
||||
startIndex,
|
||||
endIndex,
|
||||
new ViewerDataRequestMonitor<IFrameDMContext[]>(getSession().getExecutor(), update) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
if (!isSuccess()) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
IFrameDMContext[] frames = getData();
|
||||
fillUpdateWithVMCs(update, frames, startIndex);
|
||||
if (startIndex + update.getLength() > stackFrameLimit) {
|
||||
update.setChild(new IncompleteStackVMContext(execDmc, stackFrameLimit), stackFrameLimit);
|
||||
}
|
||||
update.done();
|
||||
}
|
||||
fillUpdateWithVMCs(update, getData());
|
||||
update.done();
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// full stack dump
|
||||
stackService.getFrames(
|
||||
execDmc,
|
||||
new ViewerDataRequestMonitor<IFrameDMContext[]>(getSession().getExecutor(), update) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
if (!isSuccess()) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
IFrameDMContext[] frames = getData();
|
||||
if (frames.length > stackFrameLimit) {
|
||||
IFrameDMContext[] tmpFrames = new IFrameDMContext[stackFrameLimit];
|
||||
System.arraycopy(frames, 0, tmpFrames, 0, stackFrameLimit);
|
||||
frames = tmpFrames;
|
||||
update.setChild(new IncompleteStackVMContext(execDmc, stackFrameLimit), stackFrameLimit);
|
||||
}
|
||||
fillUpdateWithVMCs(update, frames);
|
||||
update.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider#update(org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate[])
|
||||
*/
|
||||
|
@ -171,13 +258,25 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
protected void updateLabelInSessionThread(ILabelUpdate[] updates) {
|
||||
for (final ILabelUpdate update : updates) {
|
||||
IStack stackService = getServicesTracker().getService(IStack.class);
|
||||
final IFrameDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IFrameDMContext.class);
|
||||
|
||||
if (stackService == null || dmc == null) {
|
||||
if (stackService == null) {
|
||||
handleFailedUpdate(update);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (update.getElement() instanceof IncompleteStackVMContext) {
|
||||
update.setLabel("<...more frames...>", 0); //$NON-NLS-1$
|
||||
update.setImageDescriptor(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_STACKFRAME), 0);
|
||||
update.done();
|
||||
return;
|
||||
}
|
||||
|
||||
final IFrameDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IFrameDMContext.class);
|
||||
if (dmc == null) {
|
||||
handleFailedUpdate(update);
|
||||
continue;
|
||||
}
|
||||
|
||||
getDMVMProvider().getModelData(
|
||||
this, update,
|
||||
getServicesTracker().getService(IStack.class, null),
|
||||
|
@ -314,7 +413,22 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
return IModelDelta.CONTENT;
|
||||
} else if (e instanceof ModelProxyInstalledEvent) {
|
||||
return IModelDelta.SELECT | IModelDelta.EXPAND;
|
||||
}
|
||||
} else if (e instanceof ExpandStackEvent) {
|
||||
return IModelDelta.CONTENT;
|
||||
} else if (e instanceof IExitedDMEvent) {
|
||||
// Do not generate a delta for this event, but do clear the
|
||||
// internal stack frame limit to avoid a memory leak.
|
||||
clearStackFrameLimit( ((IExitedDMEvent)e).getDMContext() );
|
||||
return IModelDelta.NO_CHANGE;
|
||||
} else if (e instanceof PropertyChangeEvent) {
|
||||
String property = ((PropertyChangeEvent)e).getProperty();
|
||||
if (IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE.equals(property)
|
||||
|| IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT.equals(property))
|
||||
{
|
||||
return IModelDelta.CONTENT;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
return IModelDelta.NO_CHANGE;
|
||||
}
|
||||
|
@ -325,6 +439,9 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
*/
|
||||
public void buildDelta(final Object e, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) {
|
||||
if (e instanceof IContainerSuspendedDMEvent) {
|
||||
// Clear the limit on the stack frames for all stack frames under a given container.
|
||||
clearStackFrameLimit( ((IContainerSuspendedDMEvent)e).getDMContext() );
|
||||
|
||||
IContainerSuspendedDMEvent csEvent = (IContainerSuspendedDMEvent)e;
|
||||
|
||||
IExecutionDMContext triggeringCtx = csEvent.getTriggeringContexts().length != 0
|
||||
|
@ -341,12 +458,23 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
IExecutionDMContext execDmc = ((FullStackRefreshEvent)e).getDMContext();
|
||||
buildDeltaForFullStackRefreshEvent(execDmc, execDmc, parent, nodeOffset, rm);
|
||||
} else if (e instanceof ISuspendedDMEvent) {
|
||||
clearStackFrameLimit( ((ISuspendedDMEvent)e).getDMContext() );
|
||||
IExecutionDMContext execDmc = ((ISuspendedDMEvent)e).getDMContext();
|
||||
buildDeltaForSuspendedEvent(execDmc, execDmc, parent, nodeOffset, rm);
|
||||
} else if (e instanceof StepQueueManager.ISteppingTimedOutEvent) {
|
||||
buildDeltaForSteppingTimedOutEvent((StepQueueManager.ISteppingTimedOutEvent)e, parent, nodeOffset, rm);
|
||||
} else if (e instanceof ModelProxyInstalledEvent) {
|
||||
buildDeltaForModelProxyInstalledEvent(parent, nodeOffset, rm);
|
||||
} else if (e instanceof ExpandStackEvent) {
|
||||
IExecutionDMContext execDmc = ((ExpandStackEvent)e).getDMContext();
|
||||
buildDeltaForExpandStackEvent(execDmc, parent, rm);
|
||||
} else if (e instanceof PropertyChangeEvent) {
|
||||
String property = ((PropertyChangeEvent)e).getProperty();
|
||||
if (IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE.equals(property)
|
||||
|| IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT.equals(property))
|
||||
{
|
||||
buildDeltaForStackFrameLimitPreferenceChangedEvent(parent, rm);
|
||||
}
|
||||
} else {
|
||||
rm.done();
|
||||
}
|
||||
|
@ -443,6 +571,17 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
);
|
||||
}
|
||||
|
||||
private void buildDeltaForExpandStackEvent(IExecutionDMContext execDmc, final VMDelta parentDelta, final RequestMonitor rm) {
|
||||
parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
|
||||
rm.done();
|
||||
}
|
||||
|
||||
|
||||
private void buildDeltaForStackFrameLimitPreferenceChangedEvent(final VMDelta parentDelta, final RequestMonitor rm) {
|
||||
parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
|
||||
rm.done();
|
||||
}
|
||||
|
||||
private String produceFrameElementName( String viewName , IFrameDMContext frame ) {
|
||||
/*
|
||||
* We are addressing Bugzilla 211490 which wants the Register View to keep the same expanded
|
||||
|
@ -516,4 +655,47 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
request.done();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current active stack frame limit. If no limit is applicable {@link Integer.MAX_VALUE} is returned.
|
||||
*
|
||||
* @return the current stack frame limit
|
||||
*/
|
||||
public int getStackFrameLimit(IExecutionDMContext execCtx) {
|
||||
if (fTemporaryLimits.containsKey(execCtx)) {
|
||||
return fTemporaryLimits.get(execCtx);
|
||||
}
|
||||
Object stackDepthLimit= getVMProvider().getPresentationContext().getProperty(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT);
|
||||
if (stackDepthLimit instanceof Integer) {
|
||||
return (Integer)stackDepthLimit;
|
||||
}
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
private void clearStackFrameLimit(IExecutionDMContext execCtx) {
|
||||
if (execCtx instanceof IContainerDMContext) {
|
||||
for (Iterator<IExecutionDMContext> itr = fTemporaryLimits.keySet().iterator(); itr.hasNext();) {
|
||||
IExecutionDMContext limitCtx = itr.next();
|
||||
if (limitCtx.equals(execCtx) || DMContexts.isAncestorOf(limitCtx, execCtx)) {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fTemporaryLimits.remove(execCtx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Increment the stack frame limit by the default increment.
|
||||
* This implementation doubles the current limit.
|
||||
*/
|
||||
public void incrementStackFrameLimit(IExecutionDMContext execCtx) {
|
||||
final int stackFrameLimit= getStackFrameLimit(execCtx);
|
||||
if (stackFrameLimit < Integer.MAX_VALUE / 2) {
|
||||
fTemporaryLimits.put(execCtx, stackFrameLimit * 2);
|
||||
} else {
|
||||
fTemporaryLimits.put(execCtx, Integer.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems, Inc. 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:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.actions;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.actions.AbstractVMProviderActionDelegate;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.AbstractLaunchVMProvider;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.ExpandStackEvent;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.StackFramesVMNode;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.StackFramesVMNode.IncompleteStackVMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.IVMNode;
|
||||
import org.eclipse.debug.ui.contexts.DebugContextEvent;
|
||||
import org.eclipse.jface.action.IAction;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.ui.IViewPart;
|
||||
|
||||
/**
|
||||
* Increment the (temporary) stack limit for the selected stack.
|
||||
*/
|
||||
public class ExpandStackAction extends AbstractVMProviderActionDelegate {
|
||||
|
||||
/*
|
||||
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
|
||||
*/
|
||||
public void run(IAction action) {
|
||||
Object element = getViewerInput();
|
||||
if (element instanceof IncompleteStackVMContext) {
|
||||
IncompleteStackVMContext incStackVmc = ((IncompleteStackVMContext) element);
|
||||
IVMNode node = incStackVmc.getVMNode();
|
||||
if (incStackVmc.getVMNode() instanceof StackFramesVMNode) {
|
||||
final IExecutionDMContext exeCtx= incStackVmc.getExecutionDMContext();
|
||||
((StackFramesVMNode) node).incrementStackFrameLimit(exeCtx);
|
||||
final ExpandStackEvent event = new ExpandStackEvent(exeCtx);
|
||||
final AbstractLaunchVMProvider vmProvider = (AbstractLaunchVMProvider) getVMProvider();
|
||||
vmProvider.getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
vmProvider.handleEvent(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(IViewPart view) {
|
||||
super.init(view);
|
||||
updateEnablement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debugContextChanged(DebugContextEvent event) {
|
||||
super.debugContextChanged(event);
|
||||
updateEnablement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectionChanged(IAction action, ISelection selection) {
|
||||
super.selectionChanged(action, selection);
|
||||
updateEnablement();
|
||||
}
|
||||
|
||||
private void updateEnablement() {
|
||||
boolean enabled = false;
|
||||
if (getVMProvider() instanceof AbstractLaunchVMProvider) {
|
||||
Object element = getViewerInput();
|
||||
enabled = element instanceof IncompleteStackVMContext;
|
||||
}
|
||||
getAction().setEnabled(enabled);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems, Inc. 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:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.internal.ui.preferences;
|
||||
|
||||
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants;
|
||||
import org.eclipse.jface.preference.FieldEditorPreferencePage;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.preference.IntegerFieldEditor;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Group;
|
||||
import org.eclipse.ui.IWorkbench;
|
||||
import org.eclipse.ui.IWorkbenchPreferencePage;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
|
||||
/**
|
||||
* DSF debug preference page.
|
||||
*/
|
||||
public class DsfDebugPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
|
||||
|
||||
/**
|
||||
* Mandatory default constructor (executable extension).
|
||||
*/
|
||||
public DsfDebugPreferencePage() {
|
||||
super(GRID);
|
||||
IPreferenceStore store= DsfDebugUIPlugin.getDefault().getPreferenceStore();
|
||||
setPreferenceStore(store);
|
||||
setDescription(MessagesForPreferences.DsfDebugPreferencePage_description);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
|
||||
*/
|
||||
public void init(IWorkbench workbench) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createControl(Composite parent) {
|
||||
super.createControl(parent);
|
||||
PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IDsfDebugUIConstants.PREFERENCE_PAGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createFieldEditors() {
|
||||
Group performanceGroup= new Group(getFieldEditorParent(), SWT.NONE);
|
||||
performanceGroup.setText(MessagesForPreferences.DsfDebugPreferencePage_performanceGroup_label);
|
||||
performanceGroup.setLayout(new GridLayout());
|
||||
GridData gd= new GridData(GridData.FILL_HORIZONTAL);
|
||||
gd.verticalIndent= 5;
|
||||
performanceGroup.setLayoutData(gd);
|
||||
|
||||
Composite innerParent= new Composite(performanceGroup, SWT.NONE);
|
||||
innerParent.setLayout(new GridLayout());
|
||||
innerParent.setLayoutData(gd);
|
||||
|
||||
IntegerFieldEditor limitEditor= new IntegerWithBooleanFieldEditor(
|
||||
IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE,
|
||||
IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT,
|
||||
MessagesForPreferences.DsfDebugPreferencePage_limitStackFrames_label,
|
||||
innerParent);
|
||||
|
||||
limitEditor.setValidRange(1, Integer.MAX_VALUE);
|
||||
limitEditor.fillIntoGrid(innerParent, 3);
|
||||
addField(limitEditor);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems, Inc. 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:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.internal.ui.preferences;
|
||||
|
||||
import org.eclipse.jface.preference.IntegerFieldEditor;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
/**
|
||||
* An integer field editor with an enablement check box.
|
||||
*/
|
||||
public class IntegerWithBooleanFieldEditor extends IntegerFieldEditor {
|
||||
|
||||
private final String fEnableKey;
|
||||
private Button fCheckbox;
|
||||
private boolean fWasSelected;
|
||||
|
||||
public IntegerWithBooleanFieldEditor(String enableKey, String nameKey, String labelText, Composite parent) {
|
||||
super(nameKey, labelText, parent);
|
||||
fEnableKey= enableKey;
|
||||
}
|
||||
|
||||
public IntegerWithBooleanFieldEditor(String enableKey, String nameKey, String labelText, Composite parent, int textLimit) {
|
||||
super(nameKey, labelText, parent, textLimit);
|
||||
fEnableKey= enableKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFillIntoGrid(Composite parent, int numColumns) {
|
||||
getCheckboxControl(parent);
|
||||
super.doFillIntoGrid(parent, numColumns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfControls() {
|
||||
return super.getNumberOfControls() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void adjustForNumColumns(int numColumns) {
|
||||
// the checkbox uses one column
|
||||
super.adjustForNumColumns(numColumns - 1);
|
||||
}
|
||||
|
||||
private Button getCheckboxControl(Composite parent) {
|
||||
if (fCheckbox == null) {
|
||||
fCheckbox= new Button(parent, SWT.CHECK);
|
||||
fCheckbox.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
boolean isSelected = fCheckbox.getSelection();
|
||||
valueChanged(fWasSelected, isSelected);
|
||||
fWasSelected = isSelected;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
checkParent(fCheckbox, parent);
|
||||
}
|
||||
return fCheckbox;
|
||||
}
|
||||
|
||||
protected void valueChanged(boolean oldValue, boolean newValue) {
|
||||
setPresentsDefaultValue(false);
|
||||
if (oldValue != newValue) {
|
||||
fireStateChanged(VALUE, oldValue, newValue);
|
||||
getTextControl().setEnabled(newValue);
|
||||
getLabelControl().setEnabled(newValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean checkState() {
|
||||
if (fCheckbox != null && !fCheckbox.getSelection()) {
|
||||
return true;
|
||||
}
|
||||
return super.checkState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoad() {
|
||||
super.doLoad();
|
||||
if (fCheckbox != null) {
|
||||
boolean value = getPreferenceStore().getBoolean(fEnableKey);
|
||||
fCheckbox.setSelection(value);
|
||||
fWasSelected = value;
|
||||
getTextControl().setEnabled(value);
|
||||
getLabelControl().setEnabled(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadDefault() {
|
||||
super.doLoadDefault();
|
||||
if (fCheckbox != null) {
|
||||
boolean value = getPreferenceStore().getDefaultBoolean(fEnableKey);
|
||||
fCheckbox.setSelection(value);
|
||||
fWasSelected = value;
|
||||
getTextControl().setEnabled(value);
|
||||
getLabelControl().setEnabled(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStore() {
|
||||
super.doStore();
|
||||
getPreferenceStore().setValue(fEnableKey, fCheckbox.getSelection());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this field editor's current boolean value.
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
public boolean getBooleanValue() {
|
||||
return fCheckbox.getSelection();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems, Inc. 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:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.internal.ui.preferences;
|
||||
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
|
||||
/**
|
||||
* Preference strings.
|
||||
*/
|
||||
class MessagesForPreferences extends NLS {
|
||||
private static final String BUNDLE_NAME= "org.eclipse.dd.dsf.debug.internal.ui.preferences.messages"; //$NON-NLS-1$
|
||||
|
||||
public static String DsfDebugPreferencePage_description;
|
||||
public static String DsfDebugPreferencePage_limitStackFrames_label;
|
||||
public static String DsfDebugPreferencePage_performanceGroup_label;
|
||||
|
||||
static {
|
||||
// initialize resource bundle
|
||||
NLS.initializeMessages(BUNDLE_NAME, MessagesForPreferences.class);
|
||||
}
|
||||
|
||||
private MessagesForPreferences() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems, Inc. 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:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.internal.ui.preferences;
|
||||
|
||||
import org.eclipse.jface.preference.StringFieldEditor;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
/**
|
||||
* A string field editor with an enablement check box.
|
||||
*/
|
||||
public class StringWithBooleanFieldEditor extends StringFieldEditor {
|
||||
|
||||
private final String fEnableKey;
|
||||
private Button fCheckbox;
|
||||
private boolean fWasSelected;
|
||||
|
||||
public StringWithBooleanFieldEditor(String enableKey, String nameKey, String labelText, Composite parent) {
|
||||
super(nameKey, labelText, parent);
|
||||
fEnableKey= enableKey;
|
||||
}
|
||||
|
||||
public StringWithBooleanFieldEditor(String enableKey, String nameKey, String labelText, int width, Composite parent) {
|
||||
super(nameKey, labelText, width, parent);
|
||||
fEnableKey= enableKey;
|
||||
}
|
||||
|
||||
public StringWithBooleanFieldEditor(String enableKey, String nameKey, String labelText, int width, int strategy, Composite parent) {
|
||||
super(nameKey, labelText, width, strategy, parent);
|
||||
fEnableKey= enableKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFillIntoGrid(Composite parent, int numColumns) {
|
||||
getCheckboxControl(parent);
|
||||
super.doFillIntoGrid(parent, numColumns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfControls() {
|
||||
return super.getNumberOfControls() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void adjustForNumColumns(int numColumns) {
|
||||
// the checkbox uses one column
|
||||
super.adjustForNumColumns(numColumns - 1);
|
||||
}
|
||||
|
||||
private Button getCheckboxControl(Composite parent) {
|
||||
if (fCheckbox == null) {
|
||||
fCheckbox= new Button(parent, SWT.CHECK);
|
||||
fCheckbox.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
boolean isSelected = fCheckbox.getSelection();
|
||||
valueChanged(fWasSelected, isSelected);
|
||||
fWasSelected = isSelected;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
checkParent(fCheckbox, parent);
|
||||
}
|
||||
return fCheckbox;
|
||||
}
|
||||
|
||||
protected void valueChanged(boolean oldValue, boolean newValue) {
|
||||
setPresentsDefaultValue(false);
|
||||
if (oldValue != newValue) {
|
||||
fireStateChanged(VALUE, oldValue, newValue);
|
||||
getTextControl().setEnabled(newValue);
|
||||
getLabelControl().setEnabled(newValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean checkState() {
|
||||
if (fCheckbox != null && !fCheckbox.getSelection()) {
|
||||
return true;
|
||||
}
|
||||
return super.checkState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoad() {
|
||||
super.doLoad();
|
||||
if (fCheckbox != null) {
|
||||
boolean value = getPreferenceStore().getBoolean(fEnableKey);
|
||||
fCheckbox.setSelection(value);
|
||||
fWasSelected = value;
|
||||
getTextControl().setEnabled(value);
|
||||
getLabelControl().setEnabled(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadDefault() {
|
||||
super.doLoadDefault();
|
||||
if (fCheckbox != null) {
|
||||
boolean value = getPreferenceStore().getDefaultBoolean(fEnableKey);
|
||||
fCheckbox.setSelection(value);
|
||||
fWasSelected = value;
|
||||
getTextControl().setEnabled(value);
|
||||
getLabelControl().setEnabled(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStore() {
|
||||
super.doStore();
|
||||
getPreferenceStore().setValue(fEnableKey, fCheckbox.getSelection());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this field editor's current boolean value.
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
public boolean getBooleanValue() {
|
||||
return fCheckbox.getSelection();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
###############################################################################
|
||||
# Copyright (c) 2008 Wind River 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:
|
||||
# Wind River Systems - initial API and implementation
|
||||
###############################################################################
|
||||
|
||||
DsfDebugPreferencePage_description=General settings for debugging with DSF:
|
||||
DsfDebugPreferencePage_limitStackFrames_label=Limit number of stack frames to
|
||||
DsfDebugPreferencePage_performanceGroup_label=Performance
|
|
@ -55,7 +55,20 @@ public interface IDsfDebugUIConstants {
|
|||
* the workbench font preference page.
|
||||
*/
|
||||
public static final String DETAIL_PANE_FONT= PLUGIN_ID + "DetailPaneFont"; //$NON-NLS-1$
|
||||
|
||||
|
||||
/**
|
||||
* Integer preference to control the maximum amount of stack frames to
|
||||
* retrieve from the backend. Default value is 100.
|
||||
* @see {@link #PREF_STACK_FRAME_LIMIT_ENABLE}
|
||||
*/
|
||||
public static final String PREF_STACK_FRAME_LIMIT = "stackFrameLimit"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Boolean preference whether to apply the stack frame limit preference.
|
||||
* @see {@link #PREF_STACK_FRAME_LIMIT}
|
||||
*/
|
||||
public static final String PREF_STACK_FRAME_LIMIT_ENABLE = "stackFrameLimitEnable"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Help prefixes.
|
||||
*/
|
||||
|
@ -71,4 +84,6 @@ public interface IDsfDebugUIConstants {
|
|||
public static final String DETAIL_PANE_FIND_REPLACE_ACTION = PREFIX + "detail_pane_find_replace_action_context"; //$NON-NLS-1$
|
||||
public static final String DETAIL_PANE_WORD_WRAP_ACTION = PREFIX + "detail_pane_word_wrap_action_context"; //$NON-NLS-1$
|
||||
public static final String DETAIL_PANE_MAX_LENGTH_ACTION = PREFIX + "detail_pane_max_length_action_context"; //$NON-NLS-1$
|
||||
|
||||
public static final String PREFERENCE_PAGE= PREFIX + "preference_page_context"; //$NON-NLS-1$
|
||||
}
|
||||
|
|
|
@ -52,5 +52,11 @@ public class PreferenceInitializer extends AbstractPreferenceInitializer {
|
|||
* Expressions View
|
||||
*/
|
||||
prefs.setDefault(IDsfDebugUIConstants.EXPRESSIONS_DETAIL_PANE_ORIENTATION, IDsfDebugUIConstants.VARIABLES_DETAIL_PANE_UNDERNEATH);
|
||||
}
|
||||
|
||||
/*
|
||||
* Debug View
|
||||
*/
|
||||
prefs.setDefault(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, 100);
|
||||
prefs.setDefault(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems, Inc. 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:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.service;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
|
||||
/**
|
||||
* Stack service extension.
|
||||
* <p>
|
||||
* Adds the capability to retrieve a limited number of stack frames.
|
||||
* </p>
|
||||
*
|
||||
* @since DSF 1.1
|
||||
*/
|
||||
public interface IStack2 extends IStack {
|
||||
|
||||
/**
|
||||
* Convenience constant for use with {@link #getFrames(IDMContext, int, int, DataRequestMonitor)}
|
||||
* to retrieve all stack frames.
|
||||
*/
|
||||
public final static int ALL_FRAMES = -1;
|
||||
|
||||
/**
|
||||
* Retrieves list of stack frames for the given execution context. Request
|
||||
* will fail if the stack frame data is not available.
|
||||
* <p>The range of stack frames can be limited by the <code>startIndex</code> and <code>endIndex</code> arguments.
|
||||
* It is no error to specify an <code>endIndex</code> exceeding the number of available stack frames.
|
||||
* A negative value for <code>endIndex</code> means to retrieve all stack frames. <code>startIndex</code> must be a non-negative value.
|
||||
* </p>
|
||||
*
|
||||
* @param execContext the execution context to retrieve stack frames for
|
||||
* @param startIndex the index of the first frame to retrieve
|
||||
* @param endIndex the index of the last frame to retrieve (inclusive) or {@link #ALL_FRAMES}
|
||||
* @param rm the request monitor
|
||||
*
|
||||
* @see #getFrames(IDMContext, DataRequestMonitor)
|
||||
*/
|
||||
public abstract void getFrames(IDMContext execContext, int startIndex, int endIndex, DataRequestMonitor<IFrameDMContext[]> rm);
|
||||
|
||||
}
|
|
@ -32,6 +32,9 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
|||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
|
||||
import org.eclipse.jface.viewers.DoubleClickEvent;
|
||||
import org.eclipse.jface.viewers.IDoubleClickListener;
|
||||
import org.eclipse.jface.viewers.StructuredViewer;
|
||||
import org.eclipse.jface.viewers.Viewer;
|
||||
|
||||
|
||||
|
@ -55,6 +58,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
private Viewer fViewer;
|
||||
private boolean fDisposed = false;
|
||||
private ListenerList fListeners = new ListenerList();
|
||||
private IDoubleClickListener fDoubleClickListener;
|
||||
|
||||
/**
|
||||
* Debug flag indicating whether the deltas should be traced in stdout.
|
||||
|
@ -154,6 +158,10 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
*/
|
||||
public void dispose() {
|
||||
fDisposed = true;
|
||||
if (fViewer instanceof StructuredViewer && fDoubleClickListener != null) {
|
||||
((StructuredViewer) fViewer).removeDoubleClickListener(fDoubleClickListener);
|
||||
fDoubleClickListener= null;
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -187,9 +195,29 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
fProvider.handleEvent(new ModelProxyInstalledEvent(DefaultVMModelProxyStrategy.this, viewer, fRootElement));
|
||||
}
|
||||
});
|
||||
if (fViewer instanceof StructuredViewer && fDoubleClickListener == null) {
|
||||
((StructuredViewer) fViewer).addDoubleClickListener(fDoubleClickListener= new IDoubleClickListener() {
|
||||
public void doubleClick(DoubleClickEvent e) {
|
||||
handleDoubleClick(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle viewer double click.
|
||||
*
|
||||
* @param e the event
|
||||
*/
|
||||
protected void handleDoubleClick(final DoubleClickEvent e) {
|
||||
getVMProvider().getExecutor().execute( new DsfRunnable() {
|
||||
public void run() {
|
||||
getVMProvider().handleEvent(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the viewer this proxy is installed in.
|
||||
*
|
||||
* @return viewer or <code>null</code> if not installed
|
||||
|
|
|
@ -323,13 +323,34 @@ abstract public class AbstractDMVMNode extends AbstractVMNode implements IVMNode
|
|||
return vmContexts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill update request with view model contexts based on given data model contexts.
|
||||
* Assumes that data model context elements start at index 0.
|
||||
*
|
||||
* @param update the viewer update request
|
||||
* @param dmcs the data model contexts
|
||||
*/
|
||||
protected void fillUpdateWithVMCs(IChildrenUpdate update, IDMContext[] dmcs) {
|
||||
int startIdx = update.getOffset() != -1 ? update.getOffset() : 0;
|
||||
int endIdx = update.getLength() != -1 ? startIdx + update.getLength() : dmcs.length;
|
||||
// Ted: added bounds limitation of dmcs.length
|
||||
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109
|
||||
for (int i = startIdx; i < endIdx && i < dmcs.length; i++) {
|
||||
update.setChild(createVMContext(dmcs[i]), i);
|
||||
fillUpdateWithVMCs(update, dmcs, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill update request with view model contexts based on given data model contexts.
|
||||
*
|
||||
* @param update the viewer update request
|
||||
* @param dmcs the data model contexts
|
||||
* @param firstIndex the index of the first data model context
|
||||
*/
|
||||
protected void fillUpdateWithVMCs(IChildrenUpdate update, IDMContext[] dmcs, int firstIndex) {
|
||||
int updateIdx = update.getOffset() != -1 ? update.getOffset() : 0;
|
||||
final int endIdx = updateIdx + (update.getLength() != -1 ? update.getLength() : dmcs.length);
|
||||
int dmcIdx = updateIdx - firstIndex;
|
||||
if (dmcIdx < 0) {
|
||||
updateIdx -= dmcIdx;
|
||||
dmcIdx = 0;
|
||||
}
|
||||
while (updateIdx < endIdx && dmcIdx < dmcs.length) {
|
||||
update.setChild(createVMContext(dmcs[dmcIdx++]), updateIdx++);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -577,6 +577,7 @@ public class PDAVirtualMachine {
|
|||
else if ("eval".equals(command)) debugEval(args);
|
||||
else if ("eventstop".equals(command)) debugEventStop(args);
|
||||
else if ("exit".equals(command)) debugExit();
|
||||
else if ("frame".equals(command)) debugFrame(args);
|
||||
else if ("popdata".equals(command)) debugPop(args);
|
||||
else if ("pushdata".equals(command)) debugPush(args);
|
||||
else if ("resume".equals(command)) debugResume(args);
|
||||
|
@ -584,6 +585,7 @@ public class PDAVirtualMachine {
|
|||
else if ("setdata".equals(command)) debugSetData(args);
|
||||
else if ("setvar".equals(command)) debugSetVariable(args);
|
||||
else if ("stack".equals(command)) debugStack(args);
|
||||
else if ("stackdepth".equals(command)) debugStackDepth(args);
|
||||
else if ("state".equals(command)) debugState(args);
|
||||
else if ("step".equals(command)) debugStep(args);
|
||||
else if ("stepreturn".equals(command)) debugStepReturn(args);
|
||||
|
@ -713,6 +715,23 @@ public class PDAVirtualMachine {
|
|||
System.exit(0);
|
||||
}
|
||||
|
||||
void debugFrame(Args args) {
|
||||
PDAThread thread = args.getThreadArg();
|
||||
if (thread == null) {
|
||||
sendCommandResponse("error: invalid thread\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int sfnumber = args.getNextIntArg();
|
||||
Frame frame = null;
|
||||
if (sfnumber >= thread.fFrames.size()) {
|
||||
frame = thread.fCurrentFrame;
|
||||
} else {
|
||||
frame = thread.fFrames.get(sfnumber);
|
||||
}
|
||||
sendCommandResponse(printFrame(frame) + "\n");
|
||||
}
|
||||
|
||||
void debugPop(Args args) {
|
||||
PDAThread thread = args.getThreadArg();
|
||||
if (thread == null) {
|
||||
|
@ -819,6 +838,16 @@ public class PDAVirtualMachine {
|
|||
sendCommandResponse(result.toString());
|
||||
}
|
||||
|
||||
void debugStackDepth(Args args) {
|
||||
PDAThread thread = args.getThreadArg();
|
||||
if (thread == null) {
|
||||
sendCommandResponse("error: invalid thread\n");
|
||||
return;
|
||||
}
|
||||
sendCommandResponse( Integer.toString(thread.fFrames.size() + 1) + "\n" );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The stack frame output is: frame # frame # frame ... where each frame is:
|
||||
* filename | line number | function name | var | var | var | var ...
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.eclipse.dd.dsf.datamodel.DMContexts;
|
|||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack2;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
|
||||
|
@ -34,8 +35,12 @@ import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
|
|||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.examples.pda.PDAPlugin;
|
||||
import org.eclipse.dd.examples.pda.service.commands.PDAFrame;
|
||||
import org.eclipse.dd.examples.pda.service.commands.PDAFrameCommand;
|
||||
import org.eclipse.dd.examples.pda.service.commands.PDAFrameCommandResult;
|
||||
import org.eclipse.dd.examples.pda.service.commands.PDAStackCommand;
|
||||
import org.eclipse.dd.examples.pda.service.commands.PDAStackCommandResult;
|
||||
import org.eclipse.dd.examples.pda.service.commands.PDAStackDepthCommand;
|
||||
import org.eclipse.dd.examples.pda.service.commands.PDAStackDepthCommandResult;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
|
@ -46,7 +51,7 @@ import org.osgi.framework.BundleContext;
|
|||
* this service is initialized.
|
||||
* </p>
|
||||
*/
|
||||
public class PDAStack extends AbstractDsfService implements IStack {
|
||||
public class PDAStack extends AbstractDsfService implements IStack2 {
|
||||
|
||||
/**
|
||||
* PDA stack frame contains only the stack frame level. It is only
|
||||
|
@ -221,7 +226,7 @@ public class PDAStack extends AbstractDsfService implements IStack {
|
|||
}
|
||||
|
||||
public void getFrameData(final IFrameDMContext frameCtx, final DataRequestMonitor<IFrameDMData> rm) {
|
||||
PDAThreadDMContext threadCtx =
|
||||
final PDAThreadDMContext threadCtx =
|
||||
DMContexts.getAncestorOfType(frameCtx, PDAThreadDMContext.class);
|
||||
|
||||
if (threadCtx == null) {
|
||||
|
@ -230,23 +235,30 @@ public class PDAStack extends AbstractDsfService implements IStack {
|
|||
return;
|
||||
}
|
||||
|
||||
// Execute the PDA stack command, or retrieve the result from cache if already available.
|
||||
fCommandCache.execute(
|
||||
new PDAStackCommand(threadCtx),
|
||||
new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
|
||||
getStackDepth(
|
||||
threadCtx, -1,
|
||||
new DataRequestMonitor<Integer>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
// PDAFrame array is ordered highest to lowest. We need to
|
||||
// calculate the index based on frame level.
|
||||
int frameId = getData().fFrames.length - frameCtx.getLevel() - 1;
|
||||
if (frameId < 0) {
|
||||
int frameNum = getData() - frameCtx.getLevel() - 1;
|
||||
if (frameNum < 0) {
|
||||
PDAPlugin.failRequest(rm, IDsfStatusConstants.INVALID_HANDLE, "Invalid frame level " + frameCtx);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the frame data object based on the corresponding PDAFrame
|
||||
rm.setData(new FrameDMData(getData().fFrames[frameId]));
|
||||
rm.done();
|
||||
// Execute the PDA stack command, or retrieve the result from cache if already available.
|
||||
fCommandCache.execute(
|
||||
new PDAFrameCommand(threadCtx, frameNum),
|
||||
new DataRequestMonitor<PDAFrameCommandResult>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
// Create the frame data object based on the corresponding PDAFrame
|
||||
rm.setData(new FrameDMData(getData().fFrame));
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -267,13 +279,13 @@ public class PDAStack extends AbstractDsfService implements IStack {
|
|||
}
|
||||
|
||||
// Execute the stack command and create the corresponding frame contexts.
|
||||
fCommandCache.execute(
|
||||
new PDAStackCommand(threadCtx),
|
||||
new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
|
||||
getStackDepth(
|
||||
context, -1,
|
||||
new DataRequestMonitor<Integer>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
IFrameDMContext[] frameCtxs = new IFrameDMContext[getData().fFrames.length];
|
||||
for (int i = 0; i < getData().fFrames.length; i++) {
|
||||
IFrameDMContext[] frameCtxs = new IFrameDMContext[getData()];
|
||||
for (int i = 0; i < getData(); i++) {
|
||||
frameCtxs[i] = new FrameDMContext(getSession().getId(), threadCtx, i);
|
||||
}
|
||||
rm.setData(frameCtxs);
|
||||
|
@ -282,6 +294,38 @@ public class PDAStack extends AbstractDsfService implements IStack {
|
|||
});
|
||||
}
|
||||
|
||||
public void getFrames(IDMContext context, final int startIndex, final int endIndex, final DataRequestMonitor<IFrameDMContext[]> rm) {
|
||||
// Validate index range.
|
||||
assert startIndex >=0 && (endIndex < 0 || startIndex <= endIndex);
|
||||
|
||||
final PDAThreadDMContext threadCtx =
|
||||
DMContexts.getAncestorOfType(context, PDAThreadDMContext.class);
|
||||
|
||||
if (threadCtx == null) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context" + context, null));
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute the stack command and create the corresponding frame contexts.
|
||||
getStackDepth(
|
||||
context, -1,
|
||||
new DataRequestMonitor<Integer>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
int numFrames = endIndex < 0
|
||||
? (getData() - startIndex)
|
||||
: Math.min(endIndex + 1, getData()) - startIndex;
|
||||
IFrameDMContext[] frameCtxs = new IFrameDMContext[numFrames];
|
||||
for (int i = 0; i < numFrames; i++) {
|
||||
frameCtxs[i] = new FrameDMContext(getSession().getId(), threadCtx, startIndex + i);
|
||||
}
|
||||
rm.setData(frameCtxs);
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void getLocals(IFrameDMContext context, final DataRequestMonitor<IVariableDMContext[]> rm) {
|
||||
if (!(context instanceof FrameDMContext)) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context" + context, null));
|
||||
|
@ -324,7 +368,7 @@ public class PDAStack extends AbstractDsfService implements IStack {
|
|||
|
||||
}
|
||||
|
||||
public void getStackDepth(IDMContext context, int maxDepth, final DataRequestMonitor<Integer> rm) {
|
||||
public void getStackDepth(IDMContext context, final int maxDepth, final DataRequestMonitor<Integer> rm) {
|
||||
final PDAThreadDMContext threadCtx =
|
||||
DMContexts.getAncestorOfType(context, PDAThreadDMContext.class);
|
||||
|
||||
|
@ -336,11 +380,15 @@ public class PDAStack extends AbstractDsfService implements IStack {
|
|||
|
||||
// Execute stack command and return the data's size.
|
||||
fCommandCache.execute(
|
||||
new PDAStackCommand(threadCtx),
|
||||
new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
|
||||
new PDAStackDepthCommand(threadCtx),
|
||||
new DataRequestMonitor<PDAStackDepthCommandResult>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
rm.setData(getData().fFrames.length);
|
||||
int depth= getData().fDepth;
|
||||
if (maxDepth > 0 && maxDepth < depth) {
|
||||
depth = maxDepth;
|
||||
}
|
||||
rm.setData(depth);
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River 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:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.examples.pda.service.commands;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.examples.pda.service.PDAThreadDMContext;
|
||||
|
||||
/**
|
||||
* Retrieves command stack frame information
|
||||
*
|
||||
* <pre>
|
||||
* C: stack {thread_id} {frame_number}
|
||||
* R: {file}|{line}|{function}|{var_1}|{var_2}|...
|
||||
*
|
||||
* Errors:
|
||||
* error: invalid thread
|
||||
* </pre>
|
||||
*/
|
||||
@Immutable
|
||||
public class PDAFrameCommand extends AbstractPDACommand<PDAFrameCommandResult> {
|
||||
|
||||
public PDAFrameCommand(PDAThreadDMContext thread, int frameNum) {
|
||||
super(thread, "frame " + thread.getID() + " " + frameNum);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDAFrameCommandResult createResult(String resultText) {
|
||||
return new PDAFrameCommandResult(resultText);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River 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:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.examples.pda.service.commands;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
|
||||
|
||||
/**
|
||||
* @see PDAFrameCommand
|
||||
*/
|
||||
@Immutable
|
||||
public class PDAFrameCommandResult extends PDACommandResult {
|
||||
|
||||
/**
|
||||
* Frame data return by the frame command.
|
||||
*/
|
||||
final public PDAFrame fFrame;
|
||||
|
||||
PDAFrameCommandResult(String response) {
|
||||
super(response);
|
||||
fFrame = new PDAFrame(response);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River 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:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.examples.pda.service.commands;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.examples.pda.service.PDAThreadDMContext;
|
||||
|
||||
/**
|
||||
* Retrieves command stack depth
|
||||
*
|
||||
* <pre>
|
||||
* C: stackdepth {thread_id}
|
||||
* R: {depth}
|
||||
*
|
||||
* Errors:
|
||||
* error: invalid thread
|
||||
* </pre>
|
||||
*/
|
||||
@Immutable
|
||||
public class PDAStackDepthCommand extends AbstractPDACommand<PDAStackDepthCommandResult> {
|
||||
|
||||
public PDAStackDepthCommand(PDAThreadDMContext thread) {
|
||||
super(thread, "stackdepth " + thread.getID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PDAStackDepthCommandResult createResult(String resultText) {
|
||||
return new PDAStackDepthCommandResult(resultText);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River 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:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.examples.pda.service.commands;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
|
||||
|
||||
/**
|
||||
* @see PDADataCommand
|
||||
*/
|
||||
@Immutable
|
||||
public class PDAStackDepthCommandResult extends PDACommandResult {
|
||||
|
||||
final public int fDepth;
|
||||
|
||||
PDAStackDepthCommandResult(String response) {
|
||||
super(response);
|
||||
int depth = 1; // default to something that won't cause NPEs
|
||||
try {
|
||||
depth = Integer.parseInt(response);
|
||||
} catch (NumberFormatException e) {}
|
||||
fDepth = depth;
|
||||
}
|
||||
}
|
|
@ -114,14 +114,21 @@ public class CommandControlTestsBase {
|
|||
fCommandControl.queueCommand(testCommand, rm);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
String responseText = null;
|
||||
fExecutor.execute(sendCommandQuery);
|
||||
try {
|
||||
PDACommandResult result = sendCommandQuery.get();
|
||||
Assert.assertEquals("Command returned an unexpected result", expectedResult, result.fResponseText);
|
||||
responseText = result.fResponseText;
|
||||
} catch (ExecutionException e) {
|
||||
throw e.getCause();
|
||||
if (e.getCause() instanceof CoreException) {
|
||||
responseText = ((CoreException)e.getCause()).getStatus().getMessage();
|
||||
} else {
|
||||
throw e.getCause();
|
||||
}
|
||||
}
|
||||
Assert.assertEquals("Command returned an unexpected result", expectedResult, responseText);
|
||||
|
||||
}
|
||||
|
||||
protected void clearEvents() {
|
||||
|
|
|
@ -58,6 +58,10 @@ public class Test2 extends CommandControlTestsBase {
|
|||
expectEvent("vmsuspended 1 breakpoint 12");
|
||||
sendCommand("clear 19");
|
||||
sendCommand("stack 1", fProgram + "|6|main#" + fProgram + "|18|sub1|m|n#" + fProgram + "|12|sub2" );
|
||||
sendCommand("stackdepth 1", "3");
|
||||
sendCommand("frame 1 0", fProgram + "|6|main");
|
||||
sendCommand("frame 1 1", fProgram + "|18|sub1|m|n");
|
||||
sendCommand("frame 1 2", fProgram + "|12|sub2" );
|
||||
sendCommand("stepreturn 1");
|
||||
expectEvent("vmresumed step");
|
||||
expectEvent("vmsuspended 1 step");
|
||||
|
@ -139,6 +143,10 @@ public class Test2 extends CommandControlTestsBase {
|
|||
expectEvent("suspended 1 breakpoint 12");
|
||||
sendCommand("clear 19");
|
||||
sendCommand("stack 1", fProgram + "|6|main#" + fProgram + "|18|sub1|m|n#" + fProgram + "|12|sub2" );
|
||||
sendCommand("stackdepth 1", "3");
|
||||
sendCommand("frame 1 0", fProgram + "|6|main");
|
||||
sendCommand("frame 1 1", fProgram + "|18|sub1|m|n");
|
||||
sendCommand("frame 1 2", fProgram + "|12|sub2" );
|
||||
sendCommand("stepreturn 1");
|
||||
expectEvent("resumed 1 step");
|
||||
expectEvent("suspended 1 step");
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
|
|||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack2;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
|
||||
|
@ -54,7 +55,7 @@ import org.eclipse.dd.mi.service.command.output.MIStackListLocalsInfo;
|
|||
import org.osgi.framework.BundleContext;
|
||||
|
||||
public class MIStack extends AbstractDsfService
|
||||
implements IStack
|
||||
implements IStack2
|
||||
{
|
||||
protected static class MIFrameDMC extends AbstractDMContext
|
||||
implements IFrameDMContext
|
||||
|
@ -194,22 +195,55 @@ public class MIStack extends AbstractDsfService
|
|||
return new MIFrameDMC(getSession().getId(), execDmc, level);
|
||||
}
|
||||
|
||||
public void getFrames(final IDMContext ctx, final DataRequestMonitor<IFrameDMContext[]> rm) {
|
||||
public void getFrames(final IDMContext ctx, final DataRequestMonitor<IFrameDMContext[]> rm) {
|
||||
getFrames(ctx, 0, ALL_FRAMES, rm);
|
||||
}
|
||||
|
||||
public void getFrames(final IDMContext ctx, final int startIndex, final int endIndex, final DataRequestMonitor<IFrameDMContext[]> rm) {
|
||||
|
||||
if (startIndex < 0 || endIndex > 0 && endIndex < startIndex) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid stack frame range [" + startIndex + ',' + endIndex + ']', null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(ctx, IMIExecutionDMContext.class);
|
||||
|
||||
if (execDmc == null) {
|
||||
//rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, -1, "No frame context found in " + ctx, null)); //$NON-NLS-1$
|
||||
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context" + ctx, null)); //$NON-NLS-1$
|
||||
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context " + ctx, null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
fMICommandCache.execute(
|
||||
new MIStackListFrames(execDmc),
|
||||
|
||||
if (startIndex == 0 && endIndex == 0) {
|
||||
// Try to retrieve the top stack frame from the cached stopped event.
|
||||
if (fCachedStoppedEvent != null &&
|
||||
fCachedStoppedEvent.getFrame() != null &&
|
||||
execDmc.equals(fCachedStoppedEvent.getDMContext()))
|
||||
{
|
||||
rm.setData(new IFrameDMContext[] { createFrameDMContext(execDmc, fCachedStoppedEvent.getFrame().getLevel()) });
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final MIStackListFrames miStackListCmd;
|
||||
// firstIndex is the first index retrieved
|
||||
final int firstIndex;
|
||||
if (endIndex >= 0) {
|
||||
miStackListCmd = new MIStackListFrames(execDmc, startIndex, endIndex);
|
||||
firstIndex = startIndex;
|
||||
} else {
|
||||
miStackListCmd = new MIStackListFrames(execDmc);
|
||||
firstIndex = 0;
|
||||
}
|
||||
fMICommandCache.execute(
|
||||
miStackListCmd,
|
||||
new DataRequestMonitor<MIStackListFramesInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
rm.setData(getFrames(execDmc, getData()));
|
||||
rm.setData(getFrames(execDmc, getData(), firstIndex, endIndex, startIndex));
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
|
@ -234,9 +268,11 @@ public class MIStack extends AbstractDsfService
|
|||
}
|
||||
|
||||
// If stopped event is not available or doesn't contain frame info,
|
||||
// query the full list of frames.
|
||||
// query top stack frame
|
||||
getFrames(
|
||||
ctx,
|
||||
0,
|
||||
0,
|
||||
new DataRequestMonitor<IFrameDMContext[]>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
|
@ -247,11 +283,20 @@ public class MIStack extends AbstractDsfService
|
|||
}
|
||||
|
||||
//private MIFrameDMC[] getFrames(DsfMIStackListFramesInfo info) {
|
||||
private IFrameDMContext[] getFrames(IMIExecutionDMContext execDmc, MIStackListFramesInfo info) {
|
||||
IFrameDMContext[] frameDMCs = new MIFrameDMC[info.getMIFrames().length];
|
||||
for (int i = 0; i < info.getMIFrames().length; i++) {
|
||||
private IFrameDMContext[] getFrames(IMIExecutionDMContext execDmc, MIStackListFramesInfo info, int firstIndex, int lastIndex, int startIndex) {
|
||||
int length = info.getMIFrames().length;
|
||||
if (lastIndex > 0) {
|
||||
int limit= lastIndex - startIndex + 1;
|
||||
if (limit < length) {
|
||||
length = limit;
|
||||
}
|
||||
}
|
||||
IFrameDMContext[] frameDMCs = new MIFrameDMC[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
//frameDMCs[i] = new MIFrameDMC(this, info.getMIFrames()[i].getLevel());
|
||||
frameDMCs[i] = createFrameDMContext(execDmc, info.getMIFrames()[i].getLevel());
|
||||
final MIFrame frame= info.getMIFrames()[i + startIndex - firstIndex];
|
||||
assert startIndex + i == frame.getLevel();
|
||||
frameDMCs[i] = createFrameDMContext(execDmc, frame.getLevel());
|
||||
}
|
||||
return frameDMCs;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue