From 98eadefa280c3d564d4ace60059c0a911f00c20e Mon Sep 17 00:00:00 2001 From: Anton Leherbauer Date: Wed, 24 Feb 2010 09:15:41 +0000 Subject: [PATCH] Bug 302925 - [disassembly][dsf] Endless loop retrieving disassembly data --- .../dsf/CDIDisassemblyRetrieval.java | 12 ++- .../dsf/DisassemblyBackendCdi.java | 73 +++++++++++++------ .../dsf/IDisassemblyRetrieval.java | 3 +- 3 files changed, 61 insertions(+), 27 deletions(-) diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/CDIDisassemblyRetrieval.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/CDIDisassemblyRetrieval.java index 7751e433401..18cc8b198c7 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/CDIDisassemblyRetrieval.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/CDIDisassemblyRetrieval.java @@ -46,7 +46,7 @@ public class CDIDisassemblyRetrieval implements IDisassemblyRetrieval { /* * @see org.eclipse.cdt.debug.ui.infinitedisassembly.views.IDisassemblyRetrieval#asyncGetDisassembly(java.math.BigInteger, java.math.BigInteger, java.lang.String, int, org.eclipse.cdt.debug.ui.infinitedisassembly.views.IDisassemblyRetrieval.DisassemblyRequest) */ - public void asyncGetDisassembly(final BigInteger startAddress, final BigInteger endAddress, final String file, final int lineNumber, final int lines, final DisassemblyRequest disassemblyRequest) { + public void asyncGetDisassembly(final BigInteger startAddress, final BigInteger endAddress, final String file, final int lineNumber, final int lines, final boolean mixed, final DisassemblyRequest disassemblyRequest) { Runnable op= new Runnable() { public void run() { ICDITarget cdiTarget= (ICDITarget) fDebugTarget.getAdapter(ICDITarget.class); @@ -54,10 +54,16 @@ public class CDIDisassemblyRetrieval implements IDisassemblyRetrieval { ICDIMixedInstruction[] mixedInstructions= null; ICDIInstruction[] asmInstructions= null; if (file != null) { - mixedInstructions= cdiTarget.getMixedInstructions(file, lineNumber, lines); + if (mixed) { + mixedInstructions= cdiTarget.getMixedInstructions(file, lineNumber, lines); + } else { + asmInstructions= cdiTarget.getInstructions(file, lineNumber, lines); + } } else if (startAddress != null) { - mixedInstructions= cdiTarget.getMixedInstructions(startAddress, endAddress); + if (mixed) { + mixedInstructions= cdiTarget.getMixedInstructions(startAddress, endAddress); + } if (mixedInstructions == null || mixedInstructions.length == 0) { mixedInstructions= null; asmInstructions= cdiTarget.getInstructions(startAddress, endAddress); diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyBackendCdi.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyBackendCdi.java index 22784201200..76f81215d37 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyBackendCdi.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyBackendCdi.java @@ -255,8 +255,8 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyBackend#retrieveDisassembly(java.math.BigInteger, java.math.BigInteger, java.lang.String, boolean, boolean, boolean, int, int, int) */ public void retrieveDisassembly(final BigInteger startAddress, - BigInteger endAddress, String file, int lineNumber, int lines, final boolean mixed, - final boolean showSymbols, final boolean showDisassembly, int linesHint) { + BigInteger endAddress, final String file, int lineNumber, final int lines, final boolean mixed, + final boolean showSymbols, final boolean showDisassembly, final int linesHint) { if (fTargetContext == null || fTargetContext.isTerminated()) { return; @@ -265,28 +265,44 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe if (endAddress.subtract(startAddress).compareTo(addressLength) > 0) { endAddress= startAddress.add(addressLength); } - final BigInteger finalEndAddress= endAddress; + final BigInteger finalEndAddress= startAddress.add(BigInteger.valueOf(32)).max(endAddress); final IDisassemblyRetrieval.DisassemblyRequest disassemblyRequest= new DisassemblyRequest() { @Override public void done() { if (isSuccess() && getDisassemblyBlock() != null) { - insertDisassembly(startAddress, getDisassemblyBlock(), mixed, showSymbols, showDisassembly); - } else { - final IStatus status= getStatus(); - if (status != null && !status.isOK()) { - if (startAddress != null) { + if (!insertDisassembly(startAddress, getDisassemblyBlock(), mixed, showSymbols, showDisassembly)) { + // did not get disassembly data for startAddress - try fallbacks + if (file != null) { + // retry using plain address only + fCallback.setUpdatePending(true); + retrieveDisassembly(startAddress, finalEndAddress, null, -1, lines, mixed, showSymbols, showDisassembly, linesHint); + } else if (mixed) { + // retry using non-mixed mode + fCallback.setUpdatePending(true); + retrieveDisassembly(startAddress, finalEndAddress, null, -1, lines, false, showSymbols, showDisassembly, linesHint); + } else { + // give up fCallback.doScrollLocked(new Runnable() { public void run() { - fCallback.insertError(startAddress, status.getMessage()); + fCallback.insertError(startAddress, "Unable to retrieve disassembly data from backend."); //$NON-NLS-1$ } }); } } + } else { + final IStatus status= getStatus(); + if (status != null && !status.isOK()) { + fCallback.doScrollLocked(new Runnable() { + public void run() { + fCallback.insertError(startAddress, status.getMessage()); + } + }); + } fCallback.setUpdatePending(false); } } }; - fDisassemblyRetrieval.asyncGetDisassembly(startAddress, finalEndAddress, file, lineNumber, lines, disassemblyRequest); + fDisassemblyRetrieval.asyncGetDisassembly(startAddress, finalEndAddress, file, lineNumber, lines, mixed, disassemblyRequest); } @@ -399,18 +415,21 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe assert !fCallback.getUpdatePending(); fCallback.setUpdatePending(true); - fDisassemblyRetrieval.asyncGetDisassembly(null, endAddress, file, 1, lines, disassemblyRequest); + fDisassemblyRetrieval.asyncGetDisassembly(null, endAddress, file, 1, lines, true, disassemblyRequest); } - private void insertDisassembly(BigInteger startAddress, IDisassemblyBlock disassemblyBlock, boolean mixed, boolean showSymbols, boolean showDisassembly) { + private boolean insertDisassembly(BigInteger startAddress, IDisassemblyBlock disassemblyBlock, boolean mixed, boolean showSymbols, boolean showDisassembly) { if (!fCallback.hasViewer() || fCdiSessionId == null) { - return; + return true; } if (!fCallback.getUpdatePending()) { assert false; - return; + return true; } + + boolean insertedStartAddress = startAddress == null; + try { fCallback.lockScroller(); @@ -440,14 +459,14 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe p.fValid = false; document.addInvalidAddressRange(p); } else if (p == null) { - return; + return insertedStartAddress; } else if (p.fValid) { if (srcElement != null && lineNumber >= 0 || p.fAddressLength == BigInteger.ONE) { // override probably unaligned disassembly p.fValid = false; document.addInvalidAddressRange(p); } else { - return; + return insertedStartAddress; } } boolean hasSource= false; @@ -493,8 +512,10 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe break; } } else { - if (instructions.length == 1 && srcLines.length == 1) { - instrLength= p.fAddressLength; + if (instructions.length == 1) { + if (p.fAddressLength.compareTo(BigInteger.valueOf(8)) <= 0) { + instrLength= p.fAddressLength; + } } } if (instrLength == null) { @@ -513,7 +534,8 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe } else { p = document.insertDisassemblyLine(p, address, instrLength.intValue(), opCode, instruction.getInstructionText(), compilationPath, lineNumber); //$NON-NLS-1 } - if (p == null) { + insertedStartAddress= insertedStartAddress || address.compareTo(startAddress) == 0; + if (p == null && insertedStartAddress) { break; } } @@ -525,11 +547,16 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe DisassemblyUtils.internalError(e); } finally { fCallback.setUpdatePending(false); - fCallback.updateInvalidSource(); - fCallback.unlockScroller(); - fCallback.doPending(); - fCallback.updateVisibleArea(); + if (insertedStartAddress) { + fCallback.updateInvalidSource(); + fCallback.unlockScroller(); + fCallback.doPending(); + fCallback.updateVisibleArea(); + } else { + fCallback.unlockScroller(); + } } + return insertedStartAddress; } /* (non-Javadoc) diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyRetrieval.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyRetrieval.java index 4508c9b39e4..4d3847f4128 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyRetrieval.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyRetrieval.java @@ -42,10 +42,11 @@ public interface IDisassemblyRetrieval { * @param endAddress * @param file * @param lines + * @param mixed whether mixed assembly is preferred * @param disassemblyRequest */ void asyncGetDisassembly(BigInteger startAddress, BigInteger endAddress, String file, int fileNumber, int lines, - DisassemblyRequest disassemblyRequest); + boolean mixed, DisassemblyRequest disassemblyRequest); }