1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 14:12:10 +02:00

Bug 302925 - [disassembly][dsf] Endless loop retrieving disassembly data

This commit is contained in:
Anton Leherbauer 2010-02-24 09:15:41 +00:00
parent 35de77c32b
commit 98eadefa28
3 changed files with 61 additions and 27 deletions

View file

@ -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) * @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() { Runnable op= new Runnable() {
public void run() { public void run() {
ICDITarget cdiTarget= (ICDITarget) fDebugTarget.getAdapter(ICDITarget.class); ICDITarget cdiTarget= (ICDITarget) fDebugTarget.getAdapter(ICDITarget.class);
@ -54,10 +54,16 @@ public class CDIDisassemblyRetrieval implements IDisassemblyRetrieval {
ICDIMixedInstruction[] mixedInstructions= null; ICDIMixedInstruction[] mixedInstructions= null;
ICDIInstruction[] asmInstructions= null; ICDIInstruction[] asmInstructions= null;
if (file != null) { if (file != null) {
if (mixed) {
mixedInstructions= cdiTarget.getMixedInstructions(file, lineNumber, lines); mixedInstructions= cdiTarget.getMixedInstructions(file, lineNumber, lines);
} else {
asmInstructions= cdiTarget.getInstructions(file, lineNumber, lines);
}
} }
else if (startAddress != null) { else if (startAddress != null) {
if (mixed) {
mixedInstructions= cdiTarget.getMixedInstructions(startAddress, endAddress); mixedInstructions= cdiTarget.getMixedInstructions(startAddress, endAddress);
}
if (mixedInstructions == null || mixedInstructions.length == 0) { if (mixedInstructions == null || mixedInstructions.length == 0) {
mixedInstructions= null; mixedInstructions= null;
asmInstructions= cdiTarget.getInstructions(startAddress, endAddress); asmInstructions= cdiTarget.getInstructions(startAddress, endAddress);

View file

@ -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) * @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, public void retrieveDisassembly(final BigInteger startAddress,
BigInteger endAddress, String file, int lineNumber, int lines, final boolean mixed, BigInteger endAddress, final String file, int lineNumber, final int lines, final boolean mixed,
final boolean showSymbols, final boolean showDisassembly, int linesHint) { final boolean showSymbols, final boolean showDisassembly, final int linesHint) {
if (fTargetContext == null || fTargetContext.isTerminated()) { if (fTargetContext == null || fTargetContext.isTerminated()) {
return; return;
@ -265,28 +265,44 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe
if (endAddress.subtract(startAddress).compareTo(addressLength) > 0) { if (endAddress.subtract(startAddress).compareTo(addressLength) > 0) {
endAddress= startAddress.add(addressLength); endAddress= startAddress.add(addressLength);
} }
final BigInteger finalEndAddress= endAddress; final BigInteger finalEndAddress= startAddress.add(BigInteger.valueOf(32)).max(endAddress);
final IDisassemblyRetrieval.DisassemblyRequest disassemblyRequest= new DisassemblyRequest() { final IDisassemblyRetrieval.DisassemblyRequest disassemblyRequest= new DisassemblyRequest() {
@Override @Override
public void done() { public void done() {
if (isSuccess() && getDisassemblyBlock() != null) { if (isSuccess() && getDisassemblyBlock() != null) {
insertDisassembly(startAddress, getDisassemblyBlock(), mixed, showSymbols, showDisassembly); 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, "Unable to retrieve disassembly data from backend."); //$NON-NLS-1$
}
});
}
}
} else { } else {
final IStatus status= getStatus(); final IStatus status= getStatus();
if (status != null && !status.isOK()) { if (status != null && !status.isOK()) {
if (startAddress != null) {
fCallback.doScrollLocked(new Runnable() { fCallback.doScrollLocked(new Runnable() {
public void run() { public void run() {
fCallback.insertError(startAddress, status.getMessage()); fCallback.insertError(startAddress, status.getMessage());
} }
}); });
} }
}
fCallback.setUpdatePending(false); 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(); assert !fCallback.getUpdatePending();
fCallback.setUpdatePending(true); 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) { if (!fCallback.hasViewer() || fCdiSessionId == null) {
return; return true;
} }
if (!fCallback.getUpdatePending()) { if (!fCallback.getUpdatePending()) {
assert false; assert false;
return; return true;
} }
boolean insertedStartAddress = startAddress == null;
try { try {
fCallback.lockScroller(); fCallback.lockScroller();
@ -440,14 +459,14 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe
p.fValid = false; p.fValid = false;
document.addInvalidAddressRange(p); document.addInvalidAddressRange(p);
} else if (p == null) { } else if (p == null) {
return; return insertedStartAddress;
} else if (p.fValid) { } else if (p.fValid) {
if (srcElement != null && lineNumber >= 0 || p.fAddressLength == BigInteger.ONE) { if (srcElement != null && lineNumber >= 0 || p.fAddressLength == BigInteger.ONE) {
// override probably unaligned disassembly // override probably unaligned disassembly
p.fValid = false; p.fValid = false;
document.addInvalidAddressRange(p); document.addInvalidAddressRange(p);
} else { } else {
return; return insertedStartAddress;
} }
} }
boolean hasSource= false; boolean hasSource= false;
@ -493,10 +512,12 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe
break; break;
} }
} else { } else {
if (instructions.length == 1 && srcLines.length == 1) { if (instructions.length == 1) {
if (p.fAddressLength.compareTo(BigInteger.valueOf(8)) <= 0) {
instrLength= p.fAddressLength; instrLength= p.fAddressLength;
} }
} }
}
if (instrLength == null) { if (instrLength == null) {
// cannot determine length of last instruction // cannot determine length of last instruction
break; break;
@ -513,7 +534,8 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe
} else { } else {
p = document.insertDisassemblyLine(p, address, instrLength.intValue(), opCode, instruction.getInstructionText(), compilationPath, lineNumber); //$NON-NLS-1 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; break;
} }
} }
@ -525,12 +547,17 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe
DisassemblyUtils.internalError(e); DisassemblyUtils.internalError(e);
} finally { } finally {
fCallback.setUpdatePending(false); fCallback.setUpdatePending(false);
if (insertedStartAddress) {
fCallback.updateInvalidSource(); fCallback.updateInvalidSource();
fCallback.unlockScroller(); fCallback.unlockScroller();
fCallback.doPending(); fCallback.doPending();
fCallback.updateVisibleArea(); fCallback.updateVisibleArea();
} else {
fCallback.unlockScroller();
} }
} }
return insertedStartAddress;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[]) * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[])

View file

@ -42,10 +42,11 @@ public interface IDisassemblyRetrieval {
* @param endAddress * @param endAddress
* @param file * @param file
* @param lines * @param lines
* @param mixed whether mixed assembly is preferred
* @param disassemblyRequest * @param disassemblyRequest
*/ */
void asyncGetDisassembly(BigInteger startAddress, BigInteger endAddress, String file, int fileNumber, int lines, void asyncGetDisassembly(BigInteger startAddress, BigInteger endAddress, String file, int fileNumber, int lines,
DisassemblyRequest disassemblyRequest); boolean mixed, DisassemblyRequest disassemblyRequest);
} }