Skip to content

Commit 0a945a7

Browse files
mfasDadavidrohr
authored andcommitted
[EMCAL-1048] Treat faulty memory size reported by RDH
In case the memory size in the RDH reported is larger then the raw payload size forward the current positon to payload size or offsetToNext - whatever is smaller, before raising the error. In case the trailer is incomplete the page cannot be trusted, likely because it is overwritten in memory. The marker must be forwarded and an exception is thrown.
1 parent 9fe0d97 commit 0a945a7

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

Detectors/EMCAL/reconstruction/include/EMCALReconstruction/RawReaderMemory.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,10 @@ class RawReaderMemory
148148
/// Rewind stream to the first entry
149149
void init();
150150

151-
/// \brief Check whether the current page is accepted
152-
/// \param page Raw page to check
153-
/// \return True if the page is accepted, false otherwise
154-
bool acceptPage(const char* page) const;
155-
151+
/// \brief Decode raw header words
152+
/// \param headerwords Headerwords
153+
/// \return Decoded RDH
154+
/// \throw RawDecodingError with code HEADER_DECODING if the payload does not correspond to an expected header
156155
o2::header::RDHAny decodeRawHeader(const void* headerwords);
157156

158157
private:

Detectors/EMCAL/reconstruction/src/RawReaderMemory.cxx

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88
// In applying this license CERN does not waive the privileges and immunities
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
11-
11+
#include <iostream>
1212
#include <sstream>
1313
#include <string>
1414
#include "EMCALReconstruction/RawReaderMemory.h"
1515
#include "DetectorsRaw/RDHUtils.h"
16+
#include "Headers/RAWDataHeader.h"
17+
#include "Headers/DAQID.h"
1618

1719
using namespace o2::emcal;
1820

@@ -35,6 +37,16 @@ o2::header::RDHAny RawReaderMemory::decodeRawHeader(const void* payloadwords)
3537
if (headerversion < RDHDecoder::getVersion<o2::header::RDHLowest>() || headerversion > RDHDecoder::getVersion<o2::header::RDHHighest>()) {
3638
throw RawDecodingError(RawDecodingError::ErrorType_t::HEADER_DECODING, mCurrentFEE);
3739
}
40+
if (!RDHDecoder::checkRDH(payloadwords, false, true)) {
41+
// Header size != to 64 and 0 in reserved words indicate that the header is a fake header
42+
throw RawDecodingError(RawDecodingError::ErrorType_t::HEADER_DECODING, mCurrentFEE);
43+
}
44+
if (RDHDecoder::getVersion(payloadwords) >= 6) {
45+
// If header version is >= 6 check that the source ID is EMCAL
46+
if (RDHDecoder::getSourceID(payloadwords) != o2::header::DAQID::EMC) {
47+
throw RawDecodingError(RawDecodingError::ErrorType_t::HEADER_DECODING, mCurrentFEE);
48+
}
49+
}
3850
return {*reinterpret_cast<const o2::header::RDHAny*>(payloadwords)};
3951
}
4052

@@ -117,9 +129,31 @@ void RawReaderMemory::nextPage(bool doResetPayload)
117129
}
118130
if (mCurrentPosition + RDHDecoder::getMemorySize(mRawHeader) > mRawMemoryBuffer.size()) {
119131
// Payload incomplete
132+
// Set to offset to next or buffer size, whatever is smaller
133+
if (mCurrentPosition + RDHDecoder::getOffsetToNext(mRawHeader) < mRawMemoryBuffer.size()) {
134+
mCurrentPosition += RDHDecoder::getOffsetToNext(mRawHeader);
135+
if (mCurrentPosition + 64 < mRawMemoryBuffer.size()) {
136+
// check if the page continues with a RDH
137+
// if next page is not a header decodeRawHeader will throw a RawDecodingError
138+
auto nextheader = decodeRawHeader(mRawMemoryBuffer.data() + mCurrentPosition);
139+
if (RDHDecoder::getVersion(nextheader) != RDHDecoder::getVersion(mRawHeader)) {
140+
// Next header has different header version - clear indication that it is a fake header
141+
throw RawDecodingError(RawDecodingError::ErrorType_t::HEADER_DECODING, mCurrentFEE);
142+
}
143+
}
144+
} else {
145+
mCurrentPosition = mRawMemoryBuffer.size();
146+
}
147+
// RDHDecoder::printRDH(mRawHeader);
120148
throw RawDecodingError(RawDecodingError::ErrorType_t::PAYLOAD_DECODING, mCurrentFEE);
121149
} else if (mCurrentPosition + RDHDecoder::getHeaderSize(mRawHeader) > mRawMemoryBuffer.size()) {
122150
// Start position of the payload is outside the payload range
151+
// Set to offset to next or buffer size, whatever is smaller
152+
if (mCurrentPosition + RDHDecoder::getOffsetToNext(mRawHeader) < mRawMemoryBuffer.size()) {
153+
mCurrentPosition += RDHDecoder::getOffsetToNext(mRawHeader);
154+
} else {
155+
mCurrentPosition = mRawMemoryBuffer.size();
156+
}
123157
throw RawDecodingError(RawDecodingError::ErrorType_t::PAGE_START_INVALID, mCurrentFEE);
124158
} else {
125159
mRawBuffer.readFromMemoryBuffer(gsl::span<const char>(mRawMemoryBuffer.data() + mCurrentPosition + RDHDecoder::getHeaderSize(mRawHeader), RDHDecoder::getMemorySize(mRawHeader) - RDHDecoder::getHeaderSize(mRawHeader)));
@@ -154,6 +188,13 @@ void RawReaderMemory::nextPage(bool doResetPayload)
154188
mMinorErrors.emplace_back(RawDecodingError::ErrorType_t::TRAILER_INCOMPLETE, mCurrentFEE);
155189
}
156190
} catch (RCUTrailer::Error& e) {
191+
// We must forward the position in such cases in order to not end up in an infinity loop
192+
if (mCurrentPosition + RDHDecoder::getOffsetToNext(mRawHeader) < mRawMemoryBuffer.size()) {
193+
mCurrentPosition += RDHDecoder::getOffsetToNext(mRawHeader);
194+
} else {
195+
mCurrentPosition = mRawMemoryBuffer.size();
196+
}
197+
// Page is not consistent - must be skipped
157198
throw RawDecodingError(RawDecodingError::ErrorType_t::TRAILER_DECODING, mCurrentFEE);
158199
}
159200
} else {

0 commit comments

Comments
 (0)