From a6efddce8bbceca4dd81ef3a0acbb1265c31c3c0 Mon Sep 17 00:00:00 2001 From: Matthew Khouzam Date: Tue, 26 Jan 2016 06:15:28 -0500 Subject: [PATCH] ctf: Attempt to gracefully recover from a malformed packet context If a packet context has an end time that is less than the start time tracecompass will give an error message and refuse to read the trace. This patch makes tracecompass log a warning instead and try to read the trace. Seeking should not be affected. Bug 486670 Change-Id: I352af4c79476c73b0ced2cefd65f82bd04d6762d Signed-off-by: Matthew Khouzam Reviewed-on: https://git.eclipse.org/r/65168 Reviewed-by: Bernd Hufmann Tested-by: Bernd Hufmann Reviewed-by: Hudson CI --- .../trace/CTFStreamInputPacketIndexTest.java | 5 +- .../core/trace/StreamInputPacketIndex.java | 51 +++++++++---------- .../trace/StreamInputPacketIndexEntry.java | 27 ++++++++++ 3 files changed, 53 insertions(+), 30 deletions(-) diff --git a/ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/trace/CTFStreamInputPacketIndexTest.java b/ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/trace/CTFStreamInputPacketIndexTest.java index 2d505fce3d..b826252ecc 100644 --- a/ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/trace/CTFStreamInputPacketIndexTest.java +++ b/ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/trace/CTFStreamInputPacketIndexTest.java @@ -23,8 +23,7 @@ import org.junit.Test; * The class StreamInputPacketIndexTest contains tests for the * class {@link StreamInputPacketIndex}. * - * @author ematkho - * @version $Revision: 1.0 $ + * @author Matthew Khouzam */ @SuppressWarnings("javadoc") public class CTFStreamInputPacketIndexTest { @@ -37,7 +36,7 @@ public class CTFStreamInputPacketIndexTest { * @throws CTFException */ @Before - public void setUp() throws CTFException { + public void setUp() { fixture = new StreamInputPacketIndex(); fixture.append(new StreamInputPacketIndexEntry(1L,0L)); } diff --git a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/trace/StreamInputPacketIndex.java b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/trace/StreamInputPacketIndex.java index 34cd54acbc..91d31649aa 100644 --- a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/trace/StreamInputPacketIndex.java +++ b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/trace/StreamInputPacketIndex.java @@ -24,9 +24,10 @@ import java.util.Comparator; import java.util.List; import java.util.TreeSet; +import org.eclipse.core.runtime.IStatus; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.tracecompass.ctf.core.CTFException; import org.eclipse.tracecompass.ctf.core.trace.ICTFPacketDescriptor; +import org.eclipse.tracecompass.internal.ctf.core.Activator; /** * StreamInputPacketIndex @@ -75,12 +76,8 @@ public class StreamInputPacketIndex { * * @param preParsedIndex * the pre-parsed index file - * - * @throws CTFException - * If there was a problem reading the entry */ - public void appendAll(Collection preParsedIndex) - throws CTFException { + public void appendAll(Collection preParsedIndex) { for (ICTFPacketDescriptor sipie : preParsedIndex) { append(checkNotNull(sipie)); } @@ -92,26 +89,25 @@ public class StreamInputPacketIndex { * @param entry * element to be appended to this index, cannot be null * @return {@code true} (as specified by {@link Collection#add}) - * @throws CTFException - * If there was a problem reading the entry */ - public synchronized boolean append(@NonNull ICTFPacketDescriptor entry) - throws CTFException { - + public synchronized boolean append(@NonNull ICTFPacketDescriptor entry) { + ICTFPacketDescriptor entryToAdd = entry; /* Validate consistent entry. */ - if (entry.getTimestampBegin() > entry.getTimestampEnd()) { - throw new CTFException("Packet begin timestamp is after end timestamp"); //$NON-NLS-1$ + if (entryToAdd.getTimestampBegin() > entryToAdd.getTimestampEnd()) { + Activator.log(IStatus.WARNING, "Packet at offset " + entryToAdd.getOffsetBytes() + //$NON-NLS-1$ + " begin timestamp is after end timestamp"); //$NON-NLS-1$ + entryToAdd = new StreamInputPacketIndexEntry(entryToAdd, Long.MAX_VALUE); } /* * Validate entries are inserted in monotonic increasing timestamp * order. */ - if (!fEntries.isEmpty() && (entry.getTimestampBegin() < lastElement().getTimestampBegin())) { + if (!fEntries.isEmpty() && (entryToAdd.getTimestampBegin() < lastElement().getTimestampBegin())) { return false; } - fEntries.add(entry); + fEntries.add(entryToAdd); return true; } @@ -127,9 +123,9 @@ public class StreamInputPacketIndex { /* * Search using binary search. * - * As the entries in fEntries are IndexEntries, the key to search for needs to be one too. - * We are looking for a timestamp though, so we use the dataOffset which is a long and use - * it as a timestamp holder. + * As the entries in fEntries are IndexEntries, the key to search for + * needs to be one too. We are looking for a timestamp though, so we use + * the dataOffset which is a long and use it as a timestamp holder. */ int index = Collections.binarySearch(fEntries, new StreamInputPacketIndexEntry(timestamp, 0), new FindTimestamp()); if (index < 0) { @@ -177,12 +173,12 @@ public class StreamInputPacketIndex { * contain the element * @throws ClassCastException * if the type of the specified element is incompatible with - * this data structure (optional) + * this data structure ( + * optional) * @throws NullPointerException * if the specified element is null and this data structure does - * not permit null elements (optional) + * not permit null elements ( + * optional) */ public int indexOf(ICTFPacketDescriptor element) { int indexOf = -1; @@ -235,11 +231,12 @@ public class StreamInputPacketIndex { @Override public int compare(ICTFPacketDescriptor value, ICTFPacketDescriptor key) { /* - * It is assumed that the second packet descriptor is the key, a wrapped timestamp in a - * PacketDescriptor. So we need to extract the timestamp. Then we have 3 choices, the - * if the timestamp is in the interval, we return 0 or found. If the timestamp is - * before or after, we just need to compare it to a value in the segment (like start) to - * know if it is greater or lesser to the current packet. + * It is assumed that the second packet descriptor is the key, a + * wrapped timestamp in a PacketDescriptor. So we need to extract + * the timestamp. Then we have 3 choices, the if the timestamp is in + * the interval, we return 0 or found. If the timestamp is before or + * after, we just need to compare it to a value in the segment (like + * start) to know if it is greater or lesser to the current packet. */ long ts = key.getOffsetBits(); if (value.includes(ts)) { diff --git a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/trace/StreamInputPacketIndexEntry.java b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/trace/StreamInputPacketIndexEntry.java index bda26442b4..e92eba70d7 100644 --- a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/trace/StreamInputPacketIndexEntry.java +++ b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/trace/StreamInputPacketIndexEntry.java @@ -173,6 +173,33 @@ public class StreamInputPacketIndexEntry implements ICTFPacketDescriptor { fLostEvents = computeLostEvents(lostSoFar); } + /** + * Copy constructor that updates the timestamp end + * + * @param entryToAdd + * the original {@link StreamInputPacketIndexEntry} + * @param newTimestampEnd + * the new timestamp end + */ + public StreamInputPacketIndexEntry(ICTFPacketDescriptor entryToAdd, long newTimestampEnd) { + fEndPacketHeaderBits = entryToAdd.getPayloadStartBits(); + fAttributes = entryToAdd.getAttributes(); + fContentSizeBits = entryToAdd.getContentSizeBits(); + fPacketSizeBits = entryToAdd.getPacketSizeBits(); + fTimestampBegin = entryToAdd.getTimestampBegin(); + fTimestampEnd = newTimestampEnd; + fOffsetBits = entryToAdd.getOffsetBits(); + fOffsetBytes = entryToAdd.getOffsetBits(); + + // LTTng Specific + fTarget = entryToAdd.getTarget(); + fTargetID = entryToAdd.getTargetId(); + Target target = new Target(); + target.number = fTargetID; + target.string = fTarget; + fLostEvents = entryToAdd.getLostEvents(); + } + private static @NonNull Map computeAttributeMap(StructDefinition streamPacketContextDef) { Builder attributeBuilder = ImmutableMap. builder(); for (String field : streamPacketContextDef.getDeclaration().getFieldsList()) { -- 2.34.1