diff --git a/dsf/org.eclipse.cdt.dsf.ui/plugin.xml b/dsf/org.eclipse.cdt.dsf.ui/plugin.xml index f497bc65a96..e7fa3c0c9fe 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/plugin.xml +++ b/dsf/org.eclipse.cdt.dsf.ui/plugin.xml @@ -447,6 +447,7 @@ fRunnableQueue = new ArrayList(); @@ -310,11 +320,39 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem private ArrayList fHandlerActivations; private IContextActivation fContextActivation; - private IDisassemblyBackend fBackend; + private IDisassemblyBackend fBackend; private AddressBarContributionItem fAddressBar = null; private Action fJumpToAddressAction = new JumpToAddressAction(this); + private final class SyncActiveDebugContextAction extends Action { + public SyncActiveDebugContextAction() { + setChecked(DisassemblyPart.this.isSyncWithActiveDebugContext()); + setText(DisassemblyMessages.Disassembly_action_Sync_label); + setImageDescriptor(DisassemblyImageRegistry.getImageDescriptor(DisassemblyImageRegistry.ICON_Sync_enabled)); + setDisabledImageDescriptor(DisassemblyImageRegistry.getImageDescriptor(DisassemblyImageRegistry.ICON_Sync_disabled)); + } + + @Override + public void run() { + DisassemblyPart.this.setSyncWithDebugView(this.isChecked()); + } + } + + private final class TrackExpressionAction extends Action { + public TrackExpressionAction() { + setChecked(DisassemblyPart.this.isTrackExpression()); + setEnabled(!fSynchWithActiveDebugContext); + setText(DisassemblyMessages.Disassembly_action_TrackExpression_label); + } + + @Override + public void run() { + DisassemblyPart.this.setTrackExpression(this.isChecked()); + } + + } + private final class ActionRefreshView extends AbstractDisassemblyAction { public ActionRefreshView() { super(DisassemblyPart.this); @@ -324,10 +362,11 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } @Override public void run() { + fPCLastAddress = getTopAddress(); refreshView(10); } } - + private final class ActionToggleAddressColumn extends AbstractDisassemblyAction { ActionToggleAddressColumn () { super(DisassemblyPart.this); @@ -1157,11 +1196,11 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem fActionToggleSymbols.update(); manager.add(new GroupMarker("group.top")); // ICommonMenuConstants.GROUP_TOP //$NON-NLS-1$ manager.add(new Separator("group.breakpoints")); //$NON-NLS-1$ - manager.add(new Separator(IWorkbenchActionConstants.GO_TO)); manager.add(new Separator("group.debug")); //$NON-NLS-1$ manager.add(new Separator(ITextEditorActionConstants.GROUP_EDIT)); manager.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, fGlobalActions.get(ITextEditorActionConstants.COPY)); manager.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, fGlobalActions.get(ITextEditorActionConstants.SELECT_ALL)); + // TODO add only if this is an editor manager.add(new Separator(ITextEditorActionConstants.GROUP_SETTINGS)); manager.add(fActionToggleSource); manager.add(fActionToggleSymbols); @@ -1206,7 +1245,10 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem manager.add(new Separator()); manager.add(fActionRefreshView); manager.add(fActionGotoPC); + manager.add(fSyncAction); manager.add(fActionToggleSource); + // Other plug-ins can contribute their actions here + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); } protected void updateSelectionDependentActions() { @@ -1286,6 +1328,8 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem fActionToggleFunctionColumn = new ActionToggleFunctionColumn(); fActionToggleSymbols = new ActionToggleSymbols(); fActionRefreshView = new ActionRefreshView(); + fSyncAction = new SyncActiveDebugContextAction(); + fTrackExpressionAction = new TrackExpressionAction(); fStateDependentActions.add(fActionRefreshView); fGlobalActions.put(ActionFactory.REFRESH.getId(), fActionRefreshView); fActionOpenPreferences = new ActionOpenPreferences(getSite().getShell()); @@ -1309,7 +1353,8 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem */ public final void gotoProgramCounter() { if (fPCAddress != PC_RUNNING) { - updatePC(fPCAddress); + fPCLastAddress = PC_UNKNOWN; + gotoFrame(getActiveStackFrame()); } } @@ -1322,6 +1367,16 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } } + public final void gotoLocationByUser(BigInteger address, String locationTxt) { + fPCLastAddress = address; + fPCLastLocationTxt = locationTxt; + gotoAddress(address); + } + + public final void gotoActiveFrameByUser() { + gotoFrame(getActiveStackFrame()); + } + /* * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#gotoAddress(java.math.BigInteger) */ @@ -2043,6 +2098,24 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem public void gotoFrame(int frame, BigInteger address) { assert isGuiThread(); if (DEBUG) System.out.println("gotoFrame " + frame + " " + getAddressText(address)); //$NON-NLS-1$ //$NON-NLS-2$ + + // cache the last PC address + if (!isSyncWithActiveDebugContext()) { + if (isTrackExpression()) { + if (!DisassemblyMessages.Disassembly_GotoLocation_initial_text.equals(fPCLastLocationTxt)) + fPCLastAddress = eval(fPCLastLocationTxt); + } + if (fPCLastAddress != PC_UNKNOWN) { + address = fPCLastAddress; + } else if (address != PC_UNKNOWN) { + fPCLastAddress = address; + } + + frame = -2; // clear the annotation + } else { + fPCLastAddress = address; + } + if (fGotoAddressPending == fFrameAddress) { // cancel goto address from previous goto frame fGotoAddressPending = PC_UNKNOWN; @@ -2112,7 +2185,7 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem return false; } - return (fBackend != null) ? fBackend.hasDebugContext() : false; + return (fBackend != null) ? fBackend.hasDebugContext() : false; } /* @@ -2279,12 +2352,16 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem fPCAnnotationUpdatePending = true; return null; } - AddressRangePosition pos; + AddressRangePosition pos = null; if (fTargetFrame == 0) { // clear secondary updateAddressAnnotation(fSecondaryPCAnnotation, PC_UNKNOWN); // set primary pos = updateAddressAnnotation(fPCAnnotation, fPCAddress); + } else if (fTargetFrame < 0) { + // clear both + updateAddressAnnotation(fPCAnnotation, PC_UNKNOWN); + updateAddressAnnotation(fSecondaryPCAnnotation, PC_UNKNOWN); } else { // clear primary updateAddressAnnotation(fPCAnnotation, PC_UNKNOWN); @@ -2754,21 +2831,21 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } public void generateErrorDialog(String message) { - MessageDialog messageDialog = new MessageDialog(PlatformUI.getWorkbench().getDisplay().getActiveShell(), DisassemblyMessages.Disassembly_Error_Dialog_title, null, message, MessageDialog.ERROR, new String[]{DisassemblyMessages.Disassembly_Error_Dialog_ok_button}, 0); - messageDialog.open(); + MessageDialog messageDialog = new MessageDialog(PlatformUI.getWorkbench().getDisplay().getActiveShell(), DisassemblyMessages.Disassembly_Error_Dialog_title, null, message, MessageDialog.ERROR, new String[]{DisassemblyMessages.Disassembly_Error_Dialog_ok_button}, 0); + messageDialog.open(); } public void activateDisassemblyContext() { IContextService ctxService = (IContextService)getSite().getService(IContextService.class); if (ctxService!=null) - fContextActivation = ctxService.activateContext(KEY_BINDING_CONTEXT_DISASSEMBLY); + fContextActivation = ctxService.activateContext(KEY_BINDING_CONTEXT_DISASSEMBLY); } public void deactivateDisassemblyContext() { if (fContextActivation != null) { IContextService ctxService = (IContextService)getSite().getService(IContextService.class); ctxService.deactivateContext(fContextActivation); - } + } } /* (non-Javadoc) @@ -2802,23 +2879,22 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem asyncExec(new Runnable() { public void run() { fDebugSessionId = null; - debugContextChanged(); + debugContextChanged(); } - }); - + }); } /* (non-Javadoc) * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#setUpdatePending(boolean) */ - public void setUpdatePending(boolean pending) { + public void setUpdatePending(boolean pending) { fUpdatePending = pending; } /* (non-Javadoc) * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#getUpdatePending() */ - public boolean getUpdatePending() { + public boolean getUpdatePending() { assert isGuiThread(); return fUpdatePending; } @@ -2865,6 +2941,51 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem return ""; //$NON-NLS-1$ } + public BigInteger eval(String expr) { + String location = evaluateExpression(expr); + if (location != null) { + StringTokenizer st = new StringTokenizer(location); + if (st.hasMoreTokens()) { + try { + return DisassemblyUtils.decodeAddress(st.nextToken()); + } catch (Exception e) { + logWarning("Failed to evaluate expression " + expr, e); //$NON-NLS-1$ + } + } + } + return PC_UNKNOWN; + } + + protected boolean isTrackExpression() { + return fTrackExpression; + } + + private void setTrackExpression(boolean track) { + fTrackExpression = track; + } + + protected boolean isSyncWithActiveDebugContext() { + return fSynchWithActiveDebugContext; + } + + private void setSyncWithDebugView(boolean sync) { + fSynchWithActiveDebugContext = sync; + fTrackExpressionAction.setEnabled(!sync); + + if (sync) { + gotoActiveFrameByUser(); + } else { + // redraw + while (!fPCHistory.isEmpty()) { + AddressRangePosition pos = fPCHistory.removeFirst(); + fViewer.invalidateTextPresentation(pos.offset, pos.length); + } + + fTargetFrame = -2; // clear the annotation + updatePCAnnotation(); + } + } + /** * Most methods in IDisassemblyPartCallback require execution on the GUI thread. */ diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyView.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyView.java index ae7bc5a52c1..82d1c90e21c 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyView.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyView.java @@ -7,9 +7,11 @@ * * Contributors: * Wind River Systems - initial API and implementation + * Patrick Chuong (Texas Instruments) - Bug fix (326670) *******************************************************************************/ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly; +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.preferences.DisassemblyPreferenceConstants; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.contexts.DebugContextEvent; import org.eclipse.debug.ui.contexts.IDebugContextListener; @@ -19,8 +21,10 @@ import org.eclipse.ui.IActionBars; import org.eclipse.ui.IMemento; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.PartInitException; import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.texteditor.ITextEditorActionConstants; /** * DisassemblyView @@ -60,6 +64,15 @@ public class DisassemblyView extends DisassemblyPart implements IViewPart { */ public void init(IViewSite site, IMemento memento) throws PartInitException { setSite(site); + if (memento != null) { + Boolean trackExpression = memento.getBoolean(DisassemblyPreferenceConstants.TRACK_EXPRESSION); + if (trackExpression != null) + fTrackExpression = trackExpression; + Boolean syncContext = memento.getBoolean(DisassemblyPreferenceConstants.SYNC_ACTIVE_CONTEXT); + if (syncContext != null) + fSynchWithActiveDebugContext = syncContext; + } + DebugUITools.getDebugContextManager().addDebugContextListener(fDebugContextListener = new IDebugContextListener() { public void debugContextChanged(DebugContextEvent event) { if ((event.getFlags() & DebugContextEvent.ACTIVATED) != 0) { @@ -73,8 +86,10 @@ public class DisassemblyView extends DisassemblyPart implements IViewPart { * @see org.eclipse.ui.IViewPart#saveState(org.eclipse.ui.IMemento) */ public void saveState(IMemento memento) { + memento.putBoolean(DisassemblyPreferenceConstants.TRACK_EXPRESSION, isTrackExpression()); + memento.putBoolean(DisassemblyPreferenceConstants.SYNC_ACTIVE_CONTEXT, isSyncWithActiveDebugContext()); } - + @Override protected void contributeToActionBars(IActionBars bars) { super.contributeToActionBars(bars); @@ -84,10 +99,18 @@ public class DisassemblyView extends DisassemblyPart implements IViewPart { protected void fillLocalPullDown(IMenuManager manager) { manager.add(fGlobalActions.get(ActionFactory.FIND.getId())); + manager.add(new Separator("group.goto")); // ICommonMenuConstants.GROUP_GOTO //$NON-NLS-1$ manager.add(fActionGotoPC); manager.add(fActionGotoAddress); - manager.add(fActionToggleSource); - manager.add(new Separator()); + manager.add(new Separator("group.show")); // ICommonMenuConstants.GROUP_SHOW //$NON-NLS-1$ + manager.add(fSyncAction); + manager.add(fTrackExpressionAction); + manager.add(new Separator(ITextEditorActionConstants.GROUP_SETTINGS)); + manager.add(fActionToggleSource); + manager.add(fActionToggleSymbols); + manager.add(fActionOpenPreferences); + // Other plug-ins can contribute their actions here + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); } @Override diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/JumpToAddressAction.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/JumpToAddressAction.java index a60ec2c69d4..ee3283be864 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/JumpToAddressAction.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/JumpToAddressAction.java @@ -7,6 +7,7 @@ * * Contributors: * Texas Instruments[nmehregani] - initial API and implementation + * Patrick Chuong (Texas Instruments) - Bug fix (326670) *******************************************************************************/ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions; @@ -16,7 +17,6 @@ import java.math.BigInteger; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyMessages; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyPart; import org.eclipse.jface.action.Action; -import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.decodeAddress; public class JumpToAddressAction extends Action { @@ -30,36 +30,26 @@ public class JumpToAddressAction extends Action { public void run() { AddressBarContributionItem addressBar = fDisassemblyPart.getAddressBar(); if (addressBar!=null && addressBar.isEnabled() && fDisassemblyPart.isSuspended()) { - String location = addressBar.getText(); + String locationTxt = addressBar.getText(); - if (location==null || location.trim().length()==0) + if (locationTxt==null || locationTxt.trim().length()==0) return; - location = location.trim(); - BigInteger address = null; - try { - address = decodeAddress(location); - if (address.compareTo(BigInteger.ZERO) < 0) { - address = null; - addressBar.setWarningIconVisible(true); - fDisassemblyPart.generateErrorDialog(DisassemblyMessages.Disassembly_GotoAddressDialog_error_invalid_address); - return; - } - } catch (NumberFormatException x) { - // This will be handled below. location will be treated as a symbol - } + locationTxt = locationTxt.trim(); + + if (locationTxt.equals(DisassemblyMessages.Disassembly_GotoLocation_initial_text)) { + fDisassemblyPart.gotoActiveFrameByUser(); + return; + } - // hide warning icon if it was shown before - addressBar.setWarningIconVisible(false); - - /* Location is an address */ - if (address!=null) { - fDisassemblyPart.gotoAddress(address); + BigInteger address = fDisassemblyPart.eval(locationTxt); + if (address.compareTo(BigInteger.ZERO) < 0) { + addressBar.setWarningIconVisible(true); + fDisassemblyPart.generateErrorDialog(DisassemblyMessages.Disassembly_GotoAddressDialog_error_invalid_address); + } else { + fDisassemblyPart.gotoLocationByUser(address, locationTxt); + addressBar.setWarningIconVisible(false); } - /* Location is a symbol */ - else { - fDisassemblyPart.gotoSymbol(location); - } } } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferenceConstants.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferenceConstants.java index 45166e291ae..d35f2d1c652 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferenceConstants.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferenceConstants.java @@ -37,7 +37,9 @@ public class DisassemblyPreferenceConstants { public static final String SHOW_FUNCTION_OFFSETS = "disassembly.showFunctionOffsetRuler"; //$NON-NLS-1$ public static final String FUNCTION_OFFSETS_COLOR = "disassembly.functionOffsetsColor"; //$NON-NLS-1$ public static final String AVOID_READ_BEFORE_PC = "disassembly.avoidReadBeforePC"; //$NON-NLS-1$ - + public static final String TRACK_EXPRESSION = "disassembly.trackExpression"; //$NON-NLS-1$ + public static final String SYNC_ACTIVE_CONTEXT = "disassembly.syncActiveContext"; //$NON-NLS-1$ + /** * */