30 using llvm::yaml::Input;
33 using XRayRecordStorage =
38 std::vector<XRayRecord> &Records) {
40 return make_error<StringError>(
41 "Not enough bytes for an XRay log.",
44 if (
Data.size() - 32 == 0 ||
Data.size() % 32 != 0)
45 return make_error<StringError>(
46 "Invalid-sized XRay data.",
52 if (!FileHeaderOrError)
53 return FileHeaderOrError.takeError();
54 FileHeader =
std::move(FileHeaderOrError.get());
66 while (Reader.isValidOffset(OffsetPtr)) {
67 if (!Reader.isValidOffsetForDataOfSize(OffsetPtr, 32))
70 "Not enough bytes to read a full record at offset %" PRId64
".",
72 auto PreReadOffset = OffsetPtr;
74 if (OffsetPtr == PreReadOffset)
77 "Failed reading record type at offset %" PRId64
".", OffsetPtr);
81 Records.emplace_back();
82 auto &
Record = Records.back();
85 PreReadOffset = OffsetPtr;
86 Record.CPU = Reader.getU8(&OffsetPtr);
87 if (OffsetPtr == PreReadOffset)
90 "Failed reading CPU field at offset %" PRId64
".", OffsetPtr);
92 PreReadOffset = OffsetPtr;
93 auto Type = Reader.getU8(&OffsetPtr);
94 if (OffsetPtr == PreReadOffset)
97 "Failed reading record type field at offset %" PRId64
".",
116 "Unknown record type '%d' at offset %" PRId64
".",
Type, OffsetPtr);
119 PreReadOffset = OffsetPtr;
120 Record.FuncId = Reader.getSigned(&OffsetPtr,
sizeof(int32_t));
121 if (OffsetPtr == PreReadOffset)
124 "Failed reading function id field at offset %" PRId64
".",
127 PreReadOffset = OffsetPtr;
128 Record.TSC = Reader.getU64(&OffsetPtr);
129 if (OffsetPtr == PreReadOffset)
132 "Failed reading TSC field at offset %" PRId64
".", OffsetPtr);
134 PreReadOffset = OffsetPtr;
135 Record.TId = Reader.getU32(&OffsetPtr);
136 if (OffsetPtr == PreReadOffset)
139 "Failed reading thread id field at offset %" PRId64
".", OffsetPtr);
141 PreReadOffset = OffsetPtr;
142 Record.PId = Reader.getU32(&OffsetPtr);
143 if (OffsetPtr == PreReadOffset)
146 "Failed reading process id at offset %" PRId64
".", OffsetPtr);
151 auto &
Record = Records.back();
156 PreReadOffset = OffsetPtr;
157 int32_t
FuncId = Reader.getSigned(&OffsetPtr,
sizeof(int32_t));
158 if (OffsetPtr == PreReadOffset)
161 "Failed reading function id field at offset %" PRId64
".",
164 PreReadOffset = OffsetPtr;
165 auto TId = Reader.getU32(&OffsetPtr);
166 if (OffsetPtr == PreReadOffset)
169 "Failed reading thread id field at offset %" PRId64
".", OffsetPtr);
171 PreReadOffset = OffsetPtr;
172 auto PId = Reader.getU32(&OffsetPtr);
173 if (OffsetPtr == PreReadOffset)
176 "Failed reading process id field at offset %" PRId64
".",
184 "Corrupted log, found arg payload following non-matching "
185 "function+thread record. Record for function %d != %d at offset "
189 PreReadOffset = OffsetPtr;
190 auto Arg = Reader.getU64(&OffsetPtr);
191 if (OffsetPtr == PreReadOffset)
194 "Failed reading argument payload at offset %" PRId64
".",
203 "Unknown record type '%d' at offset %" PRId64
".",
RecordType,
270 if (
Data.size() < 32)
272 "Not enough bytes for an XRay FDR log.");
277 if (!FileHeaderOrError)
278 return FileHeaderOrError.takeError();
279 FileHeader =
std::move(FileHeaderOrError.get());
282 std::vector<std::unique_ptr<Record>> FDRRecords;
287 while (DE.isValidOffsetForDataOfSize(OffsetPtr, 1)) {
288 auto R =
P.produce();
290 return R.takeError();
300 for (
auto &R : FDRRecords)
301 if (
auto E =
R->apply(Indexer))
303 if (
auto E = Indexer.flush())
309 for (
auto &PTB : Index) {
310 auto &Blocks = PTB.second;
311 for (
auto &
B : Blocks) {
313 for (
auto *R :
B.Records)
328 for (
auto &PTB : Index) {
329 auto &Blocks = PTB.second;
335 auto Adder = [&](
const XRayRecord &
R) { Records.push_back(R); };
337 for (
auto &
B : Blocks) {
338 for (
auto *R :
B.Records)
339 if (
auto E =
R->apply(Expander))
342 if (
auto E = Expander.flush())
351 std::vector<XRayRecord> &Records) {
356 return make_error<StringError>(
"Failed loading YAML Data.",
In.error());
365 return make_error<StringError>(
372 return XRayRecord{R.RecordType, R.CPU, R.Type,
373 R.FuncId, R.TSC, R.TId,
374 R.PId, R.CallArgs, R.Data};
387 return make_error<StringError>(
388 Twine(
"Cannot read log from '") + Filename +
"'", EC);
391 return make_error<StringError>(
392 Twine(
"File '") + Filename +
"' too small for XRay.",
403 return make_error<StringError>(
404 Twine(
"Cannot read log from '") + Filename +
"'", EC);
410 auto TraceOrError =
loadTrace(LittleEndianDE, Sort);
414 TraceOrError =
loadTrace(BigEndianDE, Sort);
439 enum BinaryFormatType { NAIVE_FORMAT = 0, FLIGHT_DATA_RECORDER_FORMAT = 1 };
446 T.FileHeader,
T.Records))
449 return make_error<StringError>(
450 Twine(
"Unsupported version for Basic/Naive Mode logging: ") +
455 case FLIGHT_DATA_RECORDER_FORMAT:
461 return make_error<StringError>(
467 if (
auto E = loadYAMLLog(DE.
getData(),
T.FileHeader,
T.Records))
473 return L.TSC < R.TSC;