Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Xenos2017-03-28 19:53:56 +0000
committerStefan Xenos2017-03-28 20:35:19 +0000
commitfae393304298c10366ba6a71a6df9dcd1b32ce66 (patch)
tree2721f0f2b401e43294e892df6bfc434796a2abd6
parentd8a6dc9228bdb8dc4adc1b3c4b068a43725643f6 (diff)
downloadeclipse.jdt.core-fae393304298c10366ba6a71a6df9dcd1b32ce66.tar.gz
eclipse.jdt.core-fae393304298c10366ba6a71a6df9dcd1b32ce66.tar.xz
eclipse.jdt.core-fae393304298c10366ba6a71a6df9dcd1b32ce66.zip
Bug 514089 - Build a tool to help debug index corruptionI20170328-2000
Add late suggestions from code review. Change-Id: Ie1e4240448c4cae1aaa7b0ac40c7d152004c61c0
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/IndexExceptionBuilder.java (renamed from org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/ProblemBuilder.java)20
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/Nd.java4
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNode.java4
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/RawGrowableArray.java16
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/db/Database.java60
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdComplexTypeSignature.java4
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/TagTreeReader.java10
7 files changed, 59 insertions, 59 deletions
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/ProblemBuilder.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/IndexExceptionBuilder.java
index dc9434b4a4..42d9b5a491 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/ProblemBuilder.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/IndexExceptionBuilder.java
@@ -22,14 +22,14 @@ import org.eclipse.jdt.internal.core.nd.field.IField;
/**
* Given a set of memory ranges, this class constructs detailed error messages.
*/
-public final class ProblemBuilder {
+public final class IndexExceptionBuilder {
private final Database db;
private final List<RelatedAddress> relatedAddresses = new ArrayList<>();
/**
- * Constructs a new {@link ProblemBuilder}
+ * Constructs a new {@link IndexExceptionBuilder}
*/
- public ProblemBuilder(Database db) {
+ public IndexExceptionBuilder(Database db) {
this.db = db;
}
@@ -38,7 +38,7 @@ public final class ProblemBuilder {
* the size of the possibly-corrupt address range, and a custom description for the memory at this
* address range.
*/
- public ProblemBuilder addProblemAddress(String description, long dataBlockAddress, int rangeSize) {
+ public IndexExceptionBuilder addProblemAddress(String description, long dataBlockAddress, int rangeSize) {
MemoryAccessLog lastWrite = this.db.getLog().getReportFor(dataBlockAddress, rangeSize);
this.relatedAddresses.add(new RelatedAddress(description, dataBlockAddress, rangeSize, lastWrite));
return this;
@@ -50,7 +50,7 @@ public final class ProblemBuilder {
*
* @return this
*/
- public ProblemBuilder addProblemAddress(String description, IField field, long address) {
+ public IndexExceptionBuilder addProblemAddress(String description, IField field, long address) {
long offset = field.getOffset();
int size = field.getRecordSize();
return addProblemAddress(description, address + offset, size);
@@ -62,18 +62,18 @@ public final class ProblemBuilder {
*
* @return this
*/
- public ProblemBuilder addProblemAddress(IField field, long address) {
+ public IndexExceptionBuilder addProblemAddress(IField field, long address) {
return addProblemAddress(field.getFieldName(), field, address);
}
/**
- * Throws an {@link IndexException} containing the given message and all the addresses collected
- * by this object.
+ * Returns a newly constructed {@link IndexException} containing the given message and all the addresses collected
+ * by this object.
*/
- public void throwException(String description) {
+ public IndexException build(String description) {
IndexException toThrow = new IndexException(description);
attachTo(toThrow);
- throw toThrow;
+ return toThrow;
}
/**
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/Nd.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/Nd.java
index 7044df607d..9b20c451c0 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/Nd.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/Nd.java
@@ -708,10 +708,10 @@ public final class Nd {
}
/**
- * Creates a {@link ProblemBuilder} object that collects information about database corruption after it is
+ * Creates a {@link IndexExceptionBuilder} object that collects information about database corruption after it is
* detected.
*/
- public ProblemBuilder describeProblem() {
+ public IndexExceptionBuilder describeProblem() {
return this.db.describeProblem();
}
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNode.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNode.java
index 65116047d8..d550751e3c 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNode.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNode.java
@@ -80,9 +80,9 @@ public abstract class NdNode implements IDestructable {
Class<T> clazz = targetType.getStructClass();
if (!clazz.isAssignableFrom(result.getClass())) {
- nd.describeProblem()
+ throw nd.describeProblem()
.addProblemAddress(NODE_TYPE, address)
- .throwException("Found wrong data type at address " + address + ". Expected a subclass of " + //$NON-NLS-1$//$NON-NLS-2$
+ .build("Found wrong data type at address " + address + ". Expected a subclass of " + //$NON-NLS-1$//$NON-NLS-2$
clazz + " but found " + result.getClass()); //$NON-NLS-1$
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/RawGrowableArray.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/RawGrowableArray.java
index 03a3404fc7..ac3ede103e 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/RawGrowableArray.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/RawGrowableArray.java
@@ -210,7 +210,7 @@ public final class RawGrowableArray {
db.putRecPtr(recordAddress, value);
setSize(nd, address, newSize);
} catch (IndexException e) {
- ProblemBuilder descriptor = nd.describeProblem();
+ IndexExceptionBuilder descriptor = nd.describeProblem();
addSizeTo(nd, address, descriptor);
descriptor.attachTo(e);
throw e;
@@ -385,12 +385,12 @@ public final class RawGrowableArray {
// We use reads of 1 past the end of the array to handle insertions.
if (index > size) {
- ProblemBuilder builder = nd.describeProblem();
+ IndexExceptionBuilder builder = nd.describeProblem();
addSizeTo(nd, address, builder);
builder.addProblemAddress(GROWABLE_BLOCK_ADDRESS, address);
- builder.throwException(
+ throw builder.build(
"Record index " + index + " out of range. Array contains " + size + " elements"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
@@ -406,10 +406,10 @@ public final class RawGrowableArray {
+ block * Database.PTR_SIZE;
growableBlockAddress = db.getRecPtr(dataBlockAddress);
if (growableBlockAddress == 0) {
- nd.describeProblem()
+ throw nd.describeProblem()
.addProblemAddress("backpointer number " + block, dataBlockAddress, Database.PTR_SIZE) //$NON-NLS-1$
.addProblemAddress(GROWABLE_BLOCK_ADDRESS, address)
- .throwException("Null data block found in metablock"); //$NON-NLS-1$
+ .build("Null data block found in metablock"); //$NON-NLS-1$
}
growableBlockRelativeIndex = blockRelativeIndex;
}
@@ -422,7 +422,7 @@ public final class RawGrowableArray {
}
}
- private void addSizeTo(Nd nd, long address, ProblemBuilder builder) {
+ private void addSizeTo(Nd nd, long address, IndexExceptionBuilder builder) {
long growableBlockAddress = GROWABLE_BLOCK_ADDRESS.get(nd, address);
if (growableBlockAddress != 0) {
builder.addProblemAddress(GrowableBlockHeader.ARRAY_SIZE, growableBlockAddress);
@@ -441,9 +441,9 @@ public final class RawGrowableArray {
Database db = nd.getDB();
if (index > lastElementIndex || index < 0) {
- ProblemBuilder descriptor = nd.describeProblem().addProblemAddress(GROWABLE_BLOCK_ADDRESS, address);
+ IndexExceptionBuilder descriptor = nd.describeProblem().addProblemAddress(GROWABLE_BLOCK_ADDRESS, address);
addSizeTo(nd, address, descriptor);
- descriptor.throwException("Attempt to remove nonexistent element " + index //$NON-NLS-1$
+ throw descriptor.build("Attempt to remove nonexistent element " + index //$NON-NLS-1$
+ " from an array of size " + (lastElementIndex + 1)); //$NON-NLS-1$
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/db/Database.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/db/Database.java
index 8d7a4dd2d9..aa7f7589ab 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/db/Database.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/db/Database.java
@@ -31,7 +31,7 @@ import java.util.Set;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
-import org.eclipse.jdt.internal.core.nd.ProblemBuilder;
+import org.eclipse.jdt.internal.core.nd.IndexExceptionBuilder;
import org.eclipse.jdt.internal.core.nd.db.ModificationLog.Tag;
import org.eclipse.osgi.util.NLS;
@@ -564,9 +564,9 @@ public class Database {
chunk.makeDirty();
int blockReportedSize = chunk.getShort(freeBlock);
if (blockReportedSize != useDeltas * BLOCK_SIZE_DELTA) {
- describeProblem()
+ throw describeProblem()
.addProblemAddress("block size", freeBlock, SHORT_SIZE) //$NON-NLS-1$
- .throwException(
+ .build(
"Heap corruption detected in free space list. Block " + freeBlock //$NON-NLS-1$
+ " reports a size of " + blockReportedSize + " but was in the list for blocks of size " //$NON-NLS-1$//$NON-NLS-2$
+ useDeltas * BLOCK_SIZE_DELTA);
@@ -674,18 +674,18 @@ public class Database {
numChunks = getBlockHeaderForChunkNum(freeBlockChunkNum);
if (numChunks < neededChunks) {
- describeProblem()
+ throw describeProblem()
.addProblemAddress("chunk header", freeBlockChunkNum * CHUNK_SIZE, INT_SIZE) //$NON-NLS-1$
- .throwException("A block in the free space trie was too small or wasn't actually free. Reported size = " //$NON-NLS-1$
+ .build("A block in the free space trie was too small or wasn't actually free. Reported size = " //$NON-NLS-1$
+ numChunks + " chunks, requested size = " + neededChunks + " chunks"); //$NON-NLS-1$//$NON-NLS-2$
}
int footer = getBlockFooterForChunkBefore(freeBlockChunkNum + numChunks);
if (footer != numChunks) {
- describeProblem()
+ throw describeProblem()
.addProblemAddress("chunk header", freeBlockChunkNum * CHUNK_SIZE, INT_SIZE) //$NON-NLS-1$
.addProblemAddress("chunk footer", (freeBlockChunkNum + numChunks) * CHUNK_SIZE - INT_SIZE, INT_SIZE) //$NON-NLS-1$
- .throwException("The header and footer didn't match for a block in the free space trie. Expected " //$NON-NLS-1$
+ .build("The header and footer didn't match for a block in the free space trie. Expected " //$NON-NLS-1$
+ numChunks + " but found " + footer); //$NON-NLS-1$
}
@@ -888,9 +888,9 @@ public class Database {
long addressOfPrevBlockPointer = getAddressOfFirstBlockPointer(correctSize);
while (block != 0) {
if (block == result) {
- describeProblem()
+ throw describeProblem()
.addProblemAddress("incoming pointer", addressOfPrevBlockPointer, PTR_SIZE) //$NON-NLS-1$
- .throwException("Block " + result //$NON-NLS-1$
+ .build("Block " + result //$NON-NLS-1$
+ " was found in the free space list, even though it wasn't free"); //$NON-NLS-1$
}
addressOfPrevBlockPointer = block + BLOCK_NEXT_OFFSET;
@@ -907,7 +907,7 @@ public class Database {
int targetChunkNum = (int) (result / CHUNK_SIZE);
if (currentChunkNum == targetChunkNum) {
- describeProblem().throwException("Block " + result //$NON-NLS-1$
+ throw describeProblem().build("Block " + result //$NON-NLS-1$
+ " was not supposed to be in the free space list, but was linked as the root of the list"); //$NON-NLS-1$
}
@@ -926,9 +926,9 @@ public class Database {
}
if (nextChildChunkNum == targetChunkNum) {
- describeProblem()
+ throw describeProblem()
.addProblemAddress("trie child address", chunkAddress, INT_SIZE) //$NON-NLS-1$
- .throwException("Chunk number " + nextChildChunkNum //$NON-NLS-1$
+ .build("Chunk number " + nextChildChunkNum //$NON-NLS-1$
+ " was found in the free space trie even though it was in use"); //$NON-NLS-1$
}
@@ -946,19 +946,19 @@ public class Database {
int blockReportedSize = getShort(block);
long followingBlock = getFreeRecPtr(block + BLOCK_NEXT_OFFSET);
if (measuredLastBlock != lastBlock) {
- describeProblem()
+ throw describeProblem()
.addProblemAddress("last block", block + BLOCK_PREV_OFFSET, PTR_SIZE) //$NON-NLS-1$
.addProblemAddress("incoming pointer", addressOfPrevBlockPointer, PTR_SIZE) //$NON-NLS-1$
- .throwException("The free space block (" + block //$NON-NLS-1$
+ .build("The free space block (" + block //$NON-NLS-1$
+ ") of size " + correctSize + " had an incorrect prev pointer to " //$NON-NLS-1$//$NON-NLS-2$
+ measuredLastBlock + ", but it should have been pointing to " //$NON-NLS-1$
+ lastBlock);
}
if (blockReportedSize != correctSize) {
- describeProblem()
+ throw describeProblem()
.addProblemAddress("block size", block, SHORT_SIZE) //$NON-NLS-1$
.addProblemAddress("incoming pointer", addressOfPrevBlockPointer, PTR_SIZE) //$NON-NLS-1$
- .throwException("A block (" + block + ") of size " + measuredLastBlock //$NON-NLS-1$ //$NON-NLS-2$
+ .build("A block (" + block + ") of size " + measuredLastBlock //$NON-NLS-1$ //$NON-NLS-2$
+ " was in the free space list for blocks of size " + correctSize); //$NON-NLS-1$
}
addressOfPrevBlockPointer = block + BLOCK_NEXT_OFFSET;
@@ -983,16 +983,16 @@ public class Database {
private void validateFreeSpaceNode(Set<Integer> visited, int chunkNum, int parent) {
if (visited.contains(chunkNum)) {
- describeProblem().throwException("Chunk " + chunkNum + "(parent = " + parent //$NON-NLS-1$//$NON-NLS-2$
+ throw describeProblem().build("Chunk " + chunkNum + "(parent = " + parent //$NON-NLS-1$//$NON-NLS-2$
+ " appeared twice in the free space tree"); //$NON-NLS-1$
}
long chunkStart = chunkNum * CHUNK_SIZE;
int parentChunk = getInt(chunkStart + LargeBlock.PARENT_OFFSET);
if (parentChunk != parent) {
- describeProblem()
+ throw describeProblem()
.addProblemAddress("parent pointer", chunkStart + LargeBlock.PARENT_OFFSET, Database.INT_SIZE) //$NON-NLS-1$
- .throwException("Chunk " + chunkNum + " has the wrong parent. Expected " + parent //$NON-NLS-1$//$NON-NLS-2$
+ .build("Chunk " + chunkNum + " has the wrong parent. Expected " + parent //$NON-NLS-1$//$NON-NLS-2$
+ " but found " + parentChunk); //$NON-NLS-1$
}
@@ -1012,10 +1012,10 @@ public class Database {
Integer.highestOneBit(sizeDifference)) - 1;
if (firstDifference != testPosition) {
- ProblemBuilder descriptor = describeProblem();
+ IndexExceptionBuilder descriptor = describeProblem();
attachBlockHeaderForChunkNum(descriptor, chunkNum);
attachBlockHeaderForChunkNum(descriptor, nextChildChunkNum);
- descriptor.throwException("Chunk " + nextChildChunkNum + " contained an incorrect size of " //$NON-NLS-1$//$NON-NLS-2$
+ throw descriptor.build("Chunk " + nextChildChunkNum + " contained an incorrect size of " //$NON-NLS-1$//$NON-NLS-2$
+ nextSize + ". It was at position " + testPosition + " in parent " + chunkNum //$NON-NLS-1$ //$NON-NLS-2$
+ " which had size " + numChunks); //$NON-NLS-1$
}
@@ -1132,7 +1132,7 @@ public class Database {
return getInt((long) firstChunkNum * CHUNK_SIZE);
}
- private void attachBlockHeaderForChunkNum(ProblemBuilder builder, int firstChunkNum) {
+ private void attachBlockHeaderForChunkNum(IndexExceptionBuilder builder, int firstChunkNum) {
if (firstChunkNum >= this.fChunksUsed) {
return;
}
@@ -1271,11 +1271,11 @@ public class Database {
int chunkNum = (int) (address / CHUNK_SIZE);
int numChunks = -getBlockHeaderForChunkNum(chunkNum);
if (numChunks < 0) {
- ProblemBuilder builder = describeProblem();
+ IndexExceptionBuilder builder = describeProblem();
if (chunkNum < this.fChunksUsed) {
builder.addProblemAddress("block header", (long) chunkNum * CHUNK_SIZE, INT_SIZE); //$NON-NLS-1$
}
- builder.throwException("Already freed large block " + address); //$NON-NLS-1$
+ throw builder.build("Already freed large block " + address); //$NON-NLS-1$
}
blockSize = (long) numChunks * CHUNK_SIZE;
this.log.recordFree(address, (int)(blockSize - BLOCK_HEADER_SIZE));
@@ -1284,16 +1284,16 @@ public class Database {
// Deallocating a normal block
// TODO Look for opportunities to merge small blocks
if (blockSize < 0) {
- describeProblem()
+ throw describeProblem()
.addProblemAddress("block size", block, SHORT_SIZE) //$NON-NLS-1$
- .throwException("Already freed record " + address); //$NON-NLS-1$
+ .build("Already freed record " + address); //$NON-NLS-1$
}
this.log.recordFree(address, (int)(blockSize - BLOCK_HEADER_SIZE));
int offset = Chunk.recPtrToIndex(address);
if (offset + blockSize > CHUNK_SIZE) {
- describeProblem()
+ throw describeProblem()
.addProblemAddress("block size", block, SHORT_SIZE) //$NON-NLS-1$
- .throwException("Attempting to free chunk of impossible size. The block at address " //$NON-NLS-1$
+ .build("Attempting to free chunk of impossible size. The block at address " //$NON-NLS-1$
+ address + " in chunk " + chunk.fSequenceNumber + " offset " + offset //$NON-NLS-1$//$NON-NLS-2$
+ " can't be as large as " //$NON-NLS-1$
+ blockSize + " bytes since that would make it extend beyond the end of the chunk"); //$NON-NLS-1$
@@ -1854,7 +1854,7 @@ public class Database {
}
}
- public ProblemBuilder describeProblem() {
- return new ProblemBuilder(this);
+ public IndexExceptionBuilder describeProblem() {
+ return new IndexExceptionBuilder(this);
}
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdComplexTypeSignature.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdComplexTypeSignature.java
index bcde1c5a67..c5d6733cc4 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdComplexTypeSignature.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdComplexTypeSignature.java
@@ -106,9 +106,9 @@ public class NdComplexTypeSignature extends NdTypeSignature {
long size = TYPE_ARGUMENTS.size(getNd(), this.address);
if (size != 1) {
- getNd().describeProblem()
+ throw getNd().describeProblem()
.addProblemAddress(TYPE_ARGUMENTS, this.address)
- .throwException("Array types should have exactly one argument"); //$NON-NLS-1$
+ .build("Array types should have exactly one argument"); //$NON-NLS-1$
}
return TYPE_ARGUMENTS.get(getNd(), this.address, 0).getType();
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/TagTreeReader.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/TagTreeReader.java
index 4f9b6a288b..d81e73a791 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/TagTreeReader.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/TagTreeReader.java
@@ -78,9 +78,9 @@ public abstract class TagTreeReader {
readAddress += Database.BYTE_SIZE;
TagHandler<?> reader = this.readers[nextByte];
if (reader == null) {
- nd.describeProblem()
+ throw nd.describeProblem()
.addProblemAddress("tag", address, 1) //$NON-NLS-1$
- .throwException("Found unknown tag with value " + nextByte + " at address " + address); //$NON-NLS-1$//$NON-NLS-2$
+ .build("Found unknown tag with value " + nextByte + " at address " + address); //$NON-NLS-1$//$NON-NLS-2$
}
return reader.read(nd, readAddress, this, bytesRead);
@@ -100,7 +100,7 @@ public abstract class TagTreeReader {
TagHandler handler = this.readers[key];
if (handler == null) {
- nd.describeProblem().throwException("Invalid key " + key + " returned from getKeyFor(...)"); //$NON-NLS-1$//$NON-NLS-2$
+ throw nd.describeProblem().build("Invalid key " + key + " returned from getKeyFor(...)"); //$NON-NLS-1$//$NON-NLS-2$
}
handler.write(nd, address, this, toWrite, bytesWritten);
@@ -114,9 +114,9 @@ public abstract class TagTreeReader {
TagHandler<?> handler = this.readers[nextByte];
if (handler == null) {
- nd.describeProblem()
+ throw nd.describeProblem()
.addProblemAddress("tag", address, 1) //$NON-NLS-1$
- .throwException("Found unknown tag with value " + nextByte + " at address " + address); //$NON-NLS-1$//$NON-NLS-2$
+ .build("Found unknown tag with value " + nextByte + " at address " + address); //$NON-NLS-1$//$NON-NLS-2$
}
handler.destruct(nd, readAddress, this);

Back to the top