31 using llvm::yaml::Input;
34 using XRayRecordStorage =
35 std::aligned_storage<sizeof(XRayRecord), alignof(XRayRecord)>::type;
39 std::vector<XRayRecord> &Records) {
41 return make_error<StringError>(
42 "Not enough bytes for an XRay log.",
45 if (Data.
size() - 32 == 0 || Data.
size() % 32 != 0)
46 return make_error<StringError>(
47 "Invalid-sized XRay data.",
53 if (!FileHeaderOrError)
54 return FileHeaderOrError.takeError();
55 FileHeader = std::move(FileHeaderOrError.get());
67 while (Reader.isValidOffset(OffsetPtr)) {
68 if (!Reader.isValidOffsetForDataOfSize(OffsetPtr, 32))
71 "Not enough bytes to read a full record at offset %d.", OffsetPtr);
72 auto PreReadOffset = OffsetPtr;
73 auto RecordType = Reader.getU16(&OffsetPtr);
74 if (OffsetPtr == PreReadOffset)
77 "Failed reading record type at offset %d.", OffsetPtr);
81 Records.emplace_back();
82 auto &
Record = Records.back();
83 Record.RecordType = RecordType;
85 PreReadOffset = OffsetPtr;
86 Record.CPU = Reader.getU8(&OffsetPtr);
87 if (OffsetPtr == PreReadOffset)
90 "Failed reading CPU field at offset %d.", OffsetPtr);
92 PreReadOffset = OffsetPtr;
93 auto Type = Reader.getU8(&OffsetPtr);
94 if (OffsetPtr == PreReadOffset)
97 "Failed reading record type field at offset %d.", OffsetPtr);
115 "Unknown record type '%d' at offset %d.",
Type, OffsetPtr);
118 PreReadOffset = OffsetPtr;
119 Record.FuncId = Reader.getSigned(&OffsetPtr,
sizeof(int32_t));
120 if (OffsetPtr == PreReadOffset)
123 "Failed reading function id field at offset %d.", OffsetPtr);
125 PreReadOffset = OffsetPtr;
126 Record.TSC = Reader.getU64(&OffsetPtr);
127 if (OffsetPtr == PreReadOffset)
130 "Failed reading TSC field at offset %d.", OffsetPtr);
132 PreReadOffset = OffsetPtr;
133 Record.TId = Reader.getU32(&OffsetPtr);
134 if (OffsetPtr == PreReadOffset)
137 "Failed reading thread id field at offset %d.", OffsetPtr);
139 PreReadOffset = OffsetPtr;
140 Record.PId = Reader.getU32(&OffsetPtr);
141 if (OffsetPtr == PreReadOffset)
144 "Failed reading process id at offset %d.", OffsetPtr);
149 auto &
Record = Records.back();
154 PreReadOffset = OffsetPtr;
155 int32_t
FuncId = Reader.getSigned(&OffsetPtr,
sizeof(int32_t));
156 if (OffsetPtr == PreReadOffset)
159 "Failed reading function id field at offset %d.", OffsetPtr);
161 PreReadOffset = OffsetPtr;
162 auto TId = Reader.getU32(&OffsetPtr);
163 if (OffsetPtr == PreReadOffset)
166 "Failed reading thread id field at offset %d.", OffsetPtr);
168 PreReadOffset = OffsetPtr;
169 auto PId = Reader.getU32(&OffsetPtr);
170 if (OffsetPtr == PreReadOffset)
173 "Failed reading process id field at offset %d.", OffsetPtr);
180 "Corrupted log, found arg payload following non-matching " 181 "function+thread record. Record for function %d != %d at offset " 183 Record.FuncId, FuncId, OffsetPtr);
185 PreReadOffset = OffsetPtr;
186 auto Arg = Reader.getU64(&OffsetPtr);
187 if (OffsetPtr == PreReadOffset)
190 "Failed reading argument payload at offset %d.", OffsetPtr);
198 "Unknown record type '%d' at offset %d.", RecordType, OffsetPtr);
264 if (Data.
size() < 32)
266 "Not enough bytes for an XRay FDR log.");
271 if (!FileHeaderOrError)
272 return FileHeaderOrError.takeError();
273 FileHeader = std::move(FileHeaderOrError.get());
276 std::vector<std::unique_ptr<Record>> FDRRecords;
281 while (DE.isValidOffsetForDataOfSize(OffsetPtr, 1)) {
282 auto R =
P.produce();
284 return R.takeError();
285 if (
auto E =
C.consume(std::move(
R.get())))
294 for (
auto &R : FDRRecords)
295 if (
auto E =
R->apply(Indexer))
297 if (
auto E = Indexer.flush())
303 for (
auto &PTB : Index) {
304 auto &Blocks = PTB.second;
305 for (
auto &
B : Blocks) {
307 for (
auto *R :
B.Records)
308 if (
auto E =
R->apply(Verifier))
310 if (
auto E = Verifier.
verify())
322 for (
auto &PTB : Index) {
323 auto &Blocks = PTB.second;
329 auto Adder = [&](
const XRayRecord &R) { Records.push_back(R); };
331 for (
auto &
B : Blocks) {
332 for (
auto *R :
B.Records)
333 if (
auto E = R->apply(Expander))
336 if (
auto E = Expander.flush())
345 std::vector<XRayRecord> &Records) {
350 return make_error<StringError>(
"Failed loading YAML Data.",
In.error());
352 FileHeader.
Version = Trace.Header.Version;
353 FileHeader.
Type = Trace.Header.Type;
355 FileHeader.
NonstopTSC = Trace.Header.NonstopTSC;
359 return make_error<StringError>(
366 return XRayRecord{R.RecordType, R.CPU, R.Type,
367 R.FuncId, R.TSC, R.TId,
368 R.PId, R.CallArgs, R.Data};
377 return make_error<StringError>(
378 Twine(
"Cannot read log from '") + Filename +
"'", EC);
383 return make_error<StringError>(
384 Twine(
"Cannot read log from '") + Filename +
"'", EC);
387 return make_error<StringError>(
388 Twine(
"File '") + Filename +
"' too small for XRay.",
395 Fd, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0, EC);
397 return make_error<StringError>(
398 Twine(
"Cannot read log from '") + Filename +
"'", EC);
404 auto TraceOrError =
loadTrace(LittleEndianDE, Sort);
407 TraceOrError =
loadTrace(BigEndianDE, Sort);
429 uint16_t
Version = HeaderExtractor.getU16(&OffsetPtr);
430 uint16_t
Type = HeaderExtractor.getU16(&OffsetPtr);
432 enum BinaryFormatType { NAIVE_FORMAT = 0, FLIGHT_DATA_RECORDER_FORMAT = 1 };
437 if (Version == 1 || Version == 2 || Version == 3) {
439 T.FileHeader, T.Records))
442 return make_error<StringError>(
443 Twine(
"Unsupported version for Basic/Naive Mode logging: ") +
448 case FLIGHT_DATA_RECORDER_FORMAT:
449 if (Version >= 1 && Version <= 5) {
454 return make_error<StringError>(
455 Twine(
"Unsupported version for FDR Mode logging: ") +
Twine(Version),
460 if (
auto E = loadYAMLLog(DE.
getData(), T.FileHeader, T.Records))
465 std::stable_sort(T.Records.begin(), T.Records.end(),
467 return L.
TSC < R.TSC;
This class represents lattice values for constants.
std::error_code openFileForRead(const Twine &Name, int &ResultFD, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)
Opens the file with the given name in a read-only mode, returning its open file descriptor.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
WallclockRecord * WallclockTime
This class represents a memory mapped file.
Expected< Trace > loadTraceFile(StringRef Filename, bool Sort=false)
This function will attempt to load XRay trace records from the provided |Filename|.
Expected< XRayFileHeader > readBinaryFormatHeader(DataExtractor &HeaderExtractor, uint32_t &OffsetPtr)
Convenience function for loading the file header given a data extractor at a specified offset...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
std::error_code make_error_code(BitcodeError E)
std::error_code file_size(const Twine &Path, uint64_t &Result)
Get file size.
Tagged union holding either a T or a Error.
An XRayRecord is the denormalized view of data associated in a trace.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Expected< Trace > loadTrace(const DataExtractor &Extractor, bool Sort=false)
This function will attempt to load XRay trace records from the provided DataExtractor.
The instances of the Type class are immutable: once they are created, they are never changed...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void sort(IteratorTy Start, IteratorTy End)
static ErrorSuccess success()
Create a success value.
uint64_t TSC
Get the full 8 bytes of the TSC when we get the log record.
amdgpu Simplify well known AMD library false Value Value * Arg
verify safepoint Safepoint IR Verifier
OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate P)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere...
Lightweight error class with error context and mandatory checking.
StringRef - Represent a constant reference to a string, i.e.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.