Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/tools/llvm-xray/xray-fdr-dump.cpp
35230 views
1
//===- xray-fdr-dump.cpp: XRay FDR Trace Dump Tool ------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// Implements the FDR trace dumping tool, using the libraries for handling FDR
10
// mode traces specifically.
11
//
12
//===----------------------------------------------------------------------===//
13
#include "xray-registry.h"
14
#include "llvm/Support/CommandLine.h"
15
#include "llvm/Support/FileSystem.h"
16
#include "llvm/XRay/BlockIndexer.h"
17
#include "llvm/XRay/BlockPrinter.h"
18
#include "llvm/XRay/BlockVerifier.h"
19
#include "llvm/XRay/FDRRecordConsumer.h"
20
#include "llvm/XRay/FDRRecordProducer.h"
21
#include "llvm/XRay/FDRRecords.h"
22
#include "llvm/XRay/FileHeaderReader.h"
23
#include "llvm/XRay/RecordPrinter.h"
24
25
using namespace llvm;
26
using namespace xray;
27
28
static cl::SubCommand Dump("fdr-dump", "FDR Trace Dump");
29
static cl::opt<std::string> DumpInput(cl::Positional,
30
cl::desc("<xray fdr mode log>"),
31
cl::Required, cl::sub(Dump));
32
static cl::opt<bool> DumpVerify("verify",
33
cl::desc("verify structure of the log"),
34
cl::init(false), cl::sub(Dump));
35
36
static CommandRegistration Unused(&Dump, []() -> Error {
37
// Open the file provided.
38
auto FDOrErr = sys::fs::openNativeFileForRead(DumpInput);
39
if (!FDOrErr)
40
return FDOrErr.takeError();
41
42
uint64_t FileSize;
43
if (auto EC = sys::fs::file_size(DumpInput, FileSize))
44
return createStringError(EC, "Failed to get file size for '%s'.",
45
DumpInput.c_str());
46
47
std::error_code EC;
48
sys::fs::mapped_file_region MappedFile(
49
*FDOrErr, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0,
50
EC);
51
sys::fs::closeFile(*FDOrErr);
52
53
DataExtractor DE(StringRef(MappedFile.data(), MappedFile.size()), true, 8);
54
uint64_t OffsetPtr = 0;
55
56
auto FileHeaderOrError = readBinaryFormatHeader(DE, OffsetPtr);
57
if (!FileHeaderOrError)
58
return FileHeaderOrError.takeError();
59
auto &H = FileHeaderOrError.get();
60
61
FileBasedRecordProducer P(H, DE, OffsetPtr);
62
63
RecordPrinter RP(outs(), "\n");
64
if (!DumpVerify) {
65
PipelineConsumer C({&RP});
66
while (DE.isValidOffsetForDataOfSize(OffsetPtr, 1)) {
67
auto R = P.produce();
68
if (!R)
69
return R.takeError();
70
if (auto E = C.consume(std::move(R.get())))
71
return E;
72
}
73
return Error::success();
74
}
75
76
BlockPrinter BP(outs(), RP);
77
std::vector<std::unique_ptr<Record>> Records;
78
LogBuilderConsumer C(Records);
79
while (DE.isValidOffsetForDataOfSize(OffsetPtr, 1)) {
80
auto R = P.produce();
81
if (!R) {
82
// Print records we've found so far.
83
for (auto &Ptr : Records)
84
if (auto E = Ptr->apply(RP))
85
return joinErrors(std::move(E), R.takeError());
86
return R.takeError();
87
}
88
if (auto E = C.consume(std::move(R.get())))
89
return E;
90
}
91
92
// Once we have a trace, we then index the blocks.
93
BlockIndexer::Index Index;
94
BlockIndexer BI(Index);
95
for (auto &Ptr : Records)
96
if (auto E = Ptr->apply(BI))
97
return E;
98
99
if (auto E = BI.flush())
100
return E;
101
102
// Then we validate while printing each block.
103
BlockVerifier BV;
104
for (const auto &ProcessThreadBlocks : Index) {
105
auto &Blocks = ProcessThreadBlocks.second;
106
for (auto &B : Blocks) {
107
for (auto *R : B.Records) {
108
if (auto E = R->apply(BV))
109
return E;
110
if (auto E = R->apply(BP))
111
return E;
112
}
113
BV.reset();
114
BP.reset();
115
}
116
}
117
outs().flush();
118
return Error::success();
119
});
120
121